( // VISUALS // Init vars and window var projectionWin, arduino_port, osc_func, brightness = {0} ! 27, refresh_func; projectionWin = Window.new("Remembering Clive Wearing", Rect(500, 500, 750, 500)).front; projectionWin.background = Color.black; // Keybinds (these can be change if conflicting with system keybinds) projectionWin.view.keyDownAction = { |doc, char, mod, unicode, keycode, key| case // = enter full screen {mod == 262144 && key == 70} {projectionWin.fullScreen} // = exit full screen {mod == 0 && key == 16777216} {projectionWin.endFullScreen} // = run synth {mod == 262144 && key == 82} {refresh_func.fork(AppClock); ~flicker.run} // = pause synth {mod == 262144 && key == 80} {~flicker.run(false)} // = start / fade in {mod == 262144 && key == 83} {~fadeInTrigBus.set(1)} // = end / fade out {mod == 262144 && key == 69} {~fadeOutTrigBus.set(1)} // = trigger wake {mod == 262144 && key == 84} {~wakeTrigBus.set(1)} }; // Connect arduino; edit first arg / port to match index or name of port: SerialPort.listDevices if(~arduino == 1, { arduino_port = SerialPort( 0, 115200) }, {}); // Get control signals from SynthDef osc_func = OSCFunc.new({arg msg, time; brightness[msg[2]] = msg[3]; },'/tr', s.addr); // Draw the window projectionWin.drawFunc = { var projectionRect = projectionWin.view.bounds; {|i| var outerLen, vPad, outerSquare; outerLen = projectionRect.width / 2; vPad = projectionRect.height - outerLen; outerSquare = projectionRect.insetBy(outerLen * i, vPad / 2).resizeTo(outerLen, outerLen); outerSquare = outerSquare.insetBy(outerLen * 0.05, outerLen * 0.05).resizeTo(outerLen * 0.9, outerLen * 0.9); {|j| var innerLen, innerSquare; innerLen = outerSquare.width / 3; innerSquare = outerSquare.insetBy(innerLen * (j % 3), innerLen * (j / 3).trunc).resizeTo(innerLen, innerLen); Pen.addOval(innerSquare); Pen.fillRadialGradient(innerSquare.center, innerSquare.center, (innerSquare.width / 16), (innerSquare.width / 2), Color.black.blend(Color.new255(255, 214, 170, 255), pow(brightness[(i * 9) + j], 0.5)), Color.black); } ! 9 } ! 2 }; projectionWin.refresh; // Refresh function refresh_func = { while { true } { // updateProjection projectionWin.refresh; // updateArduino if(~arduino == 1, { {|i| arduino_port.putAll(i.asString); arduino_port.put(Char.space); arduino_port.putAll(((brightness[i] - 1).abs * 110).trunc.asString); arduino_port.put(Char.space); arduino_port.put(13); } ! 18 }, {}); // delay 30.reciprocal.wait; } }; )