Commit b839f72d authored by Brandon Invergo's avatar Brandon Invergo

Add make-finite-midi-control-abs-knob callback function.

parent 0e9804f6
......@@ -1227,6 +1227,7 @@ direction of rotation) (default: @samp{#f}).
@defun midi-control-abs-knob device input-event input-value alsa-ctl @
options
@defunx make-finite-midi-control-abs-knob
@defunx make-rel-to-abs-midi-control-knob [init-value]
Send a MIDI control event when a knob is changed. If @var{alsa-ctl}
is not @samp{#f} and its descriptor points to an open ctl, toggle the
......@@ -1239,6 +1240,11 @@ keyword arguments: @var{channel}, the MIDI channel (default: 0),
@var{control}, the MIDI control (default: @var{mod-wheel}); and
@var{knob-max}, the knob maximum value (default: 127)
@var{make-finite-midi-control-abs-knob} returns a callback function
that behaves like @var{midi-control-abs-knob}, however it prevents the
absolute position values from ``wrapping around'' when using an
infinite rotary knob.
@var{make-rel-to-abs-midi-control-knob} returns a callback function
that converts relative-position events to absolute-position events,
given the initial value @var{init-value} (default: 0). The callback
......
......@@ -41,6 +41,7 @@
system-rel-knob
make-abs-to-rel-system-knob
midi-control-abs-knob
make-finite-midi-control-abs-knob
make-rel-to-abs-midi-control-knob
midi-note-pad))
......@@ -534,8 +535,58 @@ Optional keyword arguments:
(when (eq? (car input-event) ev-abs)
(let* ((value (scale-value input-value knob-max 127)))
(send-midi-control device channel (midi:control->number control) value))
(when alsa-ctl
(set-ctl alsa-ctl #t)))))
(set-ctl alsa-ctl #t))))
(define* (make-finite-midi-control-abs-knob)
"Return a callback function that sends a MIDI control event when a
knob is changed. If ALSA-CTL is not #f and its descriptor points to
an open ctl, toggle the ctl (i.e. turn the LED on or off). This
procedure applies to \"infinite rotary\" knobs that generate absolute
position values that \"wrap around\" when they reach the
minimum/maximum value.
Optional keyword arguments:
#:channel -- MIDI channel (default: 0)
#:control -- MIDI control (default: 'mod-wheel)
#:knob-max -- knob maximum value (default: 127)
#:wrap-tol -- Relative-position tolerance before deciding that the absolute
position has wrapped on an \"infinite-rotary\"-style knob (i.e.
the physical knob has no start or end position and can be
rotated completely in either direction). Expressed as a
fraction of KNOB-MAX (default: 0.01)"
(let ((prev-raw-value #f)
(prev-clipped-value #f))
(lambda (device input-event input-value alsa-ctl options)
(let-keywords options #f ((channel 0)
(control 'mod-wheel)
(knob-max 127)
(wrap-tol 0.1))
(when (eq? (car input-event) ev-abs)
(if (not prev-raw-value)
(begin
(send-midi-control device channel
(midi:control->number control)
(scale-value input-value knob-max 127))
(set! prev-raw-value input-value)
(set! prev-clipped-value input-value)
(set-ctl alsa-ctl #t))
(let* ((raw-rel-value (- input-value prev-raw-value))
(rel-value (cond ((< (abs raw-rel-value) (* wrap-tol knob-max))
raw-rel-value)
((> raw-rel-value (* wrap-tol knob-max))
(- (+ prev-raw-value (- knob-max input-value))))
(#t
(+ input-value (- knob-max prev-raw-value)))))
(new-value (+ prev-clipped-value rel-value))
(clipped-value (cond ((< new-value 0) 0)
((> new-value knob-max) knob-max)
(#t new-value)))
(value (scale-value clipped-value knob-max 127)))
(send-midi-control device channel (midi:control->number control)
value)
(set! prev-raw-value input-value)
(set! prev-clipped-value clipped-value)
(set-ctl alsa-ctl #t))))))))
(define* (make-rel-to-abs-midi-control-knob #:optional (init-value 0))
"Return a callback function that sends a MIDI control event when a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment