+++ /dev/null
-// Ableton push handler
-// by Eugene Zuelum
-//
-// see https://github.com/Ableton/push-interface for info about ABI:
-// https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc
-
-(
-~pushFactory = {
- var dest;
- var push = Environment[
- \version -> "33.7.2.5",
-
- \tempo -> 2,
-
- \padColor -> IdentityDictionary[
- \white -> 0,
- \red -> 1,
- \amber -> 2,
- \yellow -> 3,
- \lime -> 4,
- \green -> 5,
- \spring -> 6,
- \turquoise -> 7,
- \cyan -> 8,
- \sky -> 9,
- \ocean -> 10,
- \blue -> 11,
- \orchid -> 12,
- \magenta -> 13,
- \pink -> 14
- ],
-
- // preprocess relative controls
- \ppcr -> { |zi ...args|
- if (args[0] > 64, {
- args[0] = args[0] - 128;
- });
- args;
- },
-
- // preprocess absolute controls and notes
- \ppca -> { |zi ...args|
- args[0] = args[0].linlin(0, 127, 0, 1);
- args;
- },
-
- // preprocess bend
- \ppcb -> { |zi ...args|
- if (args[0] >= 8192, {
- args[0] = args[0].linlin(8192, 16383, 0, 1);
- }, {
- args[0] = args[0].linlin(0, 8192, -1, 0);
- });
- args;
- },
-
- // preprocess push color
- \pppc -> {|zi, c=0,l=3,w=false|
- var color;
- c = zi.padColor[c] ? c;
- if (c == 0, {
- color = l;
- },{
- if (l == 0, {
- color = 0;
- }, {
- if (w, {
- color = c*4;
- }, {
- color = c*4 + 4 - l;
- });
- });
- });
- color;
- },
-
- \hcPushTurnN -> Array.newClear(9),
- \hcPushTouchN -> Array.newClear(9)
- ];
-
- push.know = true;
-
- push.controllerFuncs = [
- // Rotators
- MIDIFunc.cc({ |...args|
- push.hcPushTurnS(*push.ppcr(*args));
- }, 14, 0),
- MIDIFunc.cc({ |...args|
- push.hcPushTurnL(*push.ppcr(*args));
- }, 15, 0),
- MIDIFunc.cc({ |...args|
- var col = args[1] - 71;
- push.hcPushTurnN[col].value(*push.ppcr(*args));
- },
- (71..79), 0),
- MIDIFunc.noteOn({ |...args|
- push.hcPushTouchS(true, *args);
-
- }, 10, 0),
- MIDIFunc.noteOn({ |...args|
- push.hcPushTouchL(true, *args);
-
- }, 9, 0),
- MIDIFunc.noteOn({ |...args|
- //args[1] = args[1] - 71;
- push.hcPushTouchN[args[1]].value(true, *args);
- },
- (0..8), 0),
- MIDIFunc.noteOff({ |...args|
- push.hcPushTouchS(false, *args);
-
- }, 10, 0),
- MIDIFunc.noteOff({ |...args|
- push.hcPushTouchL(false, *args);
-
- }, 9, 0),
- MIDIFunc.noteOff({ |...args|
- args[1] = args[1] - 71;
- push.hcPushTouchN[args[1]].value(false, *args);
- },
- (0..8), 0),
-
- // Left buttons
- MIDIFunc.cc({ |...args|
- if (args[0] == 127, {
- push.playDown(*args);
- }, {
- push.playUp(*args);
- });
- }, 85, 0),
- MIDIFunc.cc({ |...args|
- if (args[0] == 127, {
- push.recDown(*args);
- }, {
- push.recUp(*args);
- });
- }, 86, 0),
-
- // Pads
- MIDIFunc.noteOn({ |...args|
- var note, row, col;
- note = args[1] - 36;
- col = note % 8;
- row = (note/ 8).asInteger;
- push.padDown(row, col, *push.ppca(*args));
- },
- (36..99), 0),
-
- MIDIFunc.noteOff({ |...args|
- var note, row, col;
- note = args[1] - 36;
- col = note % 8;
- row = (note/ 8).asInteger;
- push.padUp(row, col, *push.ppca(*args));
- }, (36..99), 0),
-
- MIDIFunc.polytouch({ |...args|
- var note, row, col;
- note = args[1] - 36;
- col = note % 8;
- row = (note/ 8).asInteger;
- push.padPressure(row, col, *push.ppca(*args));
- }, (36..99), 0),
- ];
-
- //============================== Binding hc to synth parameters
-
- push.bindMul = { |zi, synth, param, divisor=1|
- { |d|
- synth.get(param, { |v|
- var newVal = v*((d)/divisor).midiratio;
- "%: % = %\n".postf(synth, param, newVal);
- synth.set(param, newVal);
- });
- }
- };
-
- push.bindAdd = { |zi, synth, param, divisor=1|
- { |d|
- synth.get(param, { |v|
- var newVal = v+(d/divisor);
- "%: % = %\n".postf(synth, param, newVal);
- synth.set(param, newVal);
- });
- }
- };
-
- push.bindRange = { |zi, synth, param, start, end|
- { |v|
- var newVal = v.linlin(0, 1, start, end);
- "%: % = %\n".postf(synth, param, newVal);
- synth.set(param, newVal);
- }
- };
-
- //============================== LED control
- dest = MIDIClient.destinations.detect({ |item|
- // TODO: optimize
- var res = false;
- if (item.device == "Ableton Push", {
- if (item.name == "Ableton Push MIDI 2", {
- res = true;
- });
- if (item.name == "User Port", {
- res = true;
- });
- });
- res;
- });
- push.pushOut = MIDIOut.newByName(dest.device, dest.name);
- // The following is working by itself,
- // but factory function assignment to global var
- // returns nil
- /*try {
- // linux
- push.pushOut = MIDIOut.newByName("Ableton Push", "Ableton Push MIDI 2");
- }{
- // mac os
- push.pushOut = MIDIOut.newByName("Ableton Push", "User Port");
- };*/
-
- push.pushOut.latency_(0);
- if (push.pushOut==nil, {"Cannot control push LEDs!"});
-
- push.padLight = {|zi, row, col, light=3, color=0, whiten=false, mode=0|
- if ((col < 0) || (col > 7) || (row < 0) || (row > 7), {}, {
- zi.pushOut.noteOn(mode, 36+(row*8)+col, zi.pppc(color, light, whiten));
- });
- };
-
- push.hcPushPadLedClear = { |zi|
- for (0, 7, {|i|
- for (0, 7, {|j|
- zi.hcPushPadLed.value(i, j, 0);
- });
- });
- };
-
- push.freeHC = { |zi|
- zi.controllerFuncs.do({ |item| item.free; });
- zi.pushOut.free;
- };
-
- // todo — always send clocks, and separate start/stop from setting tempo
- push.setTempo = { |zi, tempo|
- {
- zi.pushOut.start;
- 1.do({
- 24.do({
- zi.pushOut.midiClock;
- (1.0/zi.tempo/24).wait;
- });
- });
- zi.pushOut.stop;
- }.fork();
- };
-
- // Starter message and animation
- {
- (0..127).do({|i|
- ~push.pushOut.noteOn(0, i, 1);
- ~push.pushOut.control(0, i, 1);
- });
- 1.wait;
- (0..127).do({|i|
- ~push.pushOut.noteOn(0, i, 0);
- ~push.pushOut.control(0, i, 0);
- });
- }.fork();
-
- "Џяпюӈи готов к использованию 😊".postln;
-
- push;
-};
-)
-
-//============================================================================= Testing
-
-/* Test all LED colors via rotaning left rotary control
-~push = ~pushFactory.value;
-~col = 0;
-
-(
-~push.hcPushTurnS = { |zi, delta|
-~col = (~col + delta).clip(0, 127);
-~col.postln;
-(0..127).do({|i|
-~push.pushOut.noteOn(0, i, ~col);
-~push.pushOut.control(0, i, ~col);
-});
-};
-)
-*/
-
-/* Show first 64 colors
-(
-~color = 1;
-8.do({|i|
-8.do({|j|
-~push.pushOut.noteOn(0, 36+(i*8)+j, ~color);
-~color = ~color + 1;
-});
-});
-)
-*/
\ No newline at end of file