// *********************************************************** // "Grip Maestro" Granular Mapping Based on Code by Kyle Sprat // By, Michael Berger ~ May 2008 // REVISED in prep for the MarkIIa, February 9-13, 2009 // MUSIC 250B ~ HCI class // in Computer-Generated Music // *********************************************************** //CONSTANTS 2 => int Spkrs; //must be 2 or greater 4 => int Snds; //must be 2 or greater //Slew every... 0.05 => float SLOO; 1::ms => dur SlewRez; //BUFFER and Path Beginnings SndBuf Buffy; Gain Master[Snds]; Pan2 p[Snds]; JCRev reverb; LPF lpf; 3000 => lpf.freq; //patchings for (0 => int i; i < Snds; i++) { Buffy => Master[i]; p[i] => lpf => reverb => dac;//reverb optional (see also line 190ish) //spatializes the number of given speakers over STEREO (i * (2. / (Spkrs - 1)) - 1.) => p[i].pan; } // Make sure preferences are set to correct file path!!! if( me.args() ) me.arg(0) => Buffy.read; "allsound.wav" => Buffy.read; //"weeee.wav" => Buffy.read; 0.0 => reverb.mix; //GLOBAL VARIABLES 8 => int inputs; // inputs float HE[inputs]; //gain 0.0 => float Gaine => float target_gaine => float temp_gaine; float delay[Snds]; float target_delay[Snds]; float temp_delay[Snds]; float snip[Snds]; float target_snip[Snds]; float temp_snip[Snds]; dur DelayTime[Snds]; dur SnipLength[Snds]; int Position[Snds]; for (0 => int i; i < Snds; i++) { 0.1 => delay[i] => target_delay[i] => temp_delay[i]; delay[i] + 0.04 => snip[i] => target_snip[i] => temp_snip[i]; delay[i]::second => DelayTime[i]; snip[i]::second => SnipLength[i]; } // create our OSC receiver OscRecv GripMaestro; // use port 6449 (or whatever) 6449 => GripMaestro.port; // start listening (launch thread) GripMaestro.listen(); //create an address in the receiver, store in new variable GripMaestro.event ("/GM, i f") @=> OscEvent @ GM; //SPORKINGS spork ~ GetGMnumbers(); spork ~ SlewifyThings(SLOO, SlewRez); //FUNCTIONS //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fun void Snippet (dur delaytime, dur sniplength, float gain, int which, int pos) //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { Envelope env; Delay d; Envelope env2; Master[which] => env => d => env2; env => env2 => p[which]; d => d; gain => env.target => env2.target => Master[which].gain; delaytime => d.max => d.delay; pos => Buffy.pos; env.time((sniplength/2)/second); env2.time((sniplength/2)/second); env.keyOn(1); delaytime => now; env2.keyOn(1); delaytime => now; env.keyOff(1); sniplength - delaytime => now; //sniplength cannot be greater than delaytime env2.keyOff(1); 0.01::second => now; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fun void GetGMnumbers() //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { while (true) { GM => now; GM.nextMsg(); GM.getInt() => int i; GM.getFloat() => HE[i]; } } // interpolation >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> fun void SlewifyThings (float slew, dur resolution) //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { //ADD PANNING HERE while (true) { (target_gaine - temp_gaine) * slew + temp_gaine => temp_gaine => Gaine; for (0 => int i; i < Snds; i++) { Gaine => Master[i].gain; (target_delay[i] - temp_delay[i]) * slew + temp_delay[i] => temp_delay[i]; Std.fabs(temp_delay[i])::second => DelayTime[i]; (target_snip[i] - temp_snip[i]) * slew + temp_snip[i] => temp_snip[i]; Std.fabs(temp_snip[i])::second => SnipLength[i]; } resolution => now; //time resolution of changes } } //MAIN BLOCK //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Buffy.play; //Buffy.samples() => Buffy.pos;//will be redundant with "1 => Buffy.loop;" below <<< " ", "" >>>; <<< "GRIP MAESTRO - GRANULAR APPLICATION ~ MARKII", "" >>>; <<< "by Michael Berger -- inspired by Kyle Sprat's 'I Miss My Uncle Charles'", "" >>>; <<< "~", "" >>>; <<< "Use the GRIP MAESTRO device to control the Sounds.", "" >>>; <<< "Finger 1 controls the snippet size, 2: the delay between snippets, 3: the buffer position,", "" >>>; <<< "and 4: the amount of randomness around the preceding three parameters.","">>>; <<< "The palm pad controls the volume, and playback-rate.", "" >>>; <<< " ", "" >>>; <<< "Press CTRL+C to exit.", "" >>>; 0 => Buffy.pos; 1 => Buffy.loop; for (0 => int i; i < Snds; i++) 1. => Master[i].gain; //MAIN LOOP while (true) { for (0 => int i; i < Snds; i++) { //Gaine => Master[i].gain; spork ~ Snippet (DelayTime[i], SnipLength[i], Gaine, i, Position[i]); SnipLength[i] / (Snds) => now; //0.1::second => now; //print out? //<<< HE[0], HE[1], HE[2], HE[3], HE[4], HE[5], HE[6], HE[7] >>>; //CONTROL //(HE[6] * 0.1) + 0.55 => Gaine; //target_gaine;//use Buffy.gain for the mastergain //for (0 => int i; i < Snds; i++) //{ (Std.fabs(HE[0]) + 0.05) => target_delay[i];//DelayTime[i];//needs ::second target_delay[i] + Std.fabs(HE[3]) => target_snip[i];//SnipLength[i];//needs ::second (Buffy.samples() * (HE[1] * .9)) $ int => Position[i];// + Std.rand2f(0.00001, 0.05) //} //reverb mix (HE[6] * 0.05) + 0.001 => reverb.mix; //buffer rate i.e. "pitch" 1 + (HE[7] * .99) => Buffy.rate; // grain gain 0.3 * Math.sin((pi * HE[6]) / 2) => target_gaine;//Gaine; } }