Tom Says: Safe code is boring code! Why??
Previous page:
Daily Crap 2008-11-15
Next page:
Archaeopteryx Tricks
I built a cute scanning synthesizer in Processing. It's a grid of springs, so when you touch it, it ripples like a pond. I play the positions of springs in each row as if it were a sound signal (scanning across). Then added some ways to excite them.
It was inspired by a lecture given by Bill Verplank this semester (fall 2008) in which he presented videos of various music synthesizers, one of which was a string model which could be vibrated using controllers like a force-feedback pen, a chain of rotational potentiometers, a boiling liquid model, and so on.
Press the number keys to excite harmonics. Press keys on the home row to add tiny spikes. Press 'm' to toggle using microphone input to excite the strings.
Moving the mouse upward tightens the strings and, thanks to leaky Euler integration, makes everything blow up (and look cool). Holding a mouse button silences the strings. Here's why you need (and want) it:
You need Processing, and Minim for sound. The "latest" springy code is on GitHub. Here is a tour of the basic ideas (doesn't match the code exactly).
The data structures are simple. While it's a homogenous grid of springs, I think of each row as a separate string which happens to be connected to another string on one or both sides. I track position and vertical velocity for each point in each spring, and whether or not that point is fixed in space. If no points were fixed, strings wouldn't be grounded to any particular rest state, and over time things would drift out of control.
final int STRINGS = 20; final int POINTS = 100; double[][] pos = new double[STRINGS][POINTS]; double[][] vel = new double[STRINGS][POINTS]; boolean[][] fixed = new boolean[STRINGS][POINTS];
There are different variables for the spring constants vertically (between strings) and horizontally (within a string). Tweak these to affect propagation between strings for cool effects, like when each string is played at a harmonic frequency.
// k1: spring constant between points on the same string // k2: spring constant between points on adjacent strings double k1 = 0.01, k2 = 0.01; double damping = 0.03;
Here is the basic audio generation class. Give it the point position array of a particular string and tell it how fast to play it, then connect it to a speaker.
class SpringSound implements AudioSignal
{
private double[] points;
private double point;
private double rate;
private double gain;
public SpringSound(double[] points, double gain, double rate) {
this.points = points;
this.gain = gain;
this.rate = rate;
point = 0;
}
void generate(float[] mono) {
generate(mono, mono);
}
void generate(float[] left, float[] right) {
for ( int i = 0; i < left.length; i += 1 ) {
float samp = (float) (points[(int) point] / 100.0 * gain);
left[i] = right[i] = samp;
point = (point + rate) % points.length;
}
}
}
More things have been added to the version in GitHub, like exciting strings with the microphone, and a snazzier 3D interface, kind of like this one:
Posted Nov 14, 2008, in the morning. Updated updated Nov 18, 2008, in the afternoon: Added links to prior art.