aboutsummaryrefslogtreecommitdiff
path: root/guile/starlet/midi-control/faders.scm
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-09-11 12:15:14 +0200
committerThomas White <taw@physics.org>2021-09-11 12:19:41 +0200
commit3c4c9a2c89defe50ad40c544e383f50eb0aa040e (patch)
tree71ecb33c51c7b253c5c6d31b40fff662436d1d02 /guile/starlet/midi-control/faders.scm
parentd79c75b3db76e242e0299d5d324191e3133de235 (diff)
Re-assert MIDI control map on parameter change
This makes the MIDI controller stay in sync with the programmer state values. It's kind of a coarse solution, though. It would be better to: 1. Only re-assert the map if the changed parameter currently appears on the MIDI control surface 2. Only re-assert the part of the map related to the parameter Almost as a side-effect, this enables switching between multiple control maps. Just call 'set-midi-control-map!' on the controller with the new map.
Diffstat (limited to 'guile/starlet/midi-control/faders.scm')
-rw-r--r--guile/starlet/midi-control/faders.scm83
1 files changed, 66 insertions, 17 deletions
diff --git a/guile/starlet/midi-control/faders.scm b/guile/starlet/midi-control/faders.scm
index dbd2a0f..bd2da95 100644
--- a/guile/starlet/midi-control/faders.scm
+++ b/guile/starlet/midi-control/faders.scm
@@ -26,10 +26,22 @@
#:use-module (starlet scanout)
#:use-module (starlet utils)
#:use-module (srfi srfi-1)
- #:export (use-midi-control-map
+ #:use-module (oop goops)
+ #:export (set-midi-control-map!
state-on-fader))
+(define-class <parameter-controller> (<object>)
+ (callbacks
+ #:init-keyword #:callbacks
+ #:getter get-callbacks
+ #:setter set-callbacks!)
+
+ (control-map
+ #:init-keyword #:control-map
+ #:getter get-control-map))
+
+
(define (name-for-fader-state controller cc-number)
(call-with-output-string
(lambda (port)
@@ -277,23 +289,60 @@
(send-note-off controller leds))))
-(define (use-midi-control-map controller control-map)
- (let ((midi-callbacks '()))
- (add-hook! selection-hook
- (lambda (fixture-list)
+(define (scrub-parameter-controller! controller parameter-controller)
+
+ ;; Remove all the old callbacks
+ (for-each (lambda (callback)
+ (remove-midi-callback! controller callback))
+ (get-callbacks parameter-controller))
+
+ ;; Switch off all the old LEDs
+ (for-each (lambda (control-spec)
+ (led-off controller (cadddr control-spec)))
+ (get-control-map parameter-controller)))
+
+
+(define (update-midi-controls controller fixture-list)
+
+ (scrub-parameter-controller! controller
+ (get-parameter-controller controller))
+
+ (set-callbacks!
+ (get-parameter-controller controller)
+ (map (lambda (control-spec)
+ (midi-control-attr controller control-spec fixture-list))
+ (get-control-map (get-parameter-controller controller)))))
+
+
+(define (set-midi-control-map! controller new-control-map)
+ (let ((old-parameter-controller (get-parameter-controller controller)))
+
+ ;; Remove the old parameter controller
+ (when old-parameter-controller
+ (scrub-parameter-controller! controller old-parameter-controller))
+
+ (set-parameter-controller!
+ controller
+ (make <parameter-controller>
+ #:callbacks '()
+ #:control-map new-control-map))
- (for-each (lambda (callback)
- (remove-midi-callback! controller callback))
- midi-callbacks)
+ ;; If this is the first time, add the callbacks
+ (unless old-parameter-controller
- (for-each (lambda (control-spec)
- (led-off controller (cadddr control-spec)))
- control-map)
+ ;; Selection changed
+ (add-hook!
+ selection-hook
+ (lambda (fixture-list)
+ (update-midi-controls controller fixture-list)))
- (set! midi-callbacks '())
+ ;; Value changed
+ (add-update-hook! programmer-state
+ (lambda (fix attr value source)
+ (unless (eq? source controller)
+ (update-midi-controls controller (get-selection))))))
- (unless (nil? fixture-list)
- (set! midi-callbacks
- (map (lambda (control-spec)
- (midi-control-attr controller control-spec fixture-list))
- control-map)))))))
+ ;; If there is a selection, run the callback now
+ (let ((current-selection (get-selection)))
+ (when current-selection
+ (update-midi-controls controller current-selection)))))