Thursday, November 8, 2012

Midi to waveform representation in Processing



Here I'll show how to convert midi notes to frequency, and how to show that frequency with a sine wave


//click on the note numbers to get the respective frequency 
  
float hertz;
  
int noteNumber;//variable for the midi note
  
int xspacing = 5;   // How far apart should each horizontal location be spaced
  
int w;              // Width of entire wave
  
  
  
int theta = 0;  // Start angle at 0
  
float ampl;  // Height of wave
  
float period = 100.0;  // How many pixels before the wave repeats
  
float dx;  // Value for incrementing X, a function of period and xspacing
  
float[] yvalues;  // Using an array to store height values for the wave
  
  
  
void setup() {
  
  size(640, 360);
  
  w = width+16;
  
  dx = (TWO_PI / period) * xspacing;
  
  yvalues = new float[w/xspacing];
  
}
  
  
  
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[100]; //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[100]; //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<100-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
  
  
  
textSize(28);
  
fill(255);
  
text("60",30,40);
text("69",width-60,40);
text("100",30,height-40);
text("127",width-60,height-40);
  
text("hertz "+hertz,width-300,height/2+100);
  
  
  
if(mousePressed){
  
  if((mouseX>10&&mouseX<50) && (mouseY>10&&mouseY<60)){
  
    noteNumber=60;
  
  }
  
  if((mouseX>width-80&&mouseX<width) && (mouseY>10&&mouseY<60)){
  
    noteNumber=69;
  
  }
  
   if((mouseX>10&&mouseX<50) && (mouseY>height-70&&mouseY<height)){
  
    noteNumber=100;
  
  }
  
    if((mouseX>width-80&&mouseX<width) && (mouseY>height-70&&mouseY<height)){
  
    noteNumber=127;
  
  }
  
  
}
  
println("noteNumber "+ noteNumber);
  
//convert midi to frequency
  
    
hertz = ( 440*pow(2,((noteNumber-69)/12.0))) ;
println("hertz "+ hertz);
  
  
  
  ampl=20;//aplitude of 20px
  
  
  
  // For every x value, calculate a y value with sine function
  

  
  for (int i = 0; i < 100-1; i++) {
 
    
    theta += int(hertz);
   theta+=int(dx);
   if(theta%1000==0){//reset theta
     theta=0;
   }
   
    yvalues[i] = sin(theta)*ampl;
  
   println(theta);  
  
  }
  
 
  
  
  
  beginShape();
  
  noFill(); //no fill
  
  stroke(255); // white stroke
  
  strokeWeight(2); //2 px stroke
  
  
  
  for(int i = 0; i<100-1;i++){
  
  
  
  float X=lerp(startPointX,endPointX,i/float(99)); // 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(99));  // 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,(yvalues[i]),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. Great set of tips from the master himself. Excellent ideas. Thanks for Awesome tips Keep it up
    rawdigger-Free Download

    ReplyDelete
  2. So nice I am enjoying for that post as for u latest version of this Security tool Available
    webcammax-crack
    mirillis-action-crack
    rawdigger-crack

    ReplyDelete