Touching the Voice

posted in Interactive Projects

Touching the Voice

a vocal instrument using the LeapMotion

 

Created with Processing (LeapMotion Library for Processing, Minim and OSC5 to Max/MSP )

 

Touching the Voice is an instrument for the voice. It makes visible expressions of the human instrument with intimate hand gestures. I use the LEAP as a voice control tool for live performance rather than the Kinect because of the ability for quiet movements to articulate the intimate voice (the microphone voice). I would like the gestures that a vocal performance has naturally those small articulations of the hands that are used in vocal performance to help the singer convey emotion and for the audience to visualize what is happening inside the singer’s body control the voice.

You may have seen this project on QuiteBeyond.de a private tech blog about the LEAP Motion by Maximilian Werkhausen

 

 

Click Below to see the Source Code for the Project:

Leap Motion library for Processing.

Copyright (c) 2012-2013 held jointly by the individual authors.

 

import ddf.minim.*;

import ddf.minim.AudioSample;

import ddf.minim.AudioPlayer;

AudioInput in;

Minim minim;

AudioSample circuit;

AudioSample la1;

AudioSample la2;

AudioSample metro;

AudioSample tone;

float val;

int val2;

int bufferSize = 4;

int fftSize = floor(bufferSize*.9)+1;

import com.leapmotion.leap.Controller;

import com.leapmotion.leap.Finger;

import com.leapmotion.leap.Frame;

import com.leapmotion.leap.Hand;

import com.leapmotion.leap.processing.LeapMotion;

import com.leapmotion.leap.Gesture;

import oscP5.*;

import netP5.*;

int fingers = 0;

LeapMotion leapMotion;

OscP5 oscP5;

NetAddress addressForMax;

float[] leapValues = new float[3];

void setup()

{

size(1000,650);

background(20);

frameRate(60);

//textAlign(CENTER);

minim = new Minim(this);

//minim sounds

circuit = minim.loadSample("circuit.mp3", 512);

la1 = minim.loadSample("la1.mp3", 512);

la2 = minim.loadSample("la2.mp3", 512);

metro = minim.loadSample("metro.mp3", 512);

tone = minim.loadSample("tone.mp3", 512);

//end of sounds

leapMotion = new LeapMotion(this);

oscP5 = new OscP5(this,12346);

addressForMax = new NetAddress("localhost",12345);

// use the getLineIn method of the Minim object to get an AudioInput

in = minim.getLineIn();

// uncomment this line to *hear* what is being monitored, in addition to seeing it

in.enableMonitoring();}

void draw()

{background(0);

//fill(20);

//rect(0, 0, width, height);

fill(255);

textSize(2*height/5.0);

text(String.valueOf(fingers), width/6, 11*height/11.0);

for(int i = 0; i < in.bufferSize() - 1; i++)

{ stroke(0);

strokeWeight(1);

line( i*8, 900 + in.left.get(i)*500, i+height/2, 1 + in.left.get(i+1)*7);

stroke(255,43);

strokeWeight(7);

line( i, 1 + in.right.get(i)*900, height, 550 + in.right.get(i+1)*10 );

//ellipse(5 + in.left.get(i)*150, height-in.right.get(i)*150, 500, 500);

}

OscMessage myMessage = new OscMessage("/finger");

myMessage.add(fingers);

oscP5.send(myMessage,addressForMax);

}

//more minimminimminim

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);}

//miniminiminiminimin

void onFrame(final Controller controller)

{

Frame frame = controller.frame();

if (frame.hands().isEmpty())

{

fingers = 0;

}

else

{

int c = 0;

for (Hand hand : frame.hands())

{

c = Math.max(c, hand.fingers().count());

}

fingers = c;

}

for (Gesture gesture : frame.gestures())

{

if ("TYPE_CIRCLE".equals(gesture.type().toString()) && "STATE_START".equals(gesture.state().toString())) {

circuit.trigger();

}

else if ("TYPE_KEY_TAP".equals(gesture.type().toString()) && "STATE_STOP".equals(gesture.state().toString())) {

la1.trigger();

}

else if ("TYPE_SWIPE".equals(gesture.type().toString()) && "STATE_START".equals(gesture.state().toString())) {

la2.trigger();

}

else if ("TYPE_SCREEN_TAP".equals(gesture.type().toString()) && "STATE_STOP".equals(gesture.state().toString())) {

metro.trigger();

}

else if ("TYPE_SCREEN_TAP".equals(gesture.type().toString()) && "STATE_STOP".equals(gesture.state().toString())) {

tone.trigger();}

println("gesture " + gesture + " id " + gesture.id() + " type " + gesture.type() + " state " + gesture.state() + " duration " + gesture.duration() + " durationSeconds " + gesture.durationSeconds());

}

}

void stop()

{

circuit.close();

la1.close();

la2.close();

metro.close();

tone.stop();

super.stop();

}

//lessminiminiminim

//thank you Justin Lang for helping me with the OSC for Processing Library

 

Max/MSP Code:

I’ve never used max before and this was a very fun and challenging way to learn a new program in 2 weeks but I am very happy with the way it turned out.

leapvocals2_amelia