Tuesday, November 6, 2012

Dynamic waveform representation in Processing

I'll show how to use the method of the previous tutorial to draw dynamic waveforms, displaying the sound of the microphone input between two points: the center of the screen and the mouse.

Reactable look-alike =)


First, let's import the minim library


import ddf.minim.*; //import minim

Minim minim;//declare minim

AudioInput in; //declare an input

int bufferSize = 1280; //define the buffer size

int newBufferSize = bufferSize; //declare and initialize the buffer size

void setup(){

  size(700,700); // size of the screen

  minim = new Minim(this); //initialize minim

  in = minim.getLineIn(Minim.MONO, bufferSize);// get a line in from Minim, default bit depth is 16

}

void draw(){

}

And... change variables
The amplitude of the graph will be the spectrum of the input audio wave. We just have to change the values of the amplitude vector for the values of the buffer, which we get with a "for" function that increment till the buffer size -1, and replace the Y component of the vector with (in.left.get()) .


import ddf.minim.*; //import minim
Minim minim;//declare minim
AudioInput in; //declare an input




int bufferSize = 1280; //define the buffer size
int newBufferSize = bufferSize; //declare and initialize the buffer size

void setup(){
  size(700,700,P3D); // size of the screen
  minim = new Minim(this); //initialize minim
  in = minim.getLineIn(Minim.MONO, bufferSize);// get a line in from Minim, default bit depth is 16
  // get a line out from Minim, default sample rate is 44100, default bit depth is 16
  

  
}

void draw(){
  
  background(0,0,255);
  
  float startPointX = width/2; //define the X position of the start point in the center of the screen;
  float startPointY = height/2; //define the Y position of the start point in the center of the screen;
  float endPointX=mouseX; //define the X position of the end point that will follow the mouse;
  float endPointY=mouseY; //define the Y position of the end point that will follow the mouse;
  
  
float deltaX=mouseX-width/2; //create a variable with the delta of the x component of the ending - start point
float deltaY=mouseY-height/2; //create a variable with the delta of the y component of the ending - start point
float angleInRadians=atan2(deltaY,deltaX); //get the angle in radians between them with atan2()


  PVector[]points=new PVector[1280]; //create an array of vectors that will store the flat positions of points that will create the graph with the number of elements equal to the size of the of the arraylist 
  PVector[]amplitude = new PVector[1280]; //create an array of vectors that will store the amplitude of the mapped mouse with the number of elements equal to the size of the of the arraylist
  
//initalize each vector with x=0 and y=0 values;
  for(int a=0; a<1280-1; a++){
    points[a] = new PVector(0,0,0);
    amplitude[a] = new PVector(0,0,0);
  }
  
//here the magic begins

//we will create a line made of vertex, and each vertex will receive the values of the vectors

  beginShape();
  noFill(); //no fill
  stroke(255); // black stroke
  strokeWeight(3); //5 px stroke

  for(int i = 0; i<1280-1;i++){

  float X=lerp(startPointX,endPointX,i/float(1280-1)); // create a linear interpolation between the start and the end point of the X component, and the amount of interpolation will cover the entire interval;
  float Y=lerp(startPointY,endPointY,i/float(1280-1));  // create a linear interpolation between the start and the end point of the Y component, and the amount of interpolation will cover the entire interval;
  amplitude[i].set(0,(in.left.get(i)*200),0); //set each vertex of the aray with the amplitude of the graph, acquiring the data of the buffer
  rotate2D(amplitude[i],angleInRadians); //rotate the vector of amplitude acordingly to the angle between the start and end points

  points[i].set(X,Y,0); //set each vertex of the array with the correspondent value of the interpolation, creating a flat line
  points[i].add(amplitude[i]); //add the amplitude vector to the flat line of vectors, creating a 2D graph 
  
  vertex (points[i].x,points[i].y); //draw each vertex with the values (coordinates) of the vertex
  }
  endShape();
  
  //draw the ellipses with the positions of the startpoint and endpoint
  float diam=40;
  fill(255);
  ellipse(startPointX,startPointY,diam,diam);
  ellipse(endPointX,endPointY,diam,diam);
  
}


//A function that rotates the vector

void rotate2D(PVector v, float angle) {
  // What's the magnitude?
  float m = v.mag();
  // What's the angle?
  float a = v.heading2D();
 
  // Change the angle
  a += angle;
 
  // Polar to cartesian for the new xy components
  v.x = m * cos(a);
  v.y = m * sin(a);
}


3 comments:

  1. you should consider wordpress, they have a lot of great plugins like syntax highlighting. makes great tutorials you have here a lot more readable.

    ReplyDelete
    Replies
    1. Thanks! This blog wasn't initially meant to be a tutorial blog. I started to share code a few posts ago. I'll look for Wordpress and learn how to export this blog. Thanks again!!

      Delete
    2. @Łukasz I just learned how to highlight the syntax. Thanks for the advice!!

      Delete