Coursework1

 

Interactive Music Box

I create an interactive music display to experiment and explore with real-time digital signal processing. This project uses an Arduino to read and send x, y and z coordinates from an accelerometer to Processing which process the analog signal to shifts and manipulates series of video sequence, sound loops and audio effects.

Hardware Required to build this project are:

  1. Arduino Board
  2. Breadboard
  3. Axis Accelerometer
  4. Some Wires
  5. USB cable

Circuit

Connecting a three axis accelerometer to Arduino board is very simple. It is powers by 3.3v with ground (GND) and the X,Y,Z are connect to 1, 2, 3 analog input pins respectively. Then plug your Arduino board into your computer using a usb cable.

Arduino Library fro Processing and Firmata

Start the Arduino program, and open Firmata coad from Arduino examples, and then upload it to your Arduino.

File > Examples > Firmata > StandardFirmata

Firmata is a standard firmware (program) for communication with microcontrollers from differnt software. It will enable you to program Arduinoboard from with in Processing using Arduino library.

Code

In the Processing sketch below, I first import Arduino library for processing following by audio and video libraries. Furthmore, I define each Hashmap for sound loop, audio effects and video sequences.


//Shayaan Masood Khan
//Interactive Music Box

import processing.serial.*;      //import processing serial library
import cc.arduino.*;             //import Arduino library for processing
import ddf.minim.analysis.*;     //import minim.analysis library to handle sound
import ddf.minim.*;              //import minim library to manipulate sound
import processing.video.*;       //import processing video library to display video sequences

//Defing Arduino
Arduino arduino;

//Sound for the project
Minim minim;

//Defining Sound HashMasps to store array of sound loops and effects
HashMap<integer, audiosnippet=""> soundMap = new HashMap<integer, audiosnippet="">();
HashMap<integer, audiosnippet=""> EffectsMap = new HashMap<integer, audiosnippet="">();

AudioPlayer Bg;         //defing minim audioPlayer for background sound
AudioSnippet Sound01;   //defing sound loops as minin audioSnippets
AudioSnippet Sound02; 
AudioSnippet Sound03; 
AudioSnippet Sound04; 
AudioSnippet Sound05; 

AudioSnippet Effects01; //defing sound effect 1 loop as minin audioSnippets
AudioSnippet Effects02; 
AudioSnippet Effects03; 
AudioSnippet Effects04; 
AudioSnippet Effects05; 

//Video HashMaps to store array of video sequences
HashMap<integer, movie=""> videoMap = new HashMap<integer, movie="">();

Movie theMov1; //defing movie class for video 1
Movie theMov2;
Movie theMov3;
Movie theMov4;
Movie theMov5;

int videoWidth = 1366 ; //width of video
int videoHeight = 768 ; //height of video

//Analog input pins from Arduino
int xPin = 3; //declaring Arduino analog pin3 for x coordinate
int yPin = 2; //declaring Arduino analog pin2 for y coordinate
int zPin = 1; //declaring Arduino analog pin1 for z coordinate

//defing variables to hold old values
int movieOld;
int soundOld;
int effectOld;

Inside setup i define processing attributes such as size, frame rate, background, etc and populate HashMaps with  sound loops, audio effects and video sequence’ file names.



