Skip to content

Commit

Permalink
Update experimental nanoKONTROL2 device code to work with new event s…
Browse files Browse the repository at this point in the history
…ystem. Also create a bus for each control.
  • Loading branch information
samaaron committed Oct 4, 2012
1 parent 34b8ae9 commit 765e50f
Showing 1 changed file with 141 additions and 127 deletions.
268 changes: 141 additions & 127 deletions src/overtone/device/midi/nanoKONTROL2.clj
Original file line number Diff line number Diff line change
@@ -1,110 +1,132 @@
(ns overtone.device.midi.nanoKONTROL2
(:use [overtone.midi]
[overtone.libs.event :only [event]]))
[overtone.libs.event :only [event on-event on-latest-event]]
[overtone.core :only [control-bus bus-set!]]))

(defrecord NanoKontrol2 [name in out interfaces state])
(defrecord NanoKontrol2 [name out interfaces state busses])

(def event-handle "/overtone/midi/nanokontrol2")
(def event-handle [:midi-device "KORG INC." "SLIDER/KNOB" "nanoKONTROL2 SLIDER/KNOB" :control-change])

(def config
{:name "nanoKONTROL2"
:interfaces {:input-controls {:name "Input Controls"
:type :midi-in
:midi-handle "nanoKONTROL2"
:control-defaults {:chan 0 :cmd 176 :type :button}
:controls {:track-left {:note 58}
:track-right {:note 59}
:cycle {:note 46}
:marker-set {:note 60}
:marker-left {:note 61}
:marker-right {:note 62}
:rewind {:note 43}
:fast-forward {:note 44}
:stop {:note 42}
:play {:note 41}
:record {:note 45}
:s0 {:note 32}
:m0 {:note 48}
:r0 {:note 64}
:slider0 {:note 0 :type :slider}
:pot0 {:note 16 :type :pot}
(defn- merge-control-defaults
"Returns config map where control info maps are merged
with :control-defaults map."
[config]
(assoc config
:interfaces
(into {}
(map (fn [[i-name i-info]]
[i-name (assoc (dissoc i-info :control-defaults)
:controls (into {}
(map (fn [[c-name c-info]]
[c-name (merge (:control-defaults i-info)
c-info)])
(:controls i-info))))])
(:interfaces config)))))

(def default-event-type
{:button :on-event
:slider :on-latest-event
:pot :on-latest-event})

:s1 {:note 33}
:m1 {:note 49}
:r1 {:note 65}
:slider1 {:note 1 :type :slider}
:pot1 {:note 17 :type :pot}
(def config
(merge-control-defaults
{:name "nanoKONTROL2"
:interfaces {:input-controls {:name "Input Controls"
:type :midi-in
:midi-handle "nanoKONTROL2"
:control-defaults {:chan 0 :cmd 176 :type :button}
:controls {:track-left {:note 58}
:track-right {:note 59}
:cycle {:note 46}
:marker-set {:note 60}
:marker-left {:note 61}
:marker-right {:note 62}
:rewind {:note 43}
:fast-forward {:note 44}
:stop {:note 42}
:play {:note 41}
:record {:note 45}
:s0 {:note 32}
:m0 {:note 48}
:r0 {:note 64}
:slider0 {:note 0 :type :slider}
:pot0 {:note 16 :type :pot}

:s2 {:note 34}
:m2 {:note 50}
:r2 {:note 66}
:slider2 {:note 2 :type :slider}
:pot2 {:note 18 :type :pot}
:s1 {:note 33}
:m1 {:note 49}
:r1 {:note 65}
:slider1 {:note 1 :type :slider}
:pot1 {:note 17 :type :pot}

:s3 {:note 35}
:m3 {:note 51}
:r3 {:note 67}
:slider3 {:note 3 :type :slider}
:pot3 {:note 19 :type :pot}
:s2 {:note 34}
:m2 {:note 50}
:r2 {:note 66}
:slider2 {:note 2 :type :slider}
:pot2 {:note 18 :type :pot}

:s4 {:note 36}
:m4 {:note 52}
:r4 {:note 68}
:slider4 {:note 4 :type :slider}
:pot4 {:note 20 :type :pot}
:s3 {:note 35}
:m3 {:note 51}
:r3 {:note 67}
:slider3 {:note 3 :type :slider}
:pot3 {:note 19 :type :pot}

:s5 {:note 37}
:m5 {:note 53}
:r5 {:note 69}
:slider5 {:note 5 :type :slider}
:pot5 {:note 21 :type :pot}
:s4 {:note 36}
:m4 {:note 52}
:r4 {:note 68}
:slider4 {:note 4 :type :slider}
:pot4 {:note 20 :type :pot}

:s6 {:note 38}
:m6 {:note 54}
:r6 {:note 70}
:slider6 {:note 6 :type :slider}
:pot6 {:note 22 :type :pot}
:s5 {:note 37}
:m5 {:note 53}
:r5 {:note 69}
:slider5 {:note 5 :type :slider}
:pot5 {:note 21 :type :pot}

:s7 {:note 39}
:m7 {:note 55}
:r7 {:note 71}
:slider7 {:note 7 :type :slider}
:pot7 {:note 23 :type :pot}}}
:leds {:name "LEDs"
:type :midi-out
:midi-handle "nanoKONTROL2"
:control-defaults {:type :led}
:controls {:cycle {:note 46}
:rewind {:note 43}
:fast-forward {:note 44}
:stop {:note 42}
:play {:note 41}
:record {:note 45}
:s0 {:note 32}
:m0 {:note 48}
:r0 {:note 64}
:s1 {:note 33}
:m1 {:note 49}
:r1 {:note 65}
:s2 {:note 34}
:m2 {:note 50}
:r2 {:note 66}
:s3 {:note 35}
:m3 {:note 51}
:r3 {:note 67}
:s4 {:note 36}
:m4 {:note 52}
:r4 {:note 68}
:s5 {:note 37}
:m5 {:note 53}
:r5 {:note 69}
:s6 {:note 38}
:m6 {:note 54}
:r6 {:note 70}
:s7 {:note 39}
:m7 {:note 55}
:r7 {:note 71}}}}})
:s6 {:note 38}
:m6 {:note 54}
:r6 {:note 70}
:slider6 {:note 6 :type :slider}
:pot6 {:note 22 :type :pot}

:s7 {:note 39}
:m7 {:note 55}
:r7 {:note 71}
:slider7 {:note 7 :type :slider}
:pot7 {:note 23 :type :pot}}}
:leds {:name "LEDs"
:type :midi-out
:midi-handle "nanoKONTROL2"
:control-defaults {:type :led}
:controls {:cycle {:note 46}
:rewind {:note 43}
:fast-forward {:note 44}
:stop {:note 42}
:play {:note 41}
:record {:note 45}
:s0 {:note 32}
:m0 {:note 48}
:r0 {:note 64}
:s1 {:note 33}
:m1 {:note 49}
:r1 {:note 65}
:s2 {:note 34}
:m2 {:note 50}
:r2 {:note 66}
:s3 {:note 35}
:m3 {:note 51}
:r3 {:note 67}
:s4 {:note 36}
:m4 {:note 52}
:r4 {:note 68}
:s5 {:note 37}
:m5 {:note 53}
:r5 {:note 69}
:s6 {:note 38}
:m6 {:note 54}
:r6 {:note 70}
:s7 {:note 39}
:m7 {:note 55}
:r7 {:note 71}}}}}))

