// dyn-notes.ck (220A-2009 ~ hw4.ck) // demo of dynamical system melodies // writes a sound file ./dyn.wav // from miniAudicle, stop the vm to complete file output after playing the shred Clarinet c => dac; // how many phrases to play in the demo [5, 6, 10, 5] @=> int numRiffs[]; [440., 800., 356., 440.] @=> float freq[]; [100, 200, 75, 100] @=> int notedelay[]; // to write soundfile dac => WvOut o => blackhole; "./dyn.wav" => o.wavFilename; //MAIN BLOCK!!! //*************************************************************** // loop over the phrases for (0 => int i; i < 4; i++)//A, B, C, A { makeTHEsnds( i ); 1500::ms => now; } // close soundfile o.closeFile; // in miniAudicle, you need to manually stop "virtual machine" to complete file output //FUNCTIONS!!! //************************************************* //************************************************* fun void makeTHEsnds( int whichone ) { for( 0 => int ctr; ctr < numRiffs[whichone]; ctr++ ) { // calculate a ramp that increases from 0 to 1 at end of the phrases (((ctr) $ float) / ((numRiffs[whichone] - 1) $ float)) => float rampUp; // use the ramp to increase the value of a0 in the polynomial above interp(3.4, 4.0, rampUp) => float heat; <<< (ctr + 1) + " // r 'heat':", heat >>>; // x is the iterated map state variable, use the same initial condition each new phrase 0.1 => float v; // play one phrase with melody based on iterated map for( 0 => int i; i < 10; i++ ) // loop for 10 notes { poly(v, heat) => v; // feedback x to iterate the map freq[whichone] + (v * freq[whichone]/2.) => float f; // use the new value as a frequency clip (50.0, 4000.0, f) => f; // bounded f => c.freq; // to clarinet 0.80 => c.startBlowing; // note on notedelay[whichone]::ms => now; // for 100ms 1.0 => c.stopBlowing; // then, note off } 500::ms => now; // wait 500ms before beginning next phrase } } // use this polynomial function, with a0 term as the "heat" variable // y = r * x * (1.0 - x) fun float poly( float x, float r) { // set the other terms to constants return r * x * (1.0 - x); } // return a linear interpolation proportional to x, between lo and hi fun float interp( float lo, float hi, float x) { return lo + (x * (hi - lo)); } // return x, bounded by lo and hi fun float clip( float lo, float hi, float x) { return Math.min (Math.max (x , lo), hi); }