165 lines · 5.5 KB · Text
RawDownload
//--------------------------------------------------------------------// name: thx.ck// desc: emulation of the original THX Deep Note//       (by Dr. James Andy Moorer)//// author: Perry R. Cook (https://www.cs.princeton.edu/~prc/)//         Ge Wang (https://ccrma.stanford.edu/~ge/)//// Perry R. Cook (Jan 8, 2007) -- original ChucK version// Ge Wang -- modified final chord to align with original Deep Note//         -- added beginning "chaotic" section//         -- time-driven loops (was counter-driven loops)//// THX resources from /Artful Design/://     https://artful.design/thx///// Andy Moorer's personal account//.    http://www.jamminpower.org/THX.html//// -------------------------------------------------------------------// Ge, Fall 2017: from Andy Mooorer:// -------------------------------------------------------------------// OK - I dug out the original program. Here are the frequency// bounds of the cluster:// #define LOCLUST 40.0// #define HICLUST 350.0//// I had started with them in a more narrow range, but then // widened it. With the randomness, they never get anywhere // near the limits.  And here are the pitches in the final// chord for all 30 voices://// double freqs[NOSCS], initialfreqs[NOSCS],// finalfreqs[] =// { 1800.0, 1800.0, 1800.0,//   1500.0, 1500.0,//   1200.0, 1200.0, 1200.0, 1200.0,//   900.0, 900.0, 900.0, 900.0,//   600.0, 600.0, 600.0,//   300.0, 300.0, 300.0, 300.0,//   150.0, 150.0, 150.0, 150.0,//   75.0, 75.0, 75.0//   37.5, 37.5, 37.5,// };//// Note that in the final chord, they are detuned a bit by // injecting a bit of randomness to make sure they don't fuse// totally. Several people have commented that the chord // sounds "bigger" than an equivalent orchestra or organ // chord (like the big chord in the Bm fugue which was my// inspiration). I believe this is because of the just // temperament of the chord. Moving the thirds and fifths // to equal temperament just doesn't have the same impact. //// Let me know if you have any other questions. I am really // excited to see your new book. It looks like great fun!// -A//-------------------------------------------------------------------- // 30 target frequencies, corresponding to pitches in a big chord:// D1,  D2, D3,  D4,  D5,  A5,  D6,   F#6,  A6[ 37.5, 75, 150, 300, 600, 900, 1200, 1500, 1800,  37.5, 75, 150, 300, 600, 900, 1200, 1500, 1800,  37.5, 75, 150, 300, 600, 900, 1200,       1800,            150, 300,      900, 1200  ] @=> float targets[]; // initial frequenciesfloat initials[30];// for the initial "wavering" in the steady statefloat initialsBase[30];float randomRates[30]; // parameters (play with these to control timing)12.5::second => dur initialHold; // initial steady segment6.0::second => dur sweepTime; // duration over which to change freq5.5::second => dur targetHold; // duration to hold target chord6.0::second => dur decayTime; // duration for reverb tail to decay to 0 // sound objectsSawOsc saw[30]; // sawtooth waveform (30 of them)Gain gainL[30]; // left gain (volume)Gain gainR[30]; // right gain (volume)// connect stereo reverberators to outputNRev reverbL => dac.left;NRev reverbR => dac.right;// set the amount of reverb0.075 => reverbL.mix => reverbR.mix; // for each sawtooth: connect, compute frequency trajectoryfor( 0 => int i; i < 30; i++ ){    // connect sound objects (left channel)    saw[i] => gainL[i] => reverbL;    // connect sound objects (right channel)    saw[i] => gainR[i] => reverbR;    // randomize initial frequencies    Math.random2f( 160.0, 360.0 ) => initials[i]                => initialsBase[i] => saw[i].freq;    // initial gain for each sawtooth generator    0.1 => saw[i].gain;    // randomize gain (volume)    Math.random2f( 0.0, 1.0 ) => gainL[i].gain;    // right.gain is 1-left.gain -- effectively panning in stereo    1.0 - gainL[i].gain() => gainR[i].gain;    // rate at which to waver the initial voices    Math.random2f(.1,1) => randomRates[i];} // hold steady cluster (initial chaotic random frequencies)now + initialHold => time end;// fade in from silencewhile( now < end ){    // percentage (should go from 0 to 1)    1 - (end-now) / initialHold => float progress;    // for each sawtooth    for( 0 => int i; i < 30; i++ ) {        // set gradually decaying values to volume        0.1 * Math.pow(progress,3) => saw[i].gain;        // waver the voices        initialsBase[i] + (1.25-progress)*.5*initialsBase[i]*Math.sin(now/second*randomRates[i])             => initials[i] => saw[i].freq;    }    // advance time    10::ms => now;} // when to stopnow + sweepTime => end;// sweep freqs towards target freqswhile( now < end ){    // percentage (should go from 0 to 1)    1 - (end-now)/sweepTime => float progress;    // for each sawtooth    for( 0 => int i; i < 30; i++ ) {        // update frequency by delta, towards target        initials[i] + (targets[i]-initials[i])*progress => saw[i].freq;    }    // advance time    10::ms => now;} // at this point: reached target freqs; briefly holdtargetHold => now; // when to stopnow + decayTime => end;// chord decay (fade to silence)while( now < end ){    // percentage (should go from 1 to 0)    (end-now) / decayTime => float progress;    // for each sawtooth    for( 0 => int i; i < 30; i++ ) {        // set gradually decaying values to volume        0.1 * progress => saw[i].gain;    }    // advance time    10::ms => now;} // wait for reverb tail before ending5::second => now;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t