Recitation 9 – Sound in Processing

For this recitation, we use sound to do a lot of exercises. 

In the first exercise, we use keys to control the start of two sounds.

The code is below:

import processing.sound.*;

// declare three SoundFile objects
SoundFile kick;
SoundFile snare;


void setup() {
  size(640, 480);
  // create the objects and load sounds into them
  kick = new SoundFile(this, "kick.wav");
  snare = new SoundFile(this, "snare.wav");
 
}

void draw() {
  background(0);  
}

void keyPressed() {
  // when a key is pressed, use a switch statement
  // to determine which key was pressed
  // and play the appropriate sound file and set a background color
  switch(key) {
    case 'k':
      kick.play();
      background(255, 0, 0);
      break;
    case 's':
      snare.play();
      background(0, 255, 0);
      break;
    
  } 
}

 The video:

In the second exercise, we use the vibration motor to detect and show the beats of the song “Lost On The Free Way”.

The code is below:

For processing:

import processing.serial.*;


int NUM_OF_VALUES_FROM_ARDUINO = 1;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int sensorValues[];      /** this array stores values from Arduino **/

String myString = null;
Serial myPort;

import processing.sound.*;

// declare an AudioIn object
SoundFile sound;
// declare an Amplitude analysis object to detect the volume of sounds
Amplitude analysis;

void setup() {
  size(500, 500);
   sound= new SoundFile(this, "Lost On The Freeway.mp3");
   
   sound.play();
  // create the Amplitude analysis object
 
  // use the microphone as the input for the analysis
  analysis = new Amplitude(this);
  analysis.input(sound);

  setupSerial();
  
}

void draw() {
  background(0);
   println(analysis.analyze());
  background(0);
   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); 
  getSerialData();
 sensorValues[0]=int(map(analysis.analyze(),0,1,0,200));
}


void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list( )[6], 9600);

  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES_FROM_ARDUINO];
}

void getSerialData() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Arduino code:

// 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 ZD 3
#define NUM_OF_VALUES_FROM_PROCESSING 1    /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/


/** 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];
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = A0;  // analog pin used to connect the potentiometer
int val;    

void setup() {
  Serial.begin(9600);
  pinMode(ZD,OUTPUT);
   
}

void loop() {
  getSerialData();
analogWrite(ZD,200);
delay(5000);
analogWrite(ZD,0);
delay(1000);
analogWrite(ZD,100);
delay(5000);
analogWrite(ZD,0);
delay(1000);
  // 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

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

Video:

The vibration motor is kind of scary hahaha, but the moving circle is very cool that gives a feel to the atmosphere and make the music even more popping and even interactive for it engages sights in the processes of enjoying music. It was a bit hard to use the map function for a proper extent, and it was also quite tricky when making the portfolio, for the music must be included in a portfolio called data with the processing sketch in the same portfolio.

In the homework part, we tried to use amplitude to draw something on Processing, I chose to draw a line that goes up and down accordingly.

The code:

 

import processing.sound.*;

// declare an AudioIn object
AudioIn microphone;
// declare an Amplitude analysis object to detect the volume of sounds
Amplitude analysis;

int x=0;
float prediameter;
 
void setup() {
   background(198,236,255);
  size(640, 480); 
  // 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());
 
  
  // 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,  200, 0);
  // draw a circle based on the microphone amplitude (volume)
 
 
  x=x+1;
  strokeWeight(5);
  stroke(252,199,199);
  line(x, prediameter,x+1,diameter); 
  
  
  prediameter=diameter;
}

 Video:

It’s really fun to “see” your voice and to make different waves with it. However, it’s not so sensitive, I need to be very loud or very sharp can I make the line wave dramatically.

Leave a Reply

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