class partSynth { 16 => int numPartials; float partials[16]; SinOsc sArr[16]; Envelope master => dac; fun void setPartials (float p[]) { for (0 => int i; i < numPartials; i++) { p[i] => partials[i]; } } fun void ringShiftR () { partials[15] => float tmp; for (numPartials - 1 => int i; i > 0; i--) { partials[i-1] => partials[i]; } tmp => partials[0]; } fun void blip (int freq, dur len, dur decay) { // set frequencies, gains, and connect to Envelope for (0 => int partNum; partNum < numPartials; partNum++) { freq * (partNum + 1) => sArr[partNum].freq; partials[partNum] => sArr[partNum].gain; sArr[partNum] => master; } 0.05::decay => master.duration; 0.0 => master.value; 0.2 => master.target; 0.05::decay => now; 0.95::decay => master.duration; master.keyOff(); 0.95::decay => now; } } SinOsc s => Envelope e => dac; 160 => int tempo; 1::minute / tempo => dur beat; 0.25::beat => dur tick; 4::beat => dur bar; now + 8::bar => time end; partSynth ps; partSynth ps2; [0.8, 0.1, 0.2, 0.5, 0.3, 0.1, 0.5, 0.05, 0.3, 0.6, 0.2, 0.1, 0.9, 0.1, 0.1, 0.1] @=> float pArr[]; pArr => ps.setPartials; pArr => ps2.setPartials; ps2.ringShiftR(); ps2.ringShiftR(); while (now < end) { for (0 => int i; i < 2 && now < end; i++) { dur thisBeat; if (i == 0) { (1.8/6)::beat => thisBeat; } else { (1.2/6)::beat => thisBeat; } ps.ringShiftR(); ps2.ringShiftR(); spork ~ ps.blip(55, thisBeat, Std.rand2f(0.22, 1.0)::thisBeat); spork ~ ps2.blip(110, thisBeat, Std.rand2f(0.001, 0.1)::thisBeat); thisBeat => now; } }