Clamps Packages
Using a NanoKONTROL2 Controller
To use a defined midi controller, issue the add-midi-controller method with the class of the controller, a custom ID (choosable by the user) and optionally its channel as arguments:
;; create an instance of a NanoKONTROL2 midi-controller with ID :nk2 ;; using MIDI channel 1 and add it to the registry: (add-midi-controller 'nanoktl2-midi :nk2 :chan 1)
When the factory settings of the NanoKONTROL2 are in place and the controller is attached to clamps' midi ports, it can now be used.
We can add behaviour to it by attaching No description for this link functions to the knobs and faders:
(with-slots (unwatch nk2-faders) (find-controller :nk2) (dotimes (i 8) (let ((n i)) (push (watch (lambda () (msg :warn (format nil "Knob ~a turned: ~a" (1+ n) (get-val (aref nk2-faders n)))))) unwatch) (push (watch (lambda () (msg :warn (format nil "Fader ~a moved: ~a" (1+ n) (get-val (aref nk2-faders (+ n 8))))))) unwatch)))) ;; => nil ;; ;; output in REPL: ;; warn: Knob 1 turned: 0 ;; warn: Fader 1 moved: 0 ;; warn: Knob 2 turned: 0 ;; warn: Fader 2 moved: 0 ;; warn: Knob 3 turned: 0 ;; warn: Fader 3 moved: 0 ;; warn: Knob 4 turned: 0 ;; warn: Fader 4 moved: 0 ;; warn: Knob 5 turned: 0 ;; warn: Fader 5 moved: 0 ;; warn: Knob 6 turned: 0 ;; warn: Fader 6 moved: 0 ;; warn: Knob 7 turned: 0 ;; warn: Fader 7 moved: 0 ;; warn: Knob 8 turned: 0 ;; warn: Fader 8 moved: 0
The output in the REPL signals that the watch function has been established for all knobs and faders.
Moving a fader works like expected:
clamps> warn: Fader 1 moved: 1.0 warn: Fader 1 moved: 2.0 warn: Fader 1 moved: 3.0 warn: Fader 1 moved: 4.0 warn: Fader 1 moved: 5.0 warn: Fader 1 moved: 6.0 warn: Fader 1 moved: 7.0 warn: Fader 1 moved: 8.0 warn: Fader 1 moved: 9.0 <...> clamps>
Important Note
In the above example, it might not be obvious that the binding of n to i using the let in the body of the dotimes is crucial for this to work. If it isn't clear, why it wouldn't work to use i directly in the lambda forms of the watch expressions, refer to the section Excursion: Closures. The section tries to shed some light on binding and the difference of compile-time vs. run-time. Knowing how to deal with closures is a recurring necessity when working with Clamps and a thorough understanding indispensible.