aboutsummaryrefslogtreecommitdiff
path: root/guile/starlet/midi-control/base.scm
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-02-25 22:35:16 +0100
committerThomas White <taw@physics.org>2021-02-25 22:40:20 +0100
commit33c05f33e4ca9928773a78ad150f252fc7fff8cc (patch)
tree652116b9b366bdec6d015f0b0572d4aba3f62487 /guile/starlet/midi-control/base.scm
parent624f6c780d4ea9963f10265a2f1a5b5e57a5bfb5 (diff)
Gracefully handle unavailable MIDI control device
Diffstat (limited to 'guile/starlet/midi-control/base.scm')
-rw-r--r--guile/starlet/midi-control/base.scm103
1 files changed, 63 insertions, 40 deletions
diff --git a/guile/starlet/midi-control/base.scm b/guile/starlet/midi-control/base.scm
index 8b882d8..64fcae7 100644
--- a/guile/starlet/midi-control/base.scm
+++ b/guile/starlet/midi-control/base.scm
@@ -2,6 +2,7 @@
#:use-module (oop goops)
#:use-module (ice-9 atomic)
#:use-module (ice-9 threads)
+ #:use-module (ice-9 exceptions)
#:use-module (ice-9 binary-ports)
#:use-module (srfi srfi-1)
#:export (start-midi-control
@@ -175,52 +176,74 @@
(define default-channel 0)
-(define* (start-midi-control device-name
- #:key (channel #f))
-
- (when channel
- (set! default-channel channel))
-
+(define (start-midi-control-real device-name channel)
(let ((midi-port (open-file device-name "r+0b")))
;; Read thread
(begin-thread
- (with-exception-handler
- (lambda (exn)
- (backtrace)
- (raise-exception exn))
- (lambda ()
- (let again ()
-
- (let* ((status-byte (get-u8 midi-port))
- (channel (bit-extract status-byte 0 4))
- (command (bit-extract status-byte 4 8)))
-
- (case command
-
- ;; Note on
- ((9) (let* ((note (get-u8 midi-port))
- (vel (get-u8 midi-port)))
- (check-note-callbacks channel note)))
-
- ;; Control value
- ((11) (let* ((cc-number (get-u8 midi-port))
- (value (get-u8 midi-port)))
- (handle-cc-change! channel
- cc-number
- value))))
-
- (yield)
- (again))))))
+ (with-exception-handler
+ (lambda (exn)
+ (backtrace)
+ (raise-exception exn))
+ (lambda ()
+ (let again ()
+
+ (let* ((status-byte (get-u8 midi-port))
+ (channel (bit-extract status-byte 0 4))
+ (command (bit-extract status-byte 4 8)))
+
+ (case command
+
+ ;; Note on
+ ((9) (let* ((note (get-u8 midi-port))
+ (vel (get-u8 midi-port)))
+ (check-note-callbacks channel note)))
+
+ ;; Control value
+ ((11) (let* ((cc-number (get-u8 midi-port))
+ (value (get-u8 midi-port)))
+ (handle-cc-change! channel
+ cc-number
+ value))))
+
+ (yield)
+ (again))))))
;; Write thread
(begin-thread
- (let again ()
- (let ((bytes-to-send (atomic-box-swap! send-queue '())))
- (for-each (lambda (a)
- (put-u8 midi-port a))
- bytes-to-send)
- (usleep 1000)
- (again))))
+ (let again ()
+ (let ((bytes-to-send (atomic-box-swap! send-queue '())))
+ (for-each (lambda (a)
+ (put-u8 midi-port a))
+ bytes-to-send)
+ (usleep 1000)
+ (again))))
(all-notes-off! default-channel)))
+
+
+(define (start-dummy-midi)
+ (display "Using dummy MIDI control\n")
+ (begin-thread
+ (let again ()
+ (let ((bytes-to-send (atomic-box-swap! send-queue '())))
+ (usleep 1000)
+ (again)))))
+
+(define* (start-midi-control device-name
+ #:key (channel #f))
+
+ (when channel
+ (set! default-channel channel))
+
+ (with-exception-handler
+
+ (lambda (exn)
+ (format #t "Couldn't start MIDI ~a\n"
+ (exception-irritants exn))
+ (start-dummy-midi))
+
+ (lambda ()
+ (start-midi-control-real device-name channel))
+
+ #:unwind? #t))