void setup() {

  arduino = new Arduino(this, Arduino.list()[0], 57600);
//println(Arduino.list()); //to read what your COM PORT

  size(videoWidth, videoHeight);
  frameRate(30);
  background (0);
  smooth();
  rectMode(CENTER);
  ellipseMode(CENTER);
  imageMode(CENTER);
  strokeWeight(2);
  fill(255);
  noCursor();

//calling minim class 
  minim = new Minim(this);

//setting background sound as minim playback, giving it a file name and 19000 sample rate
  Bg = minim.loadFile("Bg.wav", 19000);     

//seting sound loops as minim snippet by giving it source file name 
  Sound01 = minim.loadSnippet("Sound01.wav"); 
  Sound02 = minim.loadSnippet("Sound02.wav");
  Sound03 = minim.loadSnippet("Sound03.wav");
  Sound04 = minim.loadSnippet("Sound04.wav");
  Sound05 = minim.loadSnippet("Sound05.wav");

//populating sound efffect HashMap
  soundMap.put(1, Sound01); 
  soundMap.put(2, Sound02); 
  soundMap.put(3, Sound03); 
  soundMap.put(4, Sound04); 
  soundMap.put(5, Sound05); 

//seting audio effects as minim snippet by giving it source file name
  Effects01 = minim.loadSnippet("Effect01.wav");
  Effects02 = minim.loadSnippet("Effect02.wav");
  Effects03 = minim.loadSnippet("Effect03.wav");
  Effects04 = minim.loadSnippet("Effect04.wav");
  Effects05 = minim.loadSnippet("Effect05.wav");

//populating audio effect HashMap
  EffectsMap.put(1, Effects01); 
  EffectsMap.put(2, Effects02); 
  EffectsMap.put(3, Effects03); 
  EffectsMap.put(4, Effects04); 
  EffectsMap.put(5, Effects05); 

//defing Movie as move class
  theMov1 = new Movie(this, "comp1.mov");
  theMov2 = new Movie(this, "comp2.mov");
  theMov3 = new Movie(this, "comp3.mov");
  theMov4 = new Movie(this, "comp4.mov");
  theMov5 = new Movie(this, "comp5.mov");

  theMov1.loop();  //plays the movie over and over
  theMov2.loop();
  theMov3.loop();
  theMov4.loop();
  theMov5.loop();

//populating video HashMap 
  videoMap.put(1, theMov1); 
  videoMap.put(2, theMov2); 
  videoMap.put(3, theMov3); 
  videoMap.put(4, theMov4); 
  videoMap.put(5, theMov5);
}

Below is the Processing code which changes the video sequence, audio loops and sound effects depending on the values received from the accelerometer via Arduino.

void draw() {

  background (0);

  //Read analog pins from Arduino
  int xRead = (arduino.analogRead(xPin)) /5;
  int yRead = (arduino.analogRead(yPin)) /5;
  int zRead = (arduino.analogRead(zPin)) /5;

  //map the reading of accelerometer's X,Y and Z between integer values from 1 to 5  
  int xmovie = int(map(xRead, 50, 100, 1, 5));
  int xsound = int(map(xRead, 50, 100, 1, 5));
  int ysound = int(map(xRead, 50, 100, 1, 5));

  //play the background Sound again and again 
  Bg.loop();

  //===================================================================================================
  //Controle SOUND using X coordinate ===============================================================
  if ((xsound >= 1 ) && (xsound < 6)) { //Controle Sound

    if ((soundOld != 0) &&(xsound != soundOld)) {

      soundMap.get(soundOld).pause();
    }

    if (ysound != soundOld) {

      soundMap.get(xsound).loop();
      soundOld = xsound;
    }
  }

  //===================================================================================================
  //Controle EFFECTS using Y coordinate ===============================================================
  if ((ysound >= 1 ) && (ysound < 6)) { //Controle Sound

    if ((effectOld != 0) &&(ysound != effectOld)) {

      EffectsMap.get(effectOld).pause();
    }

    if (ysound != soundOld) {

      EffectsMap.get(xsound).loop();
      effectOld = ysound;
    }
  }

  //===================================================================================================
  //Controle VIDEO using X coordinate ===============================================================
  if ((xmovie >= 1 ) && (xmovie < 6)) { 

    if (movieOld != 0) {

      videoMap.get(movieOld).pause();
      theMov1.pause();
      theMov2.pause();
      theMov3.pause();
      theMov4.pause();
      theMov5.pause();
    }

    videoMap.get(xmovie).play();
    image(videoMap.get(xmovie), width/2, height/2, videoWidth, videoHeight);

    movieOld = xmovie;
  }
}

void stop()
{
  //close Minim audio classes before exiting

  Bg.close();
  EffectsMap.get(effectOld).close();
  soundMap.get(soundOld).close();

  minim.stop();

  super.stop();
}

void movieEvent(Movie m) { 
  m.read();
}