// HEF4094B Storage Latch Pattern Generator // Copyright 2009 Les Hall // This software is protected by the GNU General Public License // parameters 25::ms => dur time_delta; // how often input signals get checked // variables float sum; // R2R ladder sum of 8-bit outputs // class instantiations HEF4094B latch; feedback_logic logic; // the patch PulseOsc clock => latch.CP; // clock signal second / time_delta / 10.0 => clock.freq; // clock frequency Step strobe => latch.STR; // strobe signal 1.0 => strobe.next; // strobe value for (int i; i<8; i++) { latch.O[i] => logic.inputs[i]; // hook latch outs to logic ins } logic.output => latch.D; // hook the feedback logic to the D input Step opamp_output => LPF lpf => dac; // send the output to the speakers/headphones 500.0 => lpf.freq; 50 => lpf.Q; // time loop while (true) { // summing amp 0 => sum; for (int i; i<8; i++) { latch.O[i].last() +=> sum; } sum / 8.0 => opamp_output.next; <<>>; // time delay 10 * time_delta => now; } // 4094 class class HEF4094B { // the patch Gain D => blackhole; // data input Gain CP => blackhole; // clock pulse input Gain STR => blackhole; // strobe input Step Os => Gain Os_; // outputs -1.0 => Os_.gain; // invert negative output Step O[8]; // logic outputs // internal storage resisters float shift[8]; // the serial shift register float latch[8]; // the 8 bit storage latch float prev_clk; // the previous clock value // lauch time loop spork ~ time_loop(); // the time loop fun void time_loop() { // loop forever while (true) { // check for positive edge of clock if ( (CP.last() > 0.5) & (prev_clk < 0.5) ) { // shift in data shift[7] => Os.next; // send serial data out for (int i; i<7; i++) { shift[i] => shift[i+1]; // shift the register } D.last() => shift[0]; // receive data input // check to see if strobe is high if (STR.last() > 0.5) { // latch the data from the shift register to the storage register for (int i; i<8; i++) { shift[i] => latch[i]; latch[i] => O[i].next; } } } // remember previous clock value CP.last() => prev_clk; // time step time_delta => now; } } } // the feedback logic // change this to make different music class feedback_logic { // the patch Gain inputs[8]; // the 8 inputs for (int i; i<8; i++) { inputs[i] => blackhole; // suck data to the inputs } Step output; // the output Gain Os_ => blackhole; // additional input to add complexity // internal nodes (wires) int in[8]; // the eight inputs int nodes[5]; // four nodes, change to suit logic expression int os_; // the additional input // launch the time loop spork ~ time_loop(); // the time loop fun void time_loop() { // loop forever while (true) { // copy the inputs to the input array for (int i; i<8; i++) { (inputs[i].last() > 0.5) => in[i]; } (Os_.last() > 0.5) => os_; // perform the logic function (change this to change music) !(in[0] & in[4]) => nodes[0]; !(in[1] & in[5]) => nodes[1]; !(in[2] & in[6]) => nodes[2]; !(in[3] & in[7]) => nodes[3]; (nodes[0] | nodes[1] | nodes[2] | nodes[3]) => nodes[4]; nodes[4] ^ os_ => output.next; // send out the result // time step time_delta => now; } } }