// @title hw3.ck // @author Chris Chafe (cc@ccrma), Hongchan Choi (hongchan@ccrma), Reza Payami (rpayami@ccrma) // @desc First version for homework 3, Music220a-2012 // @revision 1 "//home/reza/220/hw3/" => string path; //me.sourceDir() => string path; Flute flute => PoleZero filter => JCRev reverb => dac.left; .10 => reverb.gain; .05 => reverb.mix; .99 => filter.blockZero; // bring in a mono .wav file from which to play sample // pass through Envelope to avoid clicks from SndBuf // to right chan (1) SndBuf sampler => Envelope samplerEnv => dac.right; path + "/sample.wav" => string _file; _file => sampler.read; cherr <= "[score] SndBuf: " <= _file <= IO.newline(); 10::ms => samplerEnv.duration; // write signals to files dac.left => WvOut physmodOut => blackhole; dac.right => WvOut samplerOut => blackhole; path + "/phys.wav" => string _captureP; path + "/samp.wav" => string _captureS; _captureP => physmodOut.wavFilename; _captureS => samplerOut.wavFilename; // ------------------------------------------------------------ // three algorithms which generate numbers in range -1.0 to 1.0 // see 1) logisticMapNotes.ck 2) logisticMapNotesOSC.ck for // more info fun float logistic(float x, float r) { return r * x * (1.0 - x); } // see 1) psuedoRandomNotes.ck 2) psuedoRandomNotesOSC.ck for // more info fun float random(float r) { if (r > 1.0) { 1.0 => r; } // get a random value return Math.random2f(-r, r); } // see 1) sinNotes.ck 2) sinNotesOSC.ck fun float sinusoid(float r) { // rate in radians at 1 sec period 2 * pi => float sinScale; // convert to desired rate in radians if (r > 0.0) r /=> sinScale; // current time in seconds now / second => float nowInSeconds; // convert to phase angle using rate in radians nowInSeconds * sinScale => float currentPhase; // or could be another trig function return Math.sin(currentPhase); } // ------------------------------------------------------------ // tick the chosen algorithm to get a new value fun float algorithm(float state, string type, float r) { if (type == "logistic") { // choose me to iterate the map and hear logistic map "tune" return logistic(state, r); } else if (type == "random") { // choose me for random "tune" return random(r); } else if (type == "sinusoid") { // choose me for sin function "tune" return sinusoid(r); } else if (type == "bypass") { // choose me for sin function "tune" return r; } else { cherr <= "[score] Unknown algorithm type.\n"; } } // sporkable function that plays physical model notes forever fun void pLoop(string freqAlgType, float freqAlgValue, string durationAlgType, float durationAlgValue) { float state; dur duration; while (true) { // note off in case it's already on //flute.stopBlowing(0.1); // a short rest 50::ms => now; algorithm(state, freqAlgType, freqAlgValue) => state; Math.fabs(440.0 + (state * 220.0)) => float freq; flute.clear(1.0); //flute.jetDelay(Math.random2f(0, 1)); flute.jetReflection(Math.random2f(0, 1)); flute.endReflection(Math.random2f(0, 1)); flute.noiseGain(Math.random2f(0, 1)); flute.vibratoFreq(0);//Math.random2f(0, 12)); flute.vibratoGain(Math.random2f(0, 1)); flute.pressure(Math.random2f(0, 1)); flute.freq(freq); flute.noteOn(Math.random2f(0, 0.5)); flute.startBlowing(1); algorithm(state, durationAlgType, durationAlgValue) => state; Math.fabs(state)::second => duration; duration +=> now; } } // sporkable function that plays sampler notes forever fun void sLoop(string positionAlgType, float positionAlgValue, string durationAlgType, float durationAlgValue, string rateAlgType, float rateAlgValue) { 0.1 => float state; dur duration; while (true) { // turn off envelope in case it's already on samplerEnv.target(0.0); // a short rest 50::ms => now; algorithm(state, positionAlgType, positionAlgValue) => state; sampler.length() => dur totalFile; // time in file to start playing sample from Math.fabs(state) * totalFile => dur start; // sample duration 0.1 => state; algorithm(state, durationAlgType, durationAlgValue) => state; Math.fabs(state)::second => duration; // end time of sample (start + duration) => dur end; if (end > totalFile) { end - duration => start; } // start position in file in actual samples sampler.pos((start / samp) $ int); 0.1 => state; algorithm(state, rateAlgType, rateAlgValue) => state; sampler.rate(state); // ramp up the envelope samplerEnv.target(1.0); duration +=> now; } } // ------------------------------------------------------------ // prepare the show Shred pShred; Shred sShred; // needed to stop both shreds gracefully fun void killShreds() { pShred.exit(); sShred.exit(); me.yield(); // note off flute.stopBlowing(1.0); // turn off envelope samplerEnv.target(0.0); 10::ms => now; } // ------------------------------------------------------------ // start the show //guitar solo - normal playback spork ~sLoop("bypass", 0.40, "bypass", 20, "bypass", 1.0) @=> sShred; 20::second => now; killShreds(); // guitar random start position, normal playback // flute enters - logistic frequency, random duration spork ~sLoop("random", 1.0, "bypass", 14, "bypass", 1.0) @=> sShred; spork ~pLoop("logistic", 3.0, "random", 1.0) @=> pShred; 15::second => now; killShreds(); // flute solo - logistic frequency, logistic duration spork ~pLoop("logistic", 2.0, "logistic", 3.0) @=> pShred; 10::second => now; killShreds(); // guitar random start position, 3 times faster playback // flute logistic frequency, logistic duration spork ~sLoop("random", 1.0, "bypass", 4.8, "bypass", 3) @=> sShred; spork ~pLoop("logistic", 2.0, "logistic", 3.0) @=> pShred; 7::second => now; killShreds(); //play together - 0.1::sec beat //guitar random position, normal rate //flute logistic start position spork ~sLoop("random", 1.0, "bypass", 0.1, "bypass", 1.0) @=> sShred; spork ~pLoop("logistic", 3.9, "bypass", 0.1) @=> pShred; 7::second => now; killShreds(); // guitar random start position, rate, duration // flute logistic frequency, random duration spork ~sLoop("random", 1.0, "random", 1.0, "random", 1.0) @=> sShred; spork ~pLoop("logistic", 3.9, "random", 1.0) @=> pShred; 15::second => now; killShreds(); // ------------------------------------------------------------ // finish the show physmodOut.closeFile(); samplerOut.closeFile(); // print message in terminal for sox command cherr <= "[score] Finished. Merge two products with the command below.\n"; cherr <= "sox -M " <= _captureP <= " " <= _captureS <= " "; //cherr <= me.sourceDir() + "/Milestone.wav";/ cherr <= path + "/Milestone.wav";