Integrating sound with a Processing sketch can be accomplished in a number of different ways. You may want to communicate with another programming environment like PureData, MAX/MSP, SuperCollider or Ableton Live. This can be preferable given that these applications have a comprehensive set of features for sophisticated sound work. Processing can communicate with these applications via a variety of methods. One approach is to use OSC (open sound control) , a protocol for network communication between applications. This can be accomplished using the oscP5 library or the network library. For now let's work on some basics
Start with an import statement.
import processing.sound.*;
Before a sound can be played, it must be loaded into memory. Use a SoundFile object to store a reference to a sound from a file.
SoundFile song;
Now initialize the object by passing the sound filename to the constructor, along with a reference to this.
song = new SoundFile(this, "lalala.mp3");
Just as with images, loading the sound file from the hard drive is a slow process so make sure you put that line of code in setup() .The type of sound files compatible with Processing is limited. You can use wav, aiff, and mp3. You need to get comfortable converting files using outside sources like Audacity or Itunes. Once the sound is loaded playing is easy.
song.play(); //play function plays the sound once
If you want your sound to loop forever, call loop() instead.
song.loop(); //forever ever, forever ever
A sound can be stopped with stop() or pause(). Try the following sketch where the loop restarts whenever the user clicks the mouse.
import processing.sound.*;
// A Sample object (for a sound)
SoundFile song;
void setup() {
size(480, 270);
song = new SoundFile(this, "beat.mp3");
song.play();
}
void draw() {
background(255);
noLoop();
}
boolean playing = true;
void mousePressed() {
//if (song.isPlaying()) {
if (playing) {
song.stop();
playing = false;
} else {
song.play();
playing = true;
}
}
The doorbell class shows a simple button functionality rollover and click. This is useful for short sound effects. Note the addition of song.isPlaying() to determine if the sound is playing or not. Here the mouse toggles the sound's state. If it's playing, it stops. If it's not, it plays. Try this code!
import processing.sound.*;
// Example 20-2: Doorbell with Sonia
// A sound file object
SoundFile dingdong;
// A doorbell object (that will trigger the sound)
Doorbell doorbell;
void setup() {
size(200, 200);
// Load the sound file
dingdong = new SoundFile(this, "doorbell.mp3");
// Create a new doorbell
doorbell = new Doorbell(width/2, height/2, 64);
}
void draw() {
background(255);
// Show the doorbell
doorbell.display(mouseX, mouseY);
}
void mousePressed() {
// If the user clicks on the doorbell, play the sound!
if (doorbell.contains(mouseX, mouseY)) {
dingdong.play();
}
}
class Doorbell {
// Location and size
float x;
float y;
float r;
// Create the doorbell
Doorbell(float x_, float y_, float r_) {
x = x_;
y = y_;
r = r_;
}
// Is a point inside the doorbell? (used for mouse rollover, etc.)
boolean contains(float mx, float my) {
if (dist(mx, my, x, y) < r) {
return true;
} else {
return false;
}
}
// Show the doorbell (hardcoded colors, could be improved)
void display(float mx, float my) {
if (contains(mx, my)) {
fill(100);
} else {
fill(175);
}
stroke(0);
strokeWeight(4);
ellipse(x, y, r, r);
}
}
You will notice that the Doorbell example plays the sound and restarts every time you click. Sometimes you want to stop a sound from restarting . The simplest way to achieve such a result is always to check and see if a sound is playing before you call the play() function. The funtion isPlaying() does exactly this, returning true or false.
if (!dingdong.isPlaying()) {
dingdong.play();
}
Easy peasy.
During playback, a sound sample can be manipulated in real time. Volume, pitch and pan can all be controlled.
Let's start with volume. The technical word for volume in the world of sound is amplitude. A SoundFile object's volume can be set with the amp() function, which takes a floating point value between 0.0 and 1.0 (0.0 being silent, 1.0 being the loudest). The following snippet assumes a file named "song.mp3" and sets its volume based on mouseX position (by mapping it to a range between 0 and 1).
float volume = map(mouseX, 0 , width, 0, 1); //volume ranges from 0 to 1
song.amp(volume);
Panning refers to volume of the sound in two speakers (left and right). If the sound is panned all the way to the left it will sound really loud from the left. You need to code, similar to volume but for a variable called panning.
float panning = map(mouseX, 0, width, -1, 1); //pan ranges from -1 to 1
song.pan(panning);
Try the following code and observe volume & speed. EXERCISE Change the code to allow panning.
import processing.sound.*;
// A sound file object
SoundFile song;
void setup() {
size(200, 200);
// Load a sound file
song = new SoundFile(this, "beat.mp3");
// Loop the sound forever
// (well, at least until stop() is called)
song.loop();
}
void draw() {
background(255);
// Set the volume to a range between 0 and 1.0
float volume = map(mouseX, 0, width, 0, 1);
song.amp(volume);
// Set the rate to a range between 0.1 and 4
// Changing the rate alters the pitchf
float speed = map(mouseY, 0, height, 0, 2);
song.rate(speed);
// Draw some circles to show what is going on
stroke(0);
fill(51, 100);
ellipse(mouseX, 100, 48, 48);
stroke(0);
fill(51, 100);
ellipse(100, mouseY, 48, 48);
}
import processing.sound.*;
SoundFile soundFile;
void setup() {
size(200, 200);
soundFile = new SoundFile(this, "beat.mp3");
soundFile.loop();
}
void draw() {
background(255);
// Map mouseX to a panning value (between -1.0 and 1.0)
float panning = map(mouseX, 0., width, -1.0, 1.0);
soundFile.pan(panning);
// Draw a circle
stroke(0);
fill(51, 100);
ellipse(mouseX, 100, 48, 48);
}
import processing.sound.*;
WhiteNoise noise;
void setup() {
size(200, 200);
noise = new WhiteNoise(this);
noise.play();
}
void draw() {
background(255);
float vol = map(mouseX, 0, width, 0, 1);
noise.amp(vol);
ellipse(mouseX, 100, 32, 32);
}
*drops mike*
First try the following examples using the microphone. Make sure your microphone on your computer works.
import processing.sound.*;
AudioIn input;
Amplitude analyzer;
void setup() {
size(200, 200);
// Start listening to the microphone
// Create an Audio input and grab the 1st channel
input = new AudioIn(this, 0);
// start the Audio Input
input.start();
// create a new Amplitude analyzer
analyzer = new Amplitude(this);
// Patch the input to an volume analyzer
analyzer.input(input);
}
void draw() {
background(255);
// Get the overall volume (between 0 and 1.0)
float vol = analyzer.analyze();
fill(127);
stroke(0);
// Draw an ellipse with size based on volume
ellipse(width/2, height/2, 10+vol*200, 10+vol*200);
}
import processing.sound.*;
AudioIn input;
Amplitude analyzer;
void setup() {
size(200, 200);
background(255);
// Start listening to the microphone
// Create an Audio input and grab the 1st channel
input = new AudioIn(this, 0);
// start the Audio Input
input.start();
// create a new Amplitude analyzer
analyzer = new Amplitude(this);
// Patch the input to an volume analyzer
analyzer.input(input);
}
void draw() {
// Get the overall volume (between 0 and 1.0)
float volume = analyzer.analyze();
// If the volume is greater than 0.5 a rectangle is drawn at a random location in the window.
// The louder the volume, the larger the rectangle.
float threshold = 0.1;
if (volume > threshold) {
stroke(0);
fill(0, 100);
rect(random(40, width), random(height), 20, 20);
}
// Graph the overall volume and show threshold
float y = map(volume, 0, 1, height, 0);
float ythreshold = map(threshold, 0, 1, height, 0);
noStroke();
fill(175);
rect(0, 0, 20, height);
// Then draw a rectangle size according to volume
fill(0);
rect(0, y, 20, y);
stroke(0);
line(0, ythreshold, 19, ythreshold);
}
import processing.sound.*;
AudioIn input;
Amplitude rms;
float clapLevel = 0.3; // How loud is a clap
float threshold = 0.1; // How quiet is silence
boolean clapping = false;
void setup() {
size(200, 200);
background(255);
// Start listening to the microphone
// Create an Audio input and grab the 1st channel
input = new AudioIn(this, 0);
// start the Audio Input
input.start();
// create a new Amplitude analyzer
rms = new Amplitude(this);
// Patch the input to an volume analyzer
rms.input(input);
}
void draw() {
// Get the overall volume (between 0 and 1.0)
float vol = rms.analyze();
// If the volume is greater than 0.5, and we were not previously clapping, then we are clapping!
if (vol > clapLevel && !clapping) {
stroke(0);
fill(0, 100);
rect(random(40, width), random(height), 20, 20);
clapping = true; // We are now clapping!
} else if (clapping && vol < threshold) {
// Otherwise, if we were just clapping and the volume level has gone down below 0.25, then we are no longer clapping!
clapping = false;
}
// Graph the overall volume
// First draw a background strip
noStroke();
fill(200);
rect(0, 0, 20, height);
float y = map(vol, 0, 1, height, 0);
float ybottom = map(threshold, 0, 1, height, 0);
float ytop = map(clapLevel, 0, 1, height, 0);
// Then draw a rectangle size according to volume
fill(100);
rect(0, y, 20, y);
// Draw lines at the threshold levels
stroke(0);
line(0, ybottom, 19, ybottom);
line(0, ytop, 19, ytop);
}