summaryrefslogtreecommitdiff
path: root/lib/NanoEvent.ck
diff options
context:
space:
mode:
Diffstat (limited to 'lib/NanoEvent.ck')
-rw-r--r--lib/NanoEvent.ck159
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/NanoEvent.ck b/lib/NanoEvent.ck
new file mode 100644
index 0000000..fac8580
--- /dev/null
+++ b/lib/NanoEvent.ck
@@ -0,0 +1,159 @@
+/*
+ * nanoKONTROL event class
+ */
+public class NanoEvent extends Event {
+ /* map channel (0-15) to scene name */
+ static string @channelToScene[];
+ /* map scene name and control id (0-255) to control name */
+ static string @controlToName[][];
+
+ string wantScene;
+
+ string scene;
+ string control;
+ float value;
+
+ fun int
+ isScene(string s)
+ {
+ return scene == s;
+ }
+ fun int
+ isControl(string c)
+ {
+ return control == c;
+ }
+
+ fun float
+ getFloat()
+ {
+ return value;
+ }
+ fun float
+ getFloat(float max)
+ {
+ return max*value;
+ }
+ fun float
+ getFloat(float min, float max)
+ {
+ return min + (max - min)*value;
+ }
+
+ fun dur
+ getDur(dur max)
+ {
+ return max*value;
+ }
+ fun dur
+ getDur(dur min, dur max)
+ {
+ return min + (max - min)*value;
+ }
+
+ fun int
+ getBool()
+ {
+ return value $ int;
+ }
+
+ fun void
+ __midi_loop(int device) /* pseudo-private */
+ {
+ MidiIn min;
+
+ if (!min.open(device)) {
+ <<< "Cannot open MIDI device", device >>>;
+ me.exit();
+ }
+
+ while (min => now) {
+ while (MidiMsg msg => min.recv) {
+ channelToScene[msg.data1 & 0x0F] @=> scene;
+ if (scene == null) {
+ <<< "Unknown channel", msg.data & 0x0F >>>;
+ msg.data1 & 0x0F => Std.itoa @=> scene;
+ }
+
+ msg.data1 & 0xF0 => int cmd;
+
+ controlToName[scene][msg.data2] @=> control;
+ if (control == null) {
+ <<< "Unknown controller", msg.data2 >>>;
+ msg.data2 => Std.itoa @=> control;
+ }
+
+ (msg.data3 $ float)/127 => value;
+
+ if (cmd == 0xB0 && (wantScene == null || scene == wantScene))
+ broadcast();
+ }
+ }
+ }
+ /* always open MIDI Through port, actual connection is done by Jack */
+ spork ~ __midi_loop(0);
+
+ fun static NanoEvent @
+ new(string scene)
+ {
+ NanoEvent obj;
+
+ scene @=> obj.wantScene;
+
+ return obj;
+ }
+
+ fun static void
+ registerScene(int channel, string name)
+ {
+ name @=> channelToScene[channel];
+ }
+
+ fun static void
+ registerControl(string sceneName, int id, string controlName)
+ {
+ controlName @=> controlToName[sceneName][id];
+ }
+}
+/* static initialization */
+new string[0x0F] @=> NanoEvent.channelToScene;
+new string[0][0xFF] @=> NanoEvent.controlToName;
+
+/*
+ * global mappings
+ */
+
+NanoEvent.registerScene(0, "primary");
+NanoEvent.registerScene(1, "secondary");
+NanoEvent.registerScene(3, "oscope");
+
+NanoEvent.registerControl("primary", 14, "feedbackDistKnob");
+NanoEvent.registerControl("primary", 02, "feedbackPitchSlider");
+NanoEvent.registerControl("primary", 03, "feedbackPregainSlider");
+NanoEvent.registerControl("primary", 15, "feedbackGainKnob");
+
+fun void
+registerLFO(string scene)
+{
+ NanoEvent.registerControl(scene, 22, "lfoVolumeKnob");
+ NanoEvent.registerControl(scene, 13, "lfoPitchSlider");
+ NanoEvent.registerControl(scene, 12, "lfoDepthSlider");
+ NanoEvent.registerControl(scene, 21, "lfoFreqKnob");
+ NanoEvent.registerControl(scene, 31, "lfoSinOscButton");
+ NanoEvent.registerControl(scene, 41, "lfoPulseOscButton");
+ NanoEvent.registerControl(scene, 30, "lfoSampOscButton");
+ NanoEvent.registerControl(scene, 40, "lfoWaveToggle");
+ NanoEvent.registerControl(scene, 09, "lfoEchoSlider");
+}
+"primary" => registerLFO;
+"secondary" => registerLFO;
+
+NanoEvent.registerControl("secondary", 44, "recordToggle");
+NanoEvent.registerControl("secondary", 45, "playButton");
+NanoEvent.registerControl("secondary", 46, "stopButton");
+NanoEvent.registerControl("secondary", 49, "loopToggle");
+
+NanoEvent.registerControl("oscope", 67, "modeToggle");
+NanoEvent.registerControl("oscope", 76, "fillToggle");
+NanoEvent.registerControl("oscope", 42, "frameSlider");
+NanoEvent.registerControl("oscope", 57, "delayKnob");