From b2075e5e2d937f3f109336595ba03d6ae16b657c Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Fri, 15 May 2015 11:08:34 -0400 Subject: [PATCH] this is actually old I'm just cleaning up --- life.ck | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 life.ck diff --git a/life.ck b/life.ck new file mode 100644 index 0000000..5a8f611 --- /dev/null +++ b/life.ck @@ -0,0 +1,289 @@ +13475 => int monomeIn; +16426 => int monomeOut; +"/manager" => string monomePrefix; +"127.0.0.1" => string monomeHost; + +OscRecv recv; +monomeIn => recv.port; +recv.listen(); + +fun float[][] toneGrid(int width, int height, int columnStep, int rowStep, float baseFreq, float octaveSteps) { + float tones[width][height]; + Math.pow(2, 1.0/ octaveSteps $ float) => float toneStep; + for(0 => int row; row < height; row++) { + baseFreq * Math.pow(toneStep, row * rowStep) => float rowBase; + for(0 => int col; col < width; col++) { + rowBase * Math.pow(toneStep, col * columnStep) + => tones[col][row]; + } + } + return tones; +} + +class Monome { + + string prefix; + string hostname; + OscRecv recv; + OscSend snd; + + // PROTECTED FINAL + // + // Initialization: sets up the monome and listens for incoming messages. + fun void init(string _prefix, string _hostname, int in, int out) { + preInit(); + _prefix => prefix; + _hostname => hostname; + + OscSend m; + m.setHost(hostname, out); + m @=> snd; + + in => recv.port; + recv.listen(); + + spork ~ keyListener(); + spork ~ tiltListener(); + all(0); + postInit(); + } + + // PUBLIC + // + // preInit is called before the init cycle finishes. + // + fun void preInit() {} + + // PUBLIC + // + // postInit is called after the init cycle finishes. + // + fun void postInit() {} + + // PUBLIC + // + // key is called once for every time a key is pressed on the Monome. + // Override this method in a child class to define how to handle key + // presses from the monome. + fun void key(int x, int y, int z) { + <<< prefix, "key", x, y, z >>>; + } + + // PUBLIC + // + // position change on tilt sensor n, integer (8-bit) values (x, y, z). + // This method is called once for each OSC message received from the monome + // with regards to its tilt. + fun void tilt(int n, int x, int y, int z) { + <<< prefix, "tilt", n, x, y, z >>>; + } + + // PRIVATE + // + // key press handler. This is invoked automatically by the Monome + // constructor, and should not be called. This method starts an infinite + // loop and listens for incoming osc messages from the monome. When + // messages are received, the monome object's "key" method is called. + // + fun void keyListener() { + recv.event(prefix+"/grid/key", "iii") @=> OscEvent e; + while(true) { + e => now; + while(e.nextMsg() != 0) { + e.getInt() => int x; + e.getInt() => int y; + e.getInt() => int z; + key(x, y, z); + } + } + } + + // PRIVATE + // + // tilt sensor handler. This is invoked automatically by the Monome + // constructor, and should not be called. This method starts an infinite + // loop and listens for incoming osc messages from the monome. When + // messages are received, the monome object's "tilt" method is called. + // + fun void tiltListener() { + recv.event(prefix+"/tilt", "iiii") @=> OscEvent e; + while(true) { + e => now; + while(e.nextMsg() != 0) { + e.getInt() => int n; + e.getInt() => int x; + e.getInt() => int y; + e.getInt() => int z; + tilt(n, x, y, z); + } + } + } + + // PROTECTED FINAL + // + // set led at (x,y) to state s (0 or 1). + // + fun void set(int x, int y, int s) { + snd.startMsg(prefix+"/grid/led/set", "iii"); + snd.addInt(x); + snd.addInt(y); + snd.addInt(s); + me.yield(); + } + + // PROTECTED FINAL + // + // set all leds to state s (0 or 1). + // + fun void all(int i) { + snd.startMsg(prefix+"/grid/led/all", "i"); + snd.addInt(i); + me.yield(); + } +} + +class Life extends Monome { + float tones[8][8]; + int lifeState[8][8]; + int nextLifeState[8][8]; + 100::ms => dur genStep; + false => int running; + + fun void preInit() { + toneGrid(8, 8, 1, 6, 220, 12) @=> tones; + } + + fun void postInit() { + all(0); + spork ~ live(); + } + + fun void live() { + true => running; + while(running) { + step(); + genStep => now; + } + } + + fun void pause() { + <<< "pause!" >>>; + if(running) { + false => running; + } else { + spork ~ live(); + } + } + + fun void step() { + for(0 => int i; i < 8; i++) { + for(0 => int j; j < 8; j++) { + step(i, j); + } + } + + for(0 => int i; i < 8; i++) { + for(0 => int j; j < 8; j++) { + if(nextLifeState[i][j] != lifeState[i][j]) { + set(i, j, nextLifeState[i][j]); + spork ~ play(i, j); + } + nextLifeState[i][j] => lifeState[i][j]; + } + } + } + + fun void play(int x, int y) { + SinOsc s => ADSR env => dac; + tones[x][y] => s.freq; + env.set(20::ms, 100::ms, 0.7, 20::ms); + env.keyOn(); + 40::ms => now; + env.keyOff(); + 40::ms => now; + } + + fun void step(int x, int y) { + countNeighbors(x, y) => int neighborcount; + if(lifeState[x][y] == 1) { + if(neighborcount == 2 || neighborcount == 3) { + 1 => nextLifeState[x][y]; + } else { + 0 => nextLifeState[x][y]; + } + } else { + if(neighborcount == 3) { + 1 => nextLifeState[x][y]; + } else { + 0 => nextLifeState[x][y]; + } + } + } + + fun int wrap(int x) { + if(x > 7) return 0; + if(x < 0) return 7; + return x; + } + + fun int countNeighbors(int x, int y) { + 0 => int count; + wrap(x - 1) => int left_x; + wrap(x + 1) => int right_x; + wrap(y - 1) => int up_y; + wrap(y + 1) => int down_y; + + lifeState[left_x][up_y] +=> count; + lifeState[x][up_y] +=> count; + lifeState[right_x][up_y] +=> count; + lifeState[left_x][y] +=> count; + lifeState[right_x][y] +=> count; + lifeState[left_x][down_y] +=> count; + lifeState[x][down_y] +=> count; + lifeState[right_x][down_y] +=> count; + + return count; + } + + fun void key(int x, int y, int z) { + if(z == 0) { + return; + } + toggle(x, y); + } + + fun void toggle(int x, int y) { + if(lifeState[x][y] == 0) { + 1 => lifeState[x][y]; + } else { + 0 => lifeState[x][y]; + } + set(x, y, lifeState[x][y]); + } +} + +new Life @=> Life m; +m.init(monomePrefix, monomeHost, monomeIn, monomeOut); + +fun void keyboardHandler() { + Hid hi; + HidMsg msg; + if(!hi.openKeyboard(0)) { + <<< "can't open keyboard" >>>; + return; + } + while(true) { + hi => now; + while(hi.recv(msg)) { + if(msg.isButtonDown()) { + if(msg.which == 44) { + m.pause(); + } + } + } + } +} + +spork ~ keyboardHandler(); + +while(true) { 1::second => now; }