// Karplus Strong circuit simulator // Copyright 2010 Les Hall [[0, 1], [0, 1], [0, 1], [0, 1]] @=> int inputSwitches[][]; [2, 2, 2, 2] @=> int gateSwitches[]; [[0, 0], [0, 4], [4, 8], [8, 8]] @=> int offsets[][]; int masks[4][2]; int inputs[4][2]; int gateOutputs[4]; float sum; int c; (Math.pow(2, 12) - 1) $ int => int bitMask; SinOsc s => dac; 0.3 => s.gain; while (true) { // generate masks for (int i; i<4; i++) { for (int j; j<2; j++) { (1 << offsets[i][j]) << inputSwitches[i][j] => masks[i][j]; } } // find input values for (int i; i<4; i++) { for (int j; j<2; j++) { if (masks[i][j] & c) { true => inputs[i][j]; } else { false => inputs[i][j]; } } } // calculate outputs for (int i; i<4; i++) { if (gateSwitches[i] == 0) { !(inputs[i][0] | inputs[i][1]) => gateOutputs[i]; } if (gateSwitches[i] == 1) { !(inputs[i][0] & inputs[i][1]) => gateOutputs[i]; } if (gateSwitches[i] == 2) { (inputs[i][0] ^ inputs[i][1]) => gateOutputs[i]; } if (gateSwitches[i] == 3) { (inputs[i][0] & inputs[i][1]) => gateOutputs[i]; } } // sum the weighted output selections 0 => sum; for (int i; i<4; i++) { Math.pow(2.0, -i) * gateOutputs[i] +=> sum; } // adjust the VCO 200 + 200 * sum => s.freq; <<>>; 1 +=> c; bitMask & c => c; 250::ms => now; }