From CSWiki
Revision as of 18:16, 21 February 2006 by Art (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

// In the late '60s or early 70's Paia electronics came out with a circuit kit called the // Stereo Chord EGG (Electronic Gratification Generator). It was a top-octave generator // along with a resistor network to mix up the I,IV and V chords into the left and right channels. // // This little chuck proggy is an attempt to re-create "the wisdom of the ancients" and let you // hear what this little guy sounded like -- as best as my 35 year old, admittedly alcohol // addled memories will permit.

class Chord { string myName; // a name for us to show the user during debug prints. BTW: what's with <<<>>> ??!?!

//Paia's circuit used a top-octave generator to make a square wave train that they somehow filtered. // I can't remember how that happened so I used banded wave guides, since it sounded right.

// Paia used three note chords, so that's good enough for us. BandedWG tonic => gain g; BandedWG two => g; BandedWG third => g;

// the banded wave guides will be playing all the time, so the only control is that // we will be ramping the gain of the mixer from current vol to wanted vol. float currvol; float wantedvol; g => dac;

// set some defaults for the banded wave guide generators. I don't know or care too much // what these all mean. It is enough that someone out in internet land knows. // "The internet is the ultimate irreferance": Jim Hinds. and you can quote me on that. public void setBand ( BandedWG b, float loudness, int note ) { loudness=> b.gain; 1=> b.preset;

// comp-XXX salesman: "hey Arnie! He doesn't know what std.mtof does!". Spock: "read the source, luke". std.mtof(21+note) => b.freq;

// we love rand functions to set important parameters so that the wool is firmly over our eyes. // As the Church of the Subgenius sez: "Praise Bob!" std.rand2f( 0.1, 0.9 ) => b.bowRate; std.rand2f( 0.2, 0.35 ) => b.bowPressure; std.rand2f( 0.6, 0.8 ) => b.startBowing; }

// adjust the gain up or down as needed without going passed the desired limit // note that the direction of the adjustment MUST be in agreement with the desired // direction. This method doesnt know about that. That's one reason it is private. private void gainTo ( float v, float wanted ) { currvol + v => float adjust; if ( wanted > currvol && adjust > wanted ) wanted => adjust; if ( wanted < currvol && adjust < wanted ) wanted => adjust; adjust=>currvol; adjust=>g.gain; }

// set some reasonable values for this object. Normally we would do this in a constructor. (where // are the constructors? I must have missed something... // public void setChord ( int tonicValue, int twoValue, int thirdValue,string n) { n => myName; setBand (tonic, .80, tonicValue); setBand (two, .85, twoValue); setBand (third, .9, thirdValue); 0 => wantedvol; 0 => currvol; 0=> g.gain; }

//ramp the volume on this object incrementally till we hit the wanted volume public void rampgain ( ) { float adjust; while ( 1 ) { 175::ms => now; if ( currvol > wantedvol ) { gainTo(-.2, wantedvol); } if ( currvol < wantedvol ) { gainTo(.1, wantedvol); } // <<<myName, currvol,wantedvol>>>; } }


// a function for "syntactic cod-liver-oil" since we can't spork c.rampgain directly fun void runChord (Chord c) { c.rampgain(); }

//set up the I, IV and V chords and start them sounding at amplitude zero Chord I; I.setChord ( 1,3,5,"I"); spork ~ runChord(I); Chord IV; IV.setChord ( 4,6,1,"IV"); spork ~ runChord(IV); Chord V; V.setChord ( 5,7,2,"V"); spork ~ runChord(V);

//since machines like to use numbers to access the chords, rather than names like I,IV,V //we put the chord object (references) into an array [I,IV,V] @=> Chord @ s[ ] ;

//changeto will bring up the volume on one of the chords and leave it like for a specified duration fun void changeto (float amplitude,int index,dur t ) { for ( 0 =>int i; i <3 ; i++ ) { 0 => float v; if (i == index ) amplitude => v; v=> s [i].wantedvol; } t => now ; }

//select a chord at random, bring it up to a random level and hold for some reasonable time while (1) { changeto (std.rand2f(.5,.9), std.rand2(0,2), std.rand2f(1.5,4)::second ); }