/**
* Click, drag and release the waveforms to play with the synth.
*
* Frequency is mapped to y-position and pan is mapped to x-position.
*/
import processing.opengl.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import traer.physics.*;
ParticleSystem phys;
Particle[] parts;
Oscillator[] waves;
SignalListener[] sigs;
AudioOutput out;
// fourths, more or less
float freqs[] = { 220, 587, 830, 1046, 1396, 1839 };
//float freqs[] = { 220, 220, 220, 220, 220 };
int VOICES = freqs.length;
int xstep;
void setup()
{
size(640, 480, OPENGL);
smooth();
ellipseMode(CENTER_RADIUS);
phys = new ParticleSystem(0, 0.01);
xstep = width / VOICES;
int x = xstep / 2;
int y = height / 2;
parts = new Particle[VOICES];
for(int i = 0; i < VOICES; i++)
{
Particle f = phys.makeParticle(1, x, y, 0);
f.makeFixed();
Particle p = phys.makeParticle(1, x, y, 0);
phys.makeSpring(f, p, 1, 0.1, 0);
parts[i] = p;
x += xstep;
}
Minim.start(this);
out = Minim.getLineOut(Minim.STEREO, 2048);
sigs = new SignalListener[VOICES];
waves = new Oscillator[VOICES];
for(int i = 0; i < VOICES; i++)
{
sigs[i] = new SignalListener(out.bufferSize());
float amp = map(i, 0, VOICES, 0.2, 0.2);
float pan = map(i, 0, VOICES, -1, 1);
waves[i] = new SineWave(freqs[i], amp, 44100);
waves[i].portamento(1);
waves[i].setPan(pan);
waves[i].setAudioListener(sigs[i]);
out.addSignal(waves[i]);
}
}
void draw()
{
phys.tick(0.05);
if ( grabPart >= 0 )
{
parts[grabPart].moveTo(mouseX, mouseY, 0);
}
background(0, 0, 60);
int points = 512;
float step = TWO_PI / points;
for(int i = 0; i < VOICES; i++)
{
Particle p = parts[i];
stroke(230, 160, 0);
noFill();
//fill(230, 160, 0);
//ellipse(p.position().x(), p.position().y(), 20, 20);
SignalListener sig = sigs[i];
//println("Drawing waveform from " + sig.toString());
beginShape();
for(int v = 0; v < points; v++)
{
float dx = sin(step * v);
float dy = cos(step * v);
dx *= 20 + sig.get(v) * 50;
dy *= 20 + sig.get(v) * 50;
vertex(p.position().x() + dx, p.position().y() + dy);
}
endShape();
float yoff = (height / 2) - p.position().y();
waves[i].setFreq(freqs[i] + yoff*0.2);
float pan = map(p.position().x(), 0, width, -1, 1);
waves[i].setPan(pan);
}
}
int grabPart = -1;
void mousePressed()
{
for(int i = 0; i < VOICES; i++)
{
Particle p = parts[i];
if ( dist(mouseX, mouseY, p.position().x(), p.position().y()) < 20 )
{
grabPart = i;
break;
}
}
}
void mouseReleased()
{
grabPart = -1;
}
void stop()
{
out.close();
Minim.stop();
super.stop();
}