// Womb // Colin Raffel, 2009 // Sound generators // Phasor which cycles through the Gen9 parameters Phasor ph[7]; // Gen9 for making interesting waveform from phasor Gen9 g9[7]; // Noise generator, also fed into the Gen9 Noise n[7]; // LPF for each Noise/Gen9 combo LPF l[7]; // Level for each noise/gen9 combo Gain g[7]; // Delay line for each cluster of sound generation DelayL e[7]; // Feedback for each delay line Gain f[7]; // Gain for each noise generator Gain ng[7]; // Pitch shift for each cluster, octave down PitShift p[7]; // Pitch shift for each cluster, octave up PitShift p2[7]; // LPF in the feedback of the delay loop LPF fl[7]; // Sin oscillator for each cluster SinOsc sin[7]; // Sine gain Gain sg[7]; // Notes to play [ 33, 35, 39, 41, 43, 44, 47] @=> int keyn[]; // Osc port to listen 8000 => int oscport; // OSC Messages to receive string baseLevelMessage; "/level/base, i i" => baseLevelMessage; string lowMessage; "/level/low, i i" => lowMessage; string shiftMessage; "/level/shift, i i" => shiftMessage; // Initialize our signal flow for( 0 => int i; i < 7; i++ ) { // Coefficients for the Gen9 g9[i].coefs( [1., 0.5, 0.3, 0.2] ); // The phasor path ph[i] => g9[i] => g[i] => p[i] => p2[i] => e[i] => dac.chan(2*i); // Also send each channel twice e[i] => dac.chan(2*i+1); // Gain for each noisy osc, first set to zero 0 => g[i].gain; // Gain for echo .4 => e[i].gain; // Max delay for each echo 500::ms => e[i].max; // Random number for each delay time Std.rand2(100,500)::ms => e[i].delay; // Noisy oscillator lpf frequency 400 => l[i].freq; // Gain for each noise gen .15 => ng[i].gain; // Pitch shift and mix for the octave down .5 => p[i].shift; .5 => p[i].mix; // Pitch shift and mix for octave up (mix set via OSC) 2.0 => p2[i].shift; 0.0 => p2[i].mix; // Initialize frequencies of feedback filters keyn[i]*8 => fl[i].freq; // Regeneration feedback 2.15 => f[i].gain; // Sin oscillator gain, initialize 0.0 => sg[i].gain; // Initialize frequency of sin oscillators and phasors Std.mtof(keyn[i]) => sin[i].freq => ph[i].freq; // Send the sine oscs out sin[i] => sg[i] => p2[i]; sin[i] => sg[i] => p2[i]; // Send the noise generator in to modulate frequency n[i] => l[i] => ng[i] => g9[i]; e[i] => fl[i] => f[i] => e[i]; } // Spork our osc listeners for each message spork ~ oscListener( oscport, baseLevelMessage ); me.yield(); spork ~ oscListener( oscport, lowMessage ); me.yield(); spork ~ oscListener( oscport, shiftMessage ); me.yield(); // OSC listener shred fun void oscListener( int port, string osctype ) { // Create our OSC receiver OscRecv recv; port => recv.port; recv.listen(); // Received value int val; // Index to apply value to int index; // Type of osc message osctype => string type; // Create an address in the receiver, store in new variable recv.event( osctype ) @=> OscEvent oe; while( true ) { // Wait for osc event to arrive oe => now; // Loop through OSC messages while( oe.nextMsg() ) { oe.getInt() => index; oe.getInt() => val; // Depending on message type, apply a value if( type == baseLevelMessage ) { .175*val/127=> g[index].gain; } if( type == lowMessage ) { .04*val/127 => sg[index].gain; } if( type == shiftMessage ) { 1.0*val/127.0 => p2[index].mix; } me.yield(); } } } // Main loop while (true) { // Wait for some amount of time Std.rand2f(.3, 3)::second => now; // Chance noisy osc frequency randomly Std.rand2(0, 6) => int random; ph[random].freq() + Std.rand2f(-1, 1) => ph[random].freq; }