FRSynth - Emilio Marcelino
Motivation
My goal to start this project was to include a variety of personal interests into one piece, particularly color/sound/motion.
Interaction
The user interacts with my piece by sitting/standing in front of the webcam the program tracks the facial movement controlling the mouse. Depending on the location of the face on the screen the frequency of the sound wave is altered. Making a facial recognition synthesizer.
Function
The project will allow the users to test their creativity both visually and auditorily in a live/performance style
Visualization
Diagram
Final Code
import hypermedia.video.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.signals.*;
AudioPlayer player; Minim minim; AudioInput in; AudioOutput out; SawWave sine; FFT fft;
float[] xpos = new float[50]; float[] ypos = new float[50];
OpenCV opencv;
// contrast/brightness values int contrast_value = 0; int brightness_value = 0;
float loudestFreqAmp = 0; float loudestFreq = 0; int timerCounter = 0; float posX = 0; float posY = 0;
void setup()
{
size(640, 480);
//noCursor(); minim = new Minim(this); out = minim.getLineOut(Minim.STEREO); // create a sine wave Oscillator, set to 440 Hz, at 0.5 amplitude, sample rate from line out sine = new SawWave(440, 0.1, out.sampleRate()); // set the portamento speed on the oscillator to 200 milliseconds sine.portamento(200); // add the oscillator to the line out out.addSignal(sine); minim.debugOn();
player = minim.loadFile("beat.mp3", 2048);
for (int i = 0; i < xpos.length; i++) { xpos[i] = 0; ypos[i] = 0; }
// get a line in from Minim, default bit depth is 16 in = minim.getLineIn(Minim.STEREO, 1024);
opencv = new OpenCV( this ); opencv.capture( width, height ); // open video stream opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT ); // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"
}
void draw() {
player.play(); // grab a new frame // and convert to gray opencv.read(); opencv.convert( GRAY ); opencv.contrast( contrast_value ); opencv.brightness( brightness_value ); opencv.flip( OpenCV.FLIP_HORIZONTAL );
// proceed detection java.awt.Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );
for( int i=0; i<faces.length; i++ ) { posX = faces[i].x; posY = faces[i].y; if ((posX != 0) && (posY != 0)) { drawCircles(posX, posY); } }
// with portamento on the frequency will change smoothly float freq = map(posY, 0, height, 1500, 60); sine.setFreq(freq*.5); // pan always changes smoothly to avoid crackles getting into the signal // note that we could call setPan on out, instead of on sine // this would sound the same, but the waveforms in out would not reflect the panning float pan = map(posX, 0, width, -1, 1); sine.setPan(pan);
}
// Circle splatter machine
void drawCircles(float posX, float posY)
{
background(000);
for (int i = 0; i <xpos.length - 1; i++) { xpos[i] = xpos[i + 1]; ypos[i] = ypos[i + 1]; }
xpos [xpos.length - 1] = posX; ypos [ypos.length - 1] = posY;
for (int i = 0; i < xpos.length; i++) { noStroke(); fill(random(255),random(255),random(255) - i * 5); ellipse(xpos[i],ypos[i],i,i); }
}
void stop() {
// always close Minim audio classes when you are done with them in.close(); out.close(); minim.stop();
super.stop();
}