I'm a total Processing newbie (and programming/math newbie, for that matter). But I made this little music player which I thought was cool. Definitely not that original.
There probably is a lot of stupid code in here, so please let me know if you spot something that doesn't make sense. It works though!
(By the way, the circles don't snap to the grid, it's just for guidance).
http://popgroupe.com/alex/processing/music/index.html
Code:
/**
* music machine by alex miller
*
* click to place a circle on the screen. when the line sweeps over the
* circle, it will play a frequency depending on the y-position of the
* circle.
*
* requires the minim library for sound.
*/
import ddf.minim.*;
import ddf.minim.signals.*;
import java.util.*;
float linepos;
float speed = 1; // speed at which line moves
int range = 20; // the range, in terms of musical notes, that will be playable
float start = 220.0; // the starting frequency (lowest playable)
ArrayList circles = new ArrayList(); // holds all circles for looping
float waves[] = new float[range]; // holds frequencies for musical scale
AudioOutput out; // output, for minim
void setup() {
frameRate(60);
size(600, 500);
background(0);
linepos = 0;
smooth();
for (int i=0; i<range; i++) { // fill waves[] with frequencies
// frequency = starting * 2 ^ N/12
// N is the number of notes above the starting frequency
float m = pow(2, float(i)/12.0);
waves[i] = start*m;
}
Minim.start(this);
out = Minim.getLineOut(Minim.STEREO, 512);
}
void draw() {
background(0);
for (int i=0; i<width/5; i++) { // vertical lines, for timing guidance
float loc = i*width/5;
stroke(100);
line(loc, 0, loc, height);
}
// horizontal lines, for note guidance
for (int i=0; i<waves.length; i++) {
// this is an overly complex way to get the correct line spacings.
// however, it mirrors the way frequency is inputed along the y axis.
stroke(100);
float yh = waves[i];
yh = log(yh/start)/log(2)*12;
yh *= height/range;
line(0, yh, width, yh);
}
stroke(255);
line(linepos, 0, linepos, height); // the sweeper
if (linepos>width-5) { // if it reaches the end, start a little before the 1st line
linepos=width/5-5;;
}
linepos+=speed;
// loop through all the circles, to draw them and check for playback
for (int i=0; i<circles.size(); i++) {
circle c = (circle) circles.get(i);
c.check();
c.show();
}
}
// if user clicks mouse, put down a new circle, add it to circle array
void mousePressed() {
circles.add(new circle(mouseX, mouseY));
}
class circle {
float x, y;
color c;
float timer = 0;
SquareWave square; // minim square wave
circle(float ix, float iy) {
x = ix;
y = iy;
// map the y placing of the circle to the correct frequency.
// musical scales are exponential, while our y axis is linear.
// frequency = starting * 2 ^ N/12
float e = (y*range)/(12.0*height);
float f = start*pow(2.0, e);
square = new SquareWave(f, 0, 44100);
out.addSignal(square); // now the wave is playing
c = 100;
}
void show() {
fill(c);
noStroke();
ellipse(x, y, 10, 10);
}
void check() {
if (linepos==x) {
// if the line hits the circle, start timer, turn volume up
timer = 2;
square.setAmp(.5);
}
if (timer<0) {
// when timer finishes, make volume 0
c = 100;
square.setAmp(0);
} else {
// count down timer
timer-=.1;
c = 255;
}
}
}