Simple Music Visualizer

arduino processing

Note

If you are new to serial communication between Arduino and Processing you refer to the (slightly long) tutorial here.

In my last post I made a glowing dodecahedron out of paper and some glue. In this project I convert the same dodecahedron to make a super simple music visualizer using Processing and Arduino.

dodecahedron

This project uses only one color of the RGB LED i.e., you can substitute the RGB LED with a usual LED. (Using the RGB LED? The wiring diagrams are on the dodecahedron post.

This is way simpler than Adafruit’s Piccolo and all it does is change the brightness of the LED based on average of the values sent to the left and right audio channels. The processing sketch uses the Minim library (included by default in recent versions of Processing) to get the values out of the audio buffer and make some (weird?) visual on the screen.

We will use the dimmer sketch to convert the values sent by the processing sketch to the equivalent LED brightness. You can upload the example sketch at ‘File >> Examples >> 04.Communication >> Dimmer’ to your Arduino to do this for you. Make sure to change the ledPin variable to the pin number your LED is connected to. Compile and upload the sketch. We can now move to the Processing sketch.

Here is the Processing sketch that we’ll be using.

/*
 * A Simple Monochromatic sound Visualizer
 *
 * This sketch plays a sound and sends the average
 * values in the audio buffer as integer values to the arduino
 * where an LED changes its brightness based on the values sent.
 *
 * This project is an extension to the "Glowing Dodecahedron"
 * project and adds a bit of functionality to the dodecahedron.
 * The "Glowing Dodecahedron" project is available with instructions
 * and required circuit diagrams at:
 * http://theblubot.blogspot.com/2014/01/glowing-dodecahedron.html
 *
 * design and code by:
 * Abhik Pal. 10th January 2014, 23:13
 */

// Importing the Minim and Serial libraries
import ddf.minim.*;
import processing.serial.*;

// creating required objects
AudioPlayer song;
Minim minim;
Serial port;

// variable to store the value to be sent
int sendVal = 255;

// variable to store whether the song is being played or not
boolean isPlaying = false;

void setup()
{
  // setting the size to be the current display size
  size(displayWidth, displayHeight);

  // setting everything up!
  minim = new Minim(this);

  // make sure to change the stuff inside the
  // "quotes" to mathch the file you want to play
  // here I'm playing "song.mp3"
  song = minim.loadFile("song.mp3");

  // change the COM port to match your Arduino's COM port
  // change the baud Rate if you have used someting
  // different from 9600 bauds.
  port = new Serial(this, "COM5", 9600);
}

void draw()
{
  // clearing out the screen by creating a rectangle
  // having dimentions of the screen size.
  fill(20);
  noStroke();
  rect(0, 0, width, height);

  // this loop is used to extract and display visuals
  // based on the values present int the audio buffer
  for (int i = 0; i < song.bufferSize() - 1; i++)
  {
    // variables to store the right and left audio values
    // i.e. sound being sent to each left and right speaker.
    float rightVal = song.right.get(i);
    float leftVal = song.left.get(i);

    // the next few lines account for the pattern being
    // displayed on the screen
    pushMatrix();
    translate(width/2, height/2);
    rotate(radians(map(i, 0, song.bufferSize(), 0, 360)));

    stroke(0, 0, 0, 10);
    strokeWeight(25);
    point(0, 150 + leftVal*200);
    point(0, 150 + rightVal*200);

    strokeWeight(2);
    stroke(220, 220, 20);
    point(0, 150 + leftVal*150);
    stroke(20, 220, 220);
    point(0, 150 + rightVal*150);

    popMatrix();

    // variable to store the average of the left and right channel
    // audio.
    float avgVal = (leftVal + rightVal)/2;

    // display a graph based on the average values
    stroke(0, 0, 0, 10);
    strokeWeight(25);
    point((width/2)-500+i, (height - 100) + avgVal*50);
    stroke(20, 220, 20);
    strokeWeight(2);
    point((width/2)-500+i, (height - 100) + avgVal*50);

    // a value to temprarily store the value to be sent.
    int tempVal = (int)(avgVal*255);
    tempVal = (int)map(abs(tempVal), 0, 255, 255, 0);

    // setting the value to be sent to be equal to the
    // temporary value.
    sendVal = tempVal;
  }

  // send out the value to your Arduino
  port.write(sendVal);

  // a bar indicating the sent values
  noStroke();
  fill(220, 220, 220);
  float rectLen = map(sendVal, 255, 0, 0, width-30);
  rect(15, 15, rectLen, 5);
}

// function to change play/pause the song each time the
// left mouse button is pressed.
void mousePressed()
{
  // if the song is already being played
  // we pause it and change the value of isPlaying variable
  if (isPlaying)
  {
    song.pause();
    isPlaying = false;
  }

  // and if it is paused we play it and change 'isPlaying' accordingly
  // :P pretty simple right?
  else
  {
    song.play();
    isPlaying = true;
  }
}

Before running the sketch you need to save it and place a sound file in the same folder that has your sketch. Also, change "song.mp3" in

song = minim.loadFile("song.mp3");

to the file that you want to play. And yes, make changes to the COM port accordingly in the following line:

port = new Serial(this, "COM5", 9600);

Connect your Arduino and run your code in ‘Present’ mode using the keyboard shortcut Ctrl + Shift + R (or by navigating to ‘Sketch >> Present’ in the Processing IDE).

Once you run your code, you need to click anywhere in the screen to play/pause the song. If the song is being played; you would see something that resembles the screenshot given below. The white bar on the top indicates the value being sent, the green graph on the bottom shows the average values in the audio buffer and the central visual changes according to the values in the left and right audio channels.

processing sketch screenshot

update

Placing the sound file you want to play in the sketch folder everytime can get very tedious very soon. The upgraded version of the visualizer uses the ‘Stereo Mix’ recording device to grab eveything from your machine’s output audio stream, hence removing the unnessary hassle. The upgraded version can be found here.


Comments