Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
58 lines (50 sloc) 1.65 KB
// Author: Paul Reiners
// Implementation of the Shepard tone scale.
// See [illustration](GEBShepardToneScale.jpeg) from _Gödel, Escher, Bach_, by Douglas R. Hofstadter.
12 => int HALF_STEPS_IN_OCTAVE;
4 => int VOICE_COUNT;
SinOsc chord[VOICE_COUNT];
float gain[VOICE_COUNT];
36 => int c1;
for (0 => int i; i < VOICE_COUNT; i++) {
chord[i] => dac;
}
float gains[HALF_STEPS_IN_OCTAVE];
0.5 => float MAX_GAIN;
for (0 => int i; i < HALF_STEPS_IN_OCTAVE; i++) {
((i + 1.0) / HALF_STEPS_IN_OCTAVE) => float fraction;
Math.sin(fraction * Math.PI / 2.0) * MAX_GAIN => gains[i];
<<< "gain:", i, gains[i] >>>;
}
while (true) {
for (0 => int i; i < HALF_STEPS_IN_OCTAVE; i++) {
for (0 => int j; j < VOICE_COUNT; j++) {
0 => chord[j].gain;
}
0.25 * second => now;
<<< "\nnote:", i >>>;
for (0 => int j; j < VOICE_COUNT; j++) {
<<< "\tvoice", j >>>;
c1 + i + HALF_STEPS_IN_OCTAVE * j => int pitch;
<<< "\t\tpitch:", pitch >>>;
Std.mtof(pitch) => float freq;
<<< "\t\tfreq:", freq >>>;
freq => chord[j].freq;
0 => int gainIndex;
0.0 => float gain;
if (j < 2) {
i => gainIndex;
} else {
HALF_STEPS_IN_OCTAVE - 1 - i => gainIndex;
}
gains[gainIndex] => gain;
if (j == 0 || j == 3) {
gain / 2.0 => gain;
}
<<< "\t\tgainIndex:", gainIndex >>>;
gain => chord[j].gain;
<<< "\t\tgain:", gain >>>;
}
2 * second => now;
}
}