Tutorial: Playing Sounds in a Separate Thread
--D. Thiebaut (talk) 17:54, 10 January 2014 (EST)
This tutorial present a simple Processing sketch (developed using Processing's own IDE, and not Eclipse) that uses a thread to play sounds. Two circles bounce inside a rectangular box and a "beep" is generated every time they touche the boundaries.
The Main Sketch
// NoisyBalls.pde
// D. Thiebaut
// A sketch that animates two balls bouncing off the walls.
// It uses the minim library to play sounds.
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
// the coordinates and speeds of two circles
int x1, y1, deltax1, deltay1;
int x2, y2, deltax2, deltay2;
// the thread that plays the sounds...
MyThread sonar;
void setup() {
// create the sound player
Minim minim = new Minim(this);
AudioPlayer player = minim.loadFile( "sonar.wav" );
// define geometry and window
textAlign(CENTER);
size( 600, 400 );
smooth();
// position and activate the two circles
x1 = width/2;
y1 = height/2;
deltax1 = 4;
deltay1 = 3;
x2 = width/2;
y2 = height/2;
deltax2 = 2;
deltay2 = 5;
// create the thread and start it.
sonar = new MyThread( minim, player );
sonar.start();
}
void draw() {
// erase window
background( 0 );
// put message in middle
text( "Press any key to quit...", width/2, height/2 );
// show the two moving balls
ellipse( x1, y1, 20, 20 );
ellipse( x2, y2, 20, 20 );
// update positions of Ball 1, and if necessary change direction of movement
x1 += deltax1;
if ( x1 < 0 || x1 > width ) {
deltax1 = -deltax1;
// beep!
sonar.playNow();
}
y1 += deltay1;
if ( y1 < 0 || y1 > height ) {
deltay1 = -deltay1;
// beep!
sonar.playNow();
}
// update positions of Ball 2, and if necessary change direction of movement
x2 += deltax2;
if ( x2 < 0 || x2 > width ) {
deltax2 = -deltax2;
sonar.playNow();
}
y2 += deltay2;
if ( y2 < 0 || y2 > height ) {
deltay2 = -deltay2;
sonar.playNow();
}
}
// keyPressed(): if a key is pressed, simply stop the sketch
void keyPressed() {
// set sonar to stop running
sonar.quit();
// wait 500 ms (1/2 sec)
try {
Thread.sleep( 500 );
}
catch ( InterruptedException e ) {
}
// then exit completely
exit( );
}
The Thread Class
The thread contains an endless loop in its run() method, and will keep on checking the playNow boolean. If it is true, then the beep must be played. The endless loop is controlled by a boolean, which if true will cause the loop to end, and the run() method to stop.
import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
class MyThread extends Thread {
Minim minim;
AudioPlayer player;
boolean quit;
boolean playNow;
MyThread( Minim m, AudioPlayer p ) {
minim = m;
player = p;
quit = false;
playNow = false;
}
public void playNow() {
playNow = true;
}
public void quit() {
quit = true;
}
void run() {
while ( !quit ) {
// wait 10 ms, then check if need to play
try {
Thread.sleep( 10 );
} catch ( InterruptedException e ) {
return;
}
// if we have to play the sound, do it!
if ( playNow ) {
playNow = false;
player.play();
player.rewind();
}
// go back and wait again for 10 ms...
}
}
}
The Sound File
The sound file used is called "sonar.wav" and is available here. It is stored in a folder called data in the main sketch folder.