Feel the Music

Posted by karthik

karthik's picture

The Instrument:

We adapted the concept of a Theremin, as we felt it's really cool to be able to generate music with just motion and no contact. We also wanted to add a gaming aspect to the instrument, in effect making one player copy the hand motions of the other. The metaphor was someone dancing to match an instructor, but producing music as they went along. 

The instrument consists of two pads, each with two light sensors. The left hand controls the octave, while the right hand controls the notes. The sound is output using the piezo speakers.

Modes:

Freestyle:

Go wild and play away in this mode! Lift your left hand high to scale the notes to higher octaves, while your right hand beats out the notes. 

Game:

Here, Player2 has to match player1 for music to play. Player1 will play a note using a hand gesture, and the instrument will stay silent until Player2 uses an identical gesture.

Video:

http://www.youtube.com/watch?v=HzhTy-r_vIE

 

Code:

/* note frequency period PW (timeHigh)
 * c        261 Hz        3830 1915
 * d        294 Hz        3400 1700
 * e        329 Hz        3038 1519
 * f        349 Hz        2864 1432
 * g        392 Hz        2550 1275
 * a        440 Hz        2272 1136
 * b        493 Hz        2028 1014
 * C        523 Hz        1912 956
 *
 * (cleft) 2005 D. Cuartielles for K3
 */
int photo1a = A0;
int photo1b = A1;
int photo2a = A4;
int photo2b = A5;
int speakerPin1 = 3;
int speakerPin2 = 5;
int aval1a;
int aval1b;
int aval2a;
int aval2b;
int val1a;
int val1b;
int val2a;
int val2b;
int aval1;
int mode = 0;
int aval2;
int octave;
int note;
String note1;
char input;
float timeHigh;
float tones1[] = { 
  16.35, 18.35, 20.60, 21.83, 24.5, 27.5, 30.87};
int tones2[] = { 
  1960, 1850, 1746, 1648, 1555, 1468, 1385, 1308};
int tones3[] = { 
   1648, 1555, 1468, 1385, 1308,1960, 1850, 1746};
 
 
int tone1store;
void setup() {
  Serial.begin(9600);
  pinMode(speakerPin1, OUTPUT); 
  pinMode(speakerPin2, OUTPUT); 
  //ambient max
  aval1a = analogRead(photo1a);    // read value from the sensor
  aval1b = analogRead(photo1b);    // read value from the sensor
  aval2a = analogRead(photo2a);    // read value from the sensor
  aval2b = analogRead(photo2b);    // read value from the sensor
  aval1 = aval1a*10+aval1b;
  aval2 = aval2a*10+aval2b;
 
}
 
String Notemaker(int octave, int note)
// takes octave and note to return a string that minim reads Eg: C4, E3
{
  String note1;
  switch(note)
  {
    case 0: note1 = "C";
    break;
    case 1: note1 = "D";
    break;
    case 2: note1 = "E";
    break;
    case 3: note1 = "F";
    break;
    case 4: note1 = "G";
    break;
    case 5: note1 = "A";
    break;
    case 6: note1 = "B";
    break;
  }
  note1 = note1+octave;
  return note1;
}
 
void loop() {
 if(Serial.available()>0){
    input = Serial.read();
    if((input == 'g')||(input == 'G')) {
      mode = 1;
    }
    else if((input == 'f')||(input == 'F')) {
      mode = 2;
    }
  }
     
       if(mode == 1) {
 
 
    digitalWrite(speakerPin1, LOW);
    digitalWrite(speakerPin2, LOW);
 
    val1a = abs(aval1a - analogRead(photo1a));    // read value from the sensor
    val1b = abs(aval1b - analogRead(photo1b));    // read value from the sensor
 
    int toneBase1 = val1a*10 + val1b;
 
    int tone1 = map(toneBase1,0,aval1,0,7);
 
    for( int i=0; i<50; i++ ) {   // play it for 50 cycles
      digitalWrite(speakerPin1, HIGH);
      delayMicroseconds(tones2[tone1]);
      digitalWrite(speakerPin1, LOW);
      delayMicroseconds(tones2[tone1]);
    }
    int exit = 0;
    while(exit==0) {
 
      val2a = abs(aval2a - analogRead(photo2a));    // read value from the sensor
      val2b = abs(aval2b - analogRead(photo2b));    // read value from the sensor
      int toneBase2 = val2a*10 + val2b;
      int tone2 = map(toneBase2,0,aval2,0,7);
 
 
      if(abs(tone1-tone2)<1) {
        for( int i=0; i<50; i++ ) {   // play it for 50 cycles
          digitalWrite(speakerPin2, HIGH);
          delayMicroseconds(tones3[tone2]);
          digitalWrite(speakerPin2, LOW);
          delayMicroseconds(tones3[tone2]);
        }
        exit=1;
      }
    }
   }    
    if(mode == 2) // freestyle
    {
    digitalWrite(speakerPin1, LOW);
    digitalWrite(speakerPin2, LOW);  
    val1a = abs(aval1a - analogRead(photo1a));    // read value from the sensor
    val1b = abs(aval1b - analogRead(photo1b));    // read value from the sensor
    
    // calculate octave
    if(val1a >= 200)
      val1a = 200;
    val1a = 200 - val1a;
    octave = map(val1a,0,200,3,5);
    // calculate note
    if(val1b >= 200)
      val1b = 200;
    val1b = 200 - val1b;
    note = map(val1b,0,200,0,6);
    note1 = Notemaker(octave,note);      
    
    // play the note
    float note2 = tones1[note];
    Serial.print("note = ");
    Serial.println(note2);
    for(int i = 1;i<octave;i++)
       note2 = note2*2;
    timeHigh = 1000000.0/(2.0 * note2);
    Serial.print("note2 ");
    Serial.println(note2);
    Serial.print("timeHigh ");
    Serial.println(timeHigh);
    Serial.print("octave ");
    Serial.println(octave);
     for( int i=0; i<8; i++ ) {   // play it for 50 cycles
      digitalWrite(speakerPin1, HIGH);
      delayMicroseconds(timeHigh);
      digitalWrite(speakerPin1, LOW);
      delayMicroseconds(timeHigh);
    }
//    delayMicroseconds(100);
    digitalWrite(speakerPin1,LOW);
    //Serial.println(5);
    val2a = abs(aval2a - analogRead(photo2a));    // read value from the sensor
    val2b = abs(aval2b - analogRead(photo2b));    // read value from the sensor
 
// calculate octave
    if(val2a >= 200)
      val2a = 200;
    val2a = 200 - val2a;
    octave = map(val2a,0,200,3,5);
    // calculate note
    if(val2b >= 200)
      val2b = 200;
    val2b = 200 - val2b;
    note = map(val1b,0,200,0,6);
    note1 = Notemaker(octave,note);      
    
    // play the note
    note2 = tones1[note];
    Serial.print("note = ");
    Serial.println(note2);
    for(int i = 1;i<octave;i++)
       note2 = note2*2;
    timeHigh = 1000000.0/(2.0 * note2);
    Serial.print("note2 ");
    Serial.println(note2);
    Serial.print("timeHigh ");
    Serial.println(timeHigh);
    Serial.print("octave ");
    Serial.println(octave);
     for( int i=0; i<8; i++ ) {   // play it for 50 cycles
      digitalWrite(speakerPin2, HIGH);
      delayMicroseconds(timeHigh);
      digitalWrite(speakerPin2, LOW);
      delayMicroseconds(timeHigh);
    }
//    delayMicroseconds(100);
    digitalWrite(speakerPin2,LOW);
  }
}
 
 
 
 
 
 
 

 

 

0
Your rating: None