Exercise 1: Virtual Music Launchpad
Code:
import processing.sound.*; // declare a SoundFile object SoundFile crashbreak; SoundFile kickcrash; SoundFile pollyunilead1; SoundFile plunkysynthloop; boolean a = false; boolean f = false; boolean j = false; boolean l = false; void setup() { size(640, 480); // create the object and load a file into it crashbreak = new SoundFile(this, "crashbreak2rideout.wav"); kickcrash = new SoundFile(this, "kickcrash.wav"); pollyunilead1 = new SoundFile(this, "pollyunilead1.wav"); plunkysynthloop = new SoundFile(this, "plunkysynthloop.wav"); } void draw() { background(0); rect(80, 50, 220, 160); rect(340, 50, 220, 160); rect(80, 270, 220, 160); rect(340, 270, 220, 160); println(a); } void keyPressed() { switch(key) { case 'a': crashbreak.play(); break; case 'f': kickcrash.play(); break; case 'j': pollyunilead1.play(); break; case 'l': plunkysynthloop.play(); break; } }
Exercise 2: Haptic Sound Wearable
Code:
At first, I didn’t know how to use Amplitude analysis to analyze the sound in the computer. After trying, I found it quite easy: all I need was to change “AudioIn” to “SoundFlie” and change “microphone” to “sound”.
Arduino:
// IMA NYU Shanghai // Interaction Lab /** This example is to send multiple values from Processing to Arduino. You can find the Processing example file in the same folder which works with this Arduino file. **/ #define NUM_OF_VALUES_FROM_PROCESSING 3 /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ #define ZD 3 /** DO NOT REMOVE THESE **/ int tempValue = 0; int valueIndex = 0; /* This is the array of values storing the data from Processing. */ int processing_values[NUM_OF_VALUES_FROM_PROCESSING]; void setup() { Serial.begin(9600); pinMode(3, OUTPUT); } void loop() { getSerialData(); // add your code here using elements in the values array //this is an example connecting a buzzer to pin 8 /* if (processing_values[0] == 1) { //turn on an LED when the mouse is pressed digitalWrite(13, HIGH); // map values from mouseX to frequency from (0 - 500 pixels) //to the output pitch range (120 - 1500Hz) int f = map(processing_values[1], 0, 500, 120, 1500); // map values from mouseY to frequency from (0 - 500 pixels) //to the output duration range (10 - 2000 milliseconds) int d = map(processing_values[2], 0, 500, 10, 2000); // play the pitch: tone(8, processing_values[1], processing_values[2]); delay(1); // delay in between reads for stability } else { digitalWrite(13, LOW); } */ //end of example if (processing_values[0] == 1) { analogWrite(ZD, 200); delay(100); } if (processing_values[0] == 0) { analogWrite(ZD, 0); delay(0); } } //receive serial data from Processing void getSerialData() { while (Serial.available()) { char c = Serial.read(); //switch - case checks the value of the variable in the switch function //in this case, the char c, then runs one of the cases that fit the value of the variable //for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase switch (c) { //if the char c from Processing is a number between 0 and 9 case '0'...'9': //save the value of char c to tempValue //but simultaneously rearrange the existing values saved in tempValue //for the digits received through char c to remain coherent //if this does not make sense and would like to know more, send an email to me! tempValue = tempValue * 10 + c - '0'; break; //if the char c from Processing is a comma //indicating that the following values of char c is for the next element in the values array case ',': processing_values[valueIndex] = tempValue; //reset tempValue value tempValue = 0; //increment valuesIndex by 1 valueIndex++; break; //if the char c from Processing is character 'n' //which signals that it is the end of data case '\n': //save the tempValue //this will b the last element in the values array processing_values[valueIndex] = tempValue; //reset tempValue and valueIndex values //to clear out the values array for the next round of readings from Processing tempValue = 0; valueIndex = 0; break; } } }
Processing:
// IMA NYU Shanghai // Interaction Lab /** * This example is to send multiple values from Processing to Arduino. * You can find the arduino example file in the same folder which works with this Processing file. **/ import processing.serial.*; import processing.sound.*; SoundFile sound; Amplitude analysis; int NUM_OF_VALUES_FROM_PROCESSING = 1; /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ int processing_values[] = new int[NUM_OF_VALUES_FROM_PROCESSING]; /** this array stores values you might want to send to Arduino **/ Serial myPort; String myString; void setup() { size(500, 500); background(0); setupSerial(); sound = new SoundFile(this, "Lost On The Freeway.mp3"); sound.loop(); analysis = new Amplitude(this); analysis.input(sound); } void draw() { println(analysis.analyze()); background(0); // analyze the audio for its volume level float volume = analysis.analyze(); // map the volume value to a useful scale float diameter = map(volume, 0, 1, 0, width); // draw a circle based on the microphone amplitude (volume) circle(width/2, height/2, diameter); if (volume > 0.5) { processing_values[0] = 1; } else { processing_values[0] = 0; } // give values to the variables you want to send here //change the code according to your project //for example: /* if (mousePressed) { processing_values[0] = 1; } else { processing_values[0] = 0; } processing_values[1] = mouseX; processing_values[2] = mouseY; */ //end of example // send the values to Arduino. sendSerialData(); } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[2], 9600); // WARNING! // You will definitely get an error here. // Change the PORT_INDEX to 0 and try running it again. // And then, check the list of the ports, // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" // and replace PORT_INDEX above with the index number of the port. myPort.clear(); // Throw out the first reading, // in case we started reading in the middle of a string from the sender. myString = myPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII myString = null; } void sendSerialData() { String data = ""; for (int i=0; i<processing_values.length; i++) { data += processing_values[i]; //if i is less than the index number of the last element in the values array if (i < processing_values.length-1) { data += ","; // add splitter character "," between each values element } //if it is the last element in the values array else { data += "\n"; // add the end of data character linefeed "\n" } } //write to Arduino myPort.write(data); print(data); // this prints to the console the values going to arduino }
Homework: Voice controlled puppet
After the practicing in exercise 2, everything went quite well.
Code
import processing.sound.*; // declare an AudioIn object AudioIn microphone; // declare an Amplitude analysis object to detect the volume of sounds Amplitude analysis; void setup() { size(800, 800); // create the AudioIn object and select the mic as the input stream microphone = new AudioIn(this, 0); // start the mic input without routing it to the speakers microphone.start(); // create the Amplitude analysis object analysis = new Amplitude(this); // use the microphone as the input for the analysis analysis.input(microphone); } void draw() { println(analysis.analyze()); background(165, 247, 175); fill(63, 170, 250); ellipse(mouseX, mouseY, 400, 300); translate(mouseX, mouseY); fill(0); circle(-70, -50, 20); circle(70, -50, 20); // analyze the audio for its volume level float volume = analysis.analyze(); // map the volume value to a useful scale float diameter = map(volume, 0, 1, 0, width/2); // draw a circle based on the microphone amplitude (volume) //circle(width/2, height/2, diameter); fill(225, 147, 149); circle(0,60, 50+diameter); }