// launch with OSC_recv.ck // host name and port [ //["mel", "0.0.0.0"], ["inventor", "localhost"] ] @=> string hostnames[][]; hostnames.cap() => int numHosts; hostnames[numHosts-1][0] => string identity; 6449 => int port; "/ChucKchat/ascii" => string identifier; 1.0 => float maxVolume; 0.0 => float minVolume; // define alphabetical lower case letters ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] @=> string lettersLowerCase[]; ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] @=> string numbers[]; // the patch // beeper SinOsc osc1 => Gain volume => dac; 440 => osc1.freq; 0 => osc1.gain; 1 => volume .gain; // loopoer adc => PitShift pitshift => volume; 0.5 => pitshift.mix; 0.95 => pitshift.shift; // activation functions // beep once function void beep(float v) { v => osc1.gain; 100::ms => now; 0 => osc1.gain; } // boolean sequencer class BS { int numBits; int maxCount; float bps; int pattern[32]; Step value => Gain output; Step gate; function void setBits(int n) { n => numBits; (Math.pow(2, n) $ int) => maxCount; for (0=>int i; i float a; Std.rand2f(-1, 1) => float b; Std.rand2f(-1, 1) => float c; Math.fabs( a * b * c * maxCount) $ int => pattern[i]; } } setBits(14); function void setTempo(float t) { t => bps; } setTempo(1.0/8); function void setGain(float g) { g => output.gain; } setGain(1.0); function void timeLoop() { int count; int logicSum; while (true) { 0 => logicSum; for (0=>int i; i value.next; (logicSum > 0) => gate.next; 3::ms => now; 0 => gate.next; (count + 1) % maxCount => count; bps::second - 10::ms => now; } } spork ~ timeLoop(); } // Karplus Strong class KS { 1 => float minDelay; 25 => float maxDelay; -0.7 => float minGain; 0.7 => float maxGain; 100 => float minFreq; 1000 => float maxFreq; Gain input => blackhole; Gain gate => Gain sum => LPF filter => Gain output; filter => DelayA delay => LPF noisey => sum; 1 => gate.gain; 1 => filter.Q; 1000 => noisey.freq; 1 => noisey.Q; maxDelay::ms => delay.max; function void monitor() { setFreq( (maxFreq - minFreq) * 0 + minFreq ); setDelay( (maxDelay - minDelay) * (1 - 0) + minDelay ); while (true) { if (gate.last() > 0) { setFreq( (maxFreq - minFreq) * input.last() + minFreq ); setDelay( (maxDelay - minDelay) * (1 - input.last() ) + minDelay ); } 1::ms => now; } } spork ~ monitor(); function void setDelay(float d) { if (d < minDelay) { minDelay => d; } else if (d > maxDelay) { maxDelay => d; } d::ms => delay.delay; } setDelay(maxDelay); function void setFreq(float f) { if (f < minFreq) { minFreq => f; } else if (f > maxFreq) { maxGain => f; } f => filter.freq; } setFreq(minFreq); function void setGain(float g) { if (g < minGain) { minGain => g; } else if (g > maxGain) { maxGain => g; } g => sum.gain; } setGain(minGain); } // make use of the boolean sequencer BS bs; KS ks; bs.output => ks.input; bs.gate => ks.gate; ks.output => volume; // Transmitter // send object OscSend xmit; Hid hi; HidMsg msg; // which keyboard 0 => int device; // get from command line if( me.args() ) me.arg(0) => Std.atoi => device; // open keyboard (get device number from command line) if( !hi.openKeyboard( device ) ) me.exit(); <<< "keyboard '" + hi.name() + "' ready", "" >>>; "" => string xmitString; // received string // hid loop function void transmit() { while (true) { // wait on event hi => now; // get one or more messages while( hi.recv( msg ) ) { // check for action type if( msg.isButtonDown() ) { //<<< "down:", msg.which, "(code)", msg.key, "(usb key)", msg.ascii, "(ascii)" >>>; msg.ascii => int char; if ( (char >= 65) && (char <= 90) ) { xmitString + lettersLowerCase[char-65] => xmitString; } else if ( (char >= 48) && (char <= 57) ) { xmitString + numbers[char-48] => xmitString; } else if (char == 32) { xmitString + " " => xmitString; } else if (char == 45) { xmitString + "-" => xmitString; } else if (char == 46) { xmitString + "." => xmitString; } else if (char == 10) { for (int i; i xmit.addString; xmitString => xmit.addString; // clear transmit string "" => xmitString; } } } else { //<<< "up:", msg.which, "(code)", msg.key, "(usb key)", msg.ascii, "(ascii)" >>>; } } } } spork ~ transmit(); // Reciever // create our OSC receiver OscRecv recv; // use port 6449 port => recv.port; // start listening (launch thread) recv.listen(); // create an address in the receiver, store in new variable recv.event(identifier + ", s,s") @=> OscEvent oe; // variables string recvIdentity; // identity of receiver string recvMessage; // the received message StringTokenizer tok; // tokens the strings string id; // target identification (could be you) string command; // first token, could be a command float value; // second token, could be a value // infinite event loop function void receive() { while ( true ) { // wait for event to arrive oe => now; // grab the next message from the queue. while ( oe.nextMsg() != 0 ) { // get the received strings oe.getString() => recvIdentity; oe.getString() => recvMessage; // print the received strings <<>>; // tokenize in case a command was sent tok.set(recvMessage); tok.next() => id; tok.next() => command; Std.atof(tok.next()) => value; // reset the tokenizer to look for identity in message tok.set(recvMessage); while (tok.more() ) { if (tok.next() == identity) { beep(0.25); } } // respond to commands if (id == identity) { if (command == "volume") { if (value > maxVolume) { maxVolume => value; } else if (value < minVolume) { minVolume => value; } value => volume.gain; } else if ( (command == "frequency") || (command == "freq") ) { value => osc1.freq; } else if (command == "beep") { beep(value); } else if (command == "ps.mix") { value => pitshift.mix; } else if (command == "ps.shift") { value => pitshift.shift; } else if (command == "bs.numbits") { bs.setBits(value$int); } else if (command == "bs.tempo") { bs.setTempo(value); } else if (command == "bs.gain") { bs.setGain(value); } else if (command == "ks.delay") { ks.setDelay(value); } else if (command == "ks.freq") { ks.setFreq(value); } else if (command == "ks.gain") { ks.setGain(value); } } } } } spork ~ receive(); // time loop while (true) { second => now; }