Processing + Leap Motion Controller + Minim
Objective:
I want to control a synthesised sound by moving my hand in space.
Requirements:
Leap Motion library for Processing Library
Minim Audio Library for Processing
Here’s the result:
And here’s the processing code with comments:
import com.leapmotion.leap.Controller;
import com.leapmotion.leap.Frame;
import com.leapmotion.leap.Gesture;
import com.leapmotion.leap.Hand;
import com.leapmotion.leap.HandList;
import com.leapmotion.leap.Vector;
import com.leapmotion.leap.processing.LeapMotion;
import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
LeapMotion leapMotion;
Minim minim;
AudioOutput out;
// the Oscil we use for modulating frequency.
Oscil fm;
void setup()
{
size(9_50, 9_50);
background(20);
leapMotion = new LeapMotion(this);
minim = new Minim(this);
// get a stereo line out with a sample buffer of 512 samples
out = minim.getLineOut(Minim.MONO, 512);
// make the Oscil we will hear.
// arguments are frequency, amplitude, and waveform
Oscil wave = new Oscil( 200, 0.8, Waves.TRIANGLE );
// make the Oscil we will use to modulate the frequency of wave.
// the frequency of this Oscil will determine how quickly the
// frequency of wave changes and the amplitude determines how much.
// since we are using the output of fm directly to set the frequency
// of wave, you can think of the amplitude as being expressed in Hz.
fm = new Oscil( 10, 2, Waves.SINE );
// set the offset of fm so that it generates values centered around 200 Hz
fm.offset.setLastValue( 200 );
// patch it to the frequency of wave so it controls it
fm.patch( wave.frequency );
// and patch wave to the output
wave.patch( out );
}
void draw()
{
fill(20);
rect(0, 0, width, height);
// draw using a white stroke
stroke( 255 );
// draw the waveforms
for( int i = 0; i < out.bufferSize() – 1; i++ )
{
// find the x position of each buffer value
float x1 = map( i, 0, out.bufferSize(), 0, width );
float x2 = map( i+1, 0, out.bufferSize(), 0, width );
// draw a line from one buffer position to the next for both channels
line( x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
line( x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
}
}
// here we provide a way to mute out
void keyPressed()
{
if ( key == 'm' )
{
if ( out.isMuted() )
{
out.unmute();
}
else
{
out.mute();
}
}
}
//called reflexively by the leap controller
void onInit(final Controller controller)
{
controller.enableGesture(Gesture.Type.TYPE_CIRCLE);
controller.enableGesture(Gesture.Type.TYPE\_KEY\_TAP);
controller.enableGesture(Gesture.Type.TYPE\_SCREEN\_TAP);
controller.enableGesture(Gesture.Type.TYPE_SWIPE);
// enable background policy
controller.setPolicyFlags(Controller.PolicyFlag.POLICY\_BACKGROUND\_FRAMES);
}
// we can change the parameters of the frequency modulation Oscil
// in real-time using the hand.
void onFrame(final Controller controller)
{
Frame frame = controller.frame();
HandList hands = frame.hands();
if (hands.count() > 0){
Hand hand = hands.get(0);
Vector pos = hand.palmPosition();
println(“x “+pos.getX()+” y “+pos.getY());
float x = pos.getX();
float y = pos.getY();
float modulateAmount = map( y, 0, height, 220, 1 );
float modulateFrequency = map( x, 0, width, 0.1, 100 );
fm.frequency.setLastValue( modulateFrequency );
fm.amplitude.setLastValue( modulateAmount );
}
}
//remember to stop the sound before closing
void stop()
{
out.close();
minim.stop();
super.stop();
}