(defn- byte-seq-to-array
"Turn a seq of bytes into a native byte-array."
Expand Down Expand Up @@ -210,40 +232,13 @@
(smr-col-off out id)
(Thread/sleep (nth intro-times id))))))

(defn- merge-control-defaults
"Returns config map where control info maps are merged
with :control-defaults map."
[config]
(assoc config
:interfaces
(into {}
(map (fn [[i-name i-info]]
[i-name (assoc (dissoc i-info :control-defaults)
:controls (into {}
(map (fn [[c-name c-info]]
[c-name (merge (:control-defaults i-info)
c-info)])
(:controls i-info))))])
(:interfaces config)))))

(defn note-controls-map
[config]
(let [controls (-> config :interfaces :input-controls :controls)]
(into {}
(map (fn [[k v]] [(:note v) k])
controls))))

(defn mk-midi-in-handler
[config state event-name]
(let [ncm (note-controls-map config)]
(fn [msg ts]
(let [note (:note msg)
vel (:vel msg)
at-key (get ncm note)
atm (get state at-key)]
(reset! atm vel)
(event event-name :msg msg :ts ts :val vel :id at-key)))))

(defn connect
"Connect to a connected nanoKONTROL2 midi device. By default, it
places the deviced into 'external led mode' which allows you to
Expand All @@ -258,13 +253,32 @@
(-> config :interfaces :leds :midi-handle)))
([midi-in-str midi-out-str] (connect true midi-in-str midi-out-str))
([force-external-led-mode? midi-in-str midi-out-str]
(let [in (midi-in midi-in-str)
out (midi-out midi-out-str)
config (merge-control-defaults config)
(let [out (midi-out midi-out-str)
interfaces (-> config :interfaces)
state (into {} (map (fn [[k v]] [k (atom nil)]) (-> config :interfaces :input-controls :controls)))]
state (into {}
(map (fn [[k v]] [k (atom nil)])
(-> config :interfaces :input-controls :controls)))
busses (into {}
(map (fn [[k v]] [k (control-bus)])
(-> config :interfaces :input-controls :controls)))]
(when force-external-led-mode?
(set-external-led-mode! out))
(midi-handle-events in (mk-midi-in-handler config state event-handle))

(doseq [[k v] (-> config :interfaces :input-controls :controls)]
(let [type (:type v)
note (:note v)
handle (concat event-handle [note])
update-fn (fn [{:keys [data2-f]}]
(println "updating bus: " (busses k) data2-f)
(bus-set! (busses k) data2-f)

(reset! (state k) data2-f))]
(cond
(= :on-event (default-event-type type))
(on-event handle update-fn (str "update-state-for" handle))

(= :on-latest-event (default-event-type type))
(on-latest-event handle update-fn (str "update-state-for" handle)))))

(intromation out)
(NanoKontrol2. (:name config) in out interfaces state))))
(NanoKontrol2. (:name config) out interfaces state busses))))

0 comments on commit 765e50f

Please sign in to comment.