// Jam On It Receiver // MIDI over OSC low latency jamming system // by Les Hall // // CHANGE THiS STUFF if you wish // // global varialbes second/4.0 => dur interval; // note time quantization // instantiate instruments Gain volume[16]; // instrument 0: the flute FLUTE flute; flute.output => volume[0] => dac; // instrument 1: loopy drone Step step => LPF lpf1 => LPF lpf2 => LPF lpf3 => volume[1] => dac; lpf1 => DelayA del1 => lpf1; lpf2 => DelayA del2 => lpf2; lpf3 => DelayA del3 => lpf3; 0.5 => lpf1.gain; 0.5 => lpf2.gain; 0.5 => lpf3.gain; 200.0 => lpf1.freq; 100.0 => lpf2.freq; 300.0 => lpf3.freq; 1::second => del1.max => del2.max => del3.max; 500::ms => del1.delay => del2.delay => del3.delay; 0.0 => volume[0].gain; // flute volume 1.0 => volume[1].gain; // loopy drone volume // STK Flute class FLUTE { float fluteFreq; // frequency queue, remember last one float fluteNoteOn; // noteOn queue, remember last one // patch Flute flute => PoleZero f => JCRev r => Gain output; .25 => r.gain; .05 => r.mix; .99 => f.blockZero; fun void randomize() { // clear flute.clear( 1.0 ); // set Std.rand2f( 0.8, 1 ) => flute.jetDelay; Std.rand2f( 0.8, 1 ) => flute.jetReflection; Std.rand2f( 0.8, 1 ) => flute.endReflection; Std.rand2f( 0, 1 ) => flute.noiseGain; Std.rand2f( 0, 12 ) => flute.vibratoFreq; Std.rand2f( 0, 1 ) => flute.vibratoGain; Std.rand2f( 0.5, 1 ) => flute.pressure; // print <<< "---", "" >>>; <<< "jetDelay:", flute.jetDelay() >>>; <<< "jetReflection:", flute.jetReflection() >>>; <<< "endReflection:", flute.endReflection() >>>; <<< "noiseGain:", flute.noiseGain() >>>; <<< "vibratoFreq:", flute.vibratoFreq() >>>; <<< "vibratoGain:", flute.vibratoGain() >>>; <<< "breath pressure:", flute.pressure() >>>; } randomize(); // basic play function (add more arguments as needed) fun void play( float frequency, float velocity ) { // start the note frequency => fluteFreq; velocity => fluteNoteOn; } play(Math.mtof(65+12), 0.8); // time quantizer fun void timeQuantizer(dur deltaTime) { while(true) { fluteFreq => flute.freq; fluteNoteOn => flute.noteOn; deltaTime => now; } } spork ~ timeQuantizer(interval); } // create our OSC receiver OscRecv recv; // use port 6449 8001 => recv.port; // start listening (launch thread) recv.listen(); // create an address in the receiver, store in new variable recv.event( "/JamOnIt/MIDI/,i,i,i" ) @=> OscEvent oe; // infinite event loop while ( true ) { // wait for event to arrive oe => now; // grab the next message from the queue. while ( oe.nextMsg() != 0 ) { // getInt fetches the expected integers oe.getInt() => int x; oe.getInt() => int y; oe.getInt() => int z; // decode first byte (x >> 4) & 0x000f => int code; x & 0x000f => int channel; // decode message and make some noise! if (code == 0x000B) // MIDI CC { if (channel == 0) // flute { // accept any parameter (y) // play a note of flute indicated by third byte (z) flute.play(Math.mtof(z), 0.8); } else if (channel == 1) // loopy drone { // accept any parameter (y) // play a note of flute indicated by third byte (z) Math.mtof(z) => float freq; freq => lpf1.freq; freq => lpf2.freq; freq => lpf3.freq; (Math.mtof(z) / 10.0)::ms => dur del; del => del1.delay; 2.0 * del => del2.delay; 4.0 * del => del3.delay; Math.mtof(z) / 500.0 => step.next; } } else if (code == 0x0009) // MIDI note on { if (channel == 0) // flute { } else if (channel == 1) // loopy drone { } } } }