//------------------------------------------------ // name: polyfony.ck // desc: polyfonic mandolin model // // by: Ananya Misra and Ge Wang // send all complaints to prc@cs.princeton.edu //-------------------------------------------- // device to open (see: chuck --probe) 0 => int device; // get from command line if( me.args() ) me.arg(0) => Std.atoi => device; MidiIn min; MidiMsg msg; // try to open MIDI port (see chuck --probe for available devices) if( !min.open( device ) ) me.exit(); // print out device that was opened <<< "MIDI device:", min.num(), " -> ", min.name() >>>; // make our own event class NoteEvent extends Event { int note; int velocity; } // the event NoteEvent on; // array of ugen's handling each note Event @ us[128]; // the base patch Gain g => JCRev r => dac; .1 => g.gain; .2 => r.mix; // handler for a single voice fun void handler() { // don't connect to dac until we need it Mandolin m; Event off; int note; while( true ) { on => now; on.note => note; // dynamically repatch m => g; Std.mtof( note ) => m.freq; Std.rand2f( .6, .8 ) => m.pluckPos; on.velocity / 128.0 => m.pluck; off @=> us[note]; off => now; null @=> us[note]; m =< g; } } // spork handlers, one for each voice for( 0 => int i; i < 20; i++ ) spork ~ handler(); // infinite time-loop while( true ) { // wait on midi event min => now; // get the midimsg while( min.recv( msg ) ) { // catch only noteon if( msg.data1 != 144 ) continue; // check velocity if( msg.data3 > 0 ) { // store midi note number msg.data2 => on.note; // store velocity msg.data3 => on.velocity; // signal the event on.signal(); // yield without advancing time to allow shred to run me.yield(); } else { if( us[msg.data2] != null ) us[msg.data2].signal(); } } }