Recitation 9 – Sound in Processing

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);
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *