Processing comes complete with a fully featured sound library to handle the playing and analysis of sounds. In order to use this library we must import it. To do this go to Sketch -> Import Library -> Minim Audio
In order to use the Minim class we first need to create a Minim Object in our code so we can call the necessary methods to get our sound working.
We'll probably want to use our Minim reference variable throughout our sketch, so we'll place the following line of
code outside our setup and draw method, to give it a global scope.
Minim minim; declare a reference variable of type Minim
Now inside our setup we need to initialize the variable minim.
minim = new Minim(this);
This will create a new Minim object and assign the reference to our variable.
Why do we pass in "this" as an argument to Minim?
This is because the Minim library needs to know certain things about our sketch. We use the special keyword "this" to refer to the current object instance in which we are coding. In this case it is the instance of our currently running sketch.
In order to play a song, we must first create an instance of the AudioPlayer class. This is a class inside the Minim library that handles the playing of sounds.
We'll probably want most (if not all) of our sounds to have global scope, like the Minim object, so that we can use and control
them throughout our sketch. Let's declare the AudioPlayer reference variable outside our setup.
Now to initialize our song we need to create a new instance of the AudioPlayer class (an AudioPlayer object). We'll do this inside our setup method.
song = minim.loadFile("song.mp3", 2048);
Notice how we're actually using the loadFile method of the minim object? This is because the Minim class handles the loading of mp3 or wav files and then passes back a reference to the loaded sound (with the type AudioPlayer) which can be assigned to a reference variable of type AudioPlayer.
Our new AudioPlayer object instance with our sound loaded comes packed with cool features. Let's take a look.
song.play(); play from current position
song.pause(); stop at current position
song.rewind(); go to beginning
song.loop(); loop forever
song.loop(int n); loop n times
song.position(); returns play position in millis.(int)
song.cue(int p); set play position to p millis.
song.length(); returns length millis.(int)
song.setLoopPoints(int b, int e);
Sets the song to loop between points b and e in millis.
In order to analyze sound, we need to declare and initialize one more object. The class for this object is called FFT which is
short for Fast Fourier Transform. The specifics of this are not necessary to know, but the basic understanding is this:
A Fast Fourier Transform takes an analog wave signal and breaks it into a series of digital approximations. What does that mean in english? The wave of a song is broken into it's components: lows, mids, highs, and we are given the level of each one.
To create an FFT object we again declare this reference variable with a global scope.
Inside our setup method we'll need to initialize our new fft reference variable with an instance of the FFT class.
fft = new FFT(song.bufferSize(), song.sampleRate());
Notice how we pass in two arguments, the song buffer size and sample rate. This is so the FFT object will know about the size and shape of our song data.
Now that we have our FFT object instance we can use some of the methods of the FFT class to analyze our sound.
Inside our draw loop we will need to update our FFT variable with the latest information about our song.
Since we don't care about stereo sound, we call fft.forward(song.mix) to advance the fft analysis of our song playing and mix the left and right audio channels together.
println( fft.getBand(0) );
This will print out the first average value in our fft object. This is the lowest frequency sound of our song, and what is printed will be the volume, or level of that sound.