Difference between revisions of "StereoChordEGG.ck"
From CSWiki
Line 11: | Line 11: | ||
//Paia's circuit used a top-octave generator to make a square wave train that they somehow filtered. | //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. | // 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. | // Paia used three note chords, so that's good enough for us. | ||
BandedWG tonic => gain g; | BandedWG tonic => gain g; | ||
BandedWG two => g; | BandedWG two => g; | ||
BandedWG third => g; | BandedWG third => g; | ||
− | |||
// the banded wave guides will be playing all the time, so the only control is that | // 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. | // we will be ramping the gain of the mixer from current vol to wanted vol. | ||
Line 22: | Line 20: | ||
float wantedvol; | float wantedvol; | ||
g => dac; | g => dac; | ||
− | |||
// set some defaults for the banded wave guide generators. I don't know or care too much | // 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. | // what these all mean. It is enough that someone out in internet land knows. | ||
Line 29: | Line 26: | ||
loudness=> b.gain; | loudness=> b.gain; | ||
1=> b.preset; | 1=> b.preset; | ||
− | |||
// comp-XXX salesman: "hey Arnie! He doesn't know what std.mtof does!". Spock: "read the source, luke". | // comp-XXX salesman: "hey Arnie! He doesn't know what std.mtof does!". Spock: "read the source, luke". | ||
std.mtof(21+note) => b.freq; | std.mtof(21+note) => b.freq; | ||
− | |||
// we love rand functions to set important parameters so that the wool is firmly over our eyes. | // 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!" | // As the Church of the Subgenius sez: "Praise Bob!" | ||
Line 39: | Line 34: | ||
std.rand2f( 0.6, 0.8 ) => b.startBowing; | std.rand2f( 0.6, 0.8 ) => b.startBowing; | ||
} | } | ||
− | |||
// adjust the gain up or down as needed without going passed the desired limit | // 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 | // note that the direction of the adjustment MUST be in agreement with the desired | ||
Line 50: | Line 44: | ||
adjust=>g.gain; | adjust=>g.gain; | ||
} | } | ||
− | |||
// set some reasonable values for this object. Normally we would do this in a constructor. (where | // set some reasonable values for this object. Normally we would do this in a constructor. (where | ||
// are the constructors? I must have missed something... | // are the constructors? I must have missed something... | ||
Line 63: | Line 56: | ||
0=> g.gain; | 0=> g.gain; | ||
} | } | ||
− | |||
//ramp the volume on this object incrementally till we hit the wanted volume | //ramp the volume on this object incrementally till we hit the wanted volume | ||
public void rampgain ( ) { | public void rampgain ( ) { | ||
Line 78: | Line 70: | ||
} | } | ||
} | } | ||
− | |||
} | } | ||
// a function for "syntactic cod-liver-oil" since we can't spork c.rampgain directly | // a function for "syntactic cod-liver-oil" since we can't spork c.rampgain directly | ||
Line 94: | Line 85: | ||
V.setChord ( 5,7,2,"V"); | V.setChord ( 5,7,2,"V"); | ||
spork ~ runChord(V); | spork ~ runChord(V); | ||
− | |||
//since machines like to use numbers to access the chords, rather than names like I,IV,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 | //we put the chord object (references) into an array | ||
[I,IV,V] @=> Chord @ s[ ] ; | [I,IV,V] @=> Chord @ s[ ] ; | ||
− | |||
//changeto will bring up the volume on one of the chords and leave it like for a specified duration | //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 ) | fun void changeto (float amplitude,int index,dur t ) |
Revision as of 17:36, 21 February 2006
// 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 ); }