Description:
I created a toy (prototype) hand which will play music. The volume of the music depends on how hard you squeeze it. If you squeeze harder, the music will play louder. If you squeeze softly, it will play softer. And, if you don't squeeze, the volume is 0.
Components used:
-
Force sensing resistor
-
10k ohm resistor
-
Speakers
-
Plastic bag
-
Mittens
Code:
Processing
/* Jennifer Wang
* HW 5 attempt
* October 4, 2011
*
* Music groover
*
* Play back music, where volume is controlled by pressing on a force sensor
* Pressing harder increases volume, not pressing has 0 volume
*
* Also creates a visualization of the beats in the music (from Damien at
*
* Visualization color dependent on pressure on force sensor.
*
*/
import ddf.minim.*;
import ddf.minim.analysis.*;
import processing.serial.*;
Minim minim;
AudioPlayer song;
AudioInput input;
AudioOutput out;
BeatDetect beat;
float gain = -60; // gain between -60 and 5
float eRadius;
int R;
int G;
int B;
Serial port;
int sensorVal; // value from force sensor
// ** calibrate the low and high values of the sensor to get full range **
int sensorLow = 100;
int sensorHigh = 490;
void setup() {
println(Serial.list()); // List COM-ports
//select second com-port from the list
port = new Serial(this, Serial.list()[0], 9600);
size(100, 100);
minim = new Minim(this);
song = minim.loadFile("02 Oxford Comma.mp3");
input = minim.getLineIn();
out = minim.getLineOut(); // returns a stereo line out with buffer size of
// 1024 samples that plays 16 bit audio at 44100 Hz sample rate
song.loop();
beat = new BeatDetect(); // SOUND_ENERGY mode
//beat = new BeatDetect(song.bufferSize(), song.sampleRate()); // FREQUENCY_ENERGY mode
song.setGain(gain);
ellipseMode(CENTER_RADIUS);
eRadius = 20;
}
void draw() {
song.setGain(gain);
beat.detect(song.mix);
background(0);
setColor();
float a = map(eRadius, 20, 80, 60, 255);
fill(R, G, B, a);
if ( beat.isOnset() ) {
eRadius = 80;
}
ellipse(width/2, height/2, eRadius, eRadius);
eRadius *= 0.95;
if ( eRadius < 20 ) eRadius = 20;
}
void stop() {
// the AudioPlayer you got from Minim.loadFile()
song.close();
// the AudioInput you got from Minim.getLineIn()
input.close();
minim.stop();
// this calls the stop method that
// you are overriding by defining your own
// it must be called so that your application
// can do all the cleanup it would normally do
super.stop();
}
// set the color of the visualization in a rainbow mode based on the value from the force sensor
// calibrated for useful range of the sensor
void setColor() {
// from blue to green
if (sensorVal >= sensorLow & sensorVal < int((sensorHigh-sensorLow)/2)+sensorLow) {
R = 0;
G = int(255.0/((sensorHigh-sensorLow)/2)*(sensorVal-sensorLow));
B = int(255 - 255.0/((sensorHigh-sensorLow)/2)*(sensorVal-sensorLow));
}
// green
else if (sensorVal == int((sensorHigh-sensorLow)/2)+sensorLow) {
R = 0;
G = 0;
B = 255;
}
// from green to red
else if (sensorVal > int((sensorHigh-sensorLow)/2+sensorLow) & sensorVal < int(2*(sensorHigh-sensorLow)/2)+sensorLow) {
R = int(255.0/((sensorHigh-sensorLow)/2.0)*((sensorVal-sensorLow) - ((sensorHigh-sensorLow)/2.0)));
G = int(255 - 255.0/((sensorHigh-sensorLow)/2.0)*((sensorVal-sensorLow) - ((sensorHigh-sensorLow)/2.0)));
B = 0;
}
// red
else if (sensorVal == int(2*(sensorHigh-sensorLow)/2)+sensorLow) {
R = 255;
G = 0;
B = 0;
}
println(sensorVal);
println(R);
println(G);
println(B);
println();
}
void serialEvent(Serial p) {
// get the ASCII string:
String inString = port.readStringUntil('\n');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
// convert to integer
sensorVal = int(inString);
// calibrating values to fill full range of screen
// y position calibrated from sensor
if (sensorVal > sensorHigh) { // above max of sensor value range
sensorVal = sensorHigh;
}
if (sensorVal < sensorLow) { // below min of sensor value range
sensorVal = sensorLow;
}
gain = int(65*(sensorVal - sensorLow)/(sensorHigh - sensorLow) - 60); // calibrate to gain between -60 and 5
}
}