summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Zerrer <him@jakezerrer.com>2025-11-05 16:45:22 -0500
committerJake Zerrer <him@jakezerrer.com>2025-11-06 10:46:22 -0500
commitbee77914483da25831093e0475e4a71f1383253b (patch)
treeb0969c3a0fe2b2c9472534eb7a9c0f8912584648
parent2a4fce4fef775f6661a625303de9b28b446f1877 (diff)
Keyboard in a decent state
-rw-r--r--src/midi.clj67
-rw-r--r--src/scratch.clj11
2 files changed, 44 insertions, 34 deletions
diff --git a/src/midi.clj b/src/midi.clj
index 330402b..8e56b08 100644
--- a/src/midi.clj
+++ b/src/midi.clj
@@ -229,14 +229,13 @@
[>messages]
(m/eduction (filter #(instance? ShortMessage %)) >messages))
-(defn |channels
+(defn |group-by-channel
[>messages]
(m/group-by #(.getChannel ^ShortMessage %) >messages))
(defn |group-by-data-1
[>messages]
- (m/group-by #(.getData1 ^ShortMessage %)
- >messages))
+ (m/group-by #(.getData1 ^ShortMessage %) >messages))
(defn |matching-commands
[>messages commands]
@@ -253,34 +252,38 @@
(defn keyboard
[f]
- (m/ap
- (let [[ch ch-messages]
- (m/?> 128 (midi/|channels (midi/|short-messages (m/stream f))))
- ch-messages (m/stream ch-messages)]
- (m/amb=
- (let [[note note-messages]
- (m/?> 128 (-> ch-messages
- (midi/|matching-commands note-commands)
- (midi/|group-by-data-1)))]
- [:key ch note
- (m/?<
- (m/relieve
- (m/reductions
- (fn [_prev curr]
- (when (some? curr)
- (let [cmd (.getCommand ^ShortMessage curr)]
- (cond
- (= cmd ShortMessage/NOTE_ON)
- (.getData2 ^ShortMessage curr)
- (= cmd ShortMessage/POLY_PRESSURE)
- (.getData2 ^ShortMessage curr)
- (= cmd ShortMessage/NOTE_OFF)
- nil)))) nil note-messages)))])
- (let [[control-number control-messages]
- (m/?> 128 (-> ch-messages
- (midi/|matching-commands control-commands)
- (midi/|group-by-data-1)))]
- [:control ch control-number (.getData2 ^ShortMessage (m/?< control-messages))])))))
+ (m/relieve
+ (m/group-by
+ first
+ (m/ap
+ (let [[ch ch-messages]
+ (m/?> 128 (midi/|group-by-channel (midi/|short-messages (m/stream f))))
+ ch-messages (m/stream ch-messages)]
+ (m/amb=
+ (let [[note note-messages]
+ (m/?> 128 (-> ch-messages
+ (midi/|matching-commands note-commands)
+ (midi/|group-by-data-1)))]
+ ;; TODO: Where to relieve in here?
+ [:key ch note
+ (m/?<
+ (m/reductions
+ (fn [_prev curr]
+ (when (some? curr)
+ (let [cmd (.getCommand ^ShortMessage curr)]
+ (cond
+ (= cmd ShortMessage/NOTE_ON)
+ (.getData2 ^ShortMessage curr)
+ (= cmd ShortMessage/POLY_PRESSURE)
+ (.getData2 ^ShortMessage curr)
+ (= cmd ShortMessage/NOTE_OFF)
+ nil)))) nil note-messages))])
+
+ (let [[control-number control-messages]
+ (m/?> 128 (-> ch-messages
+ (midi/|matching-commands control-commands)
+ (midi/|group-by-data-1)))]
+ [:control ch control-number (.getData2 ^ShortMessage (m/?< control-messages))])))))))
#_(defn >ch-stream [>device ch]
(m/cp (m/?< (second (get >device ch)))))
@@ -297,7 +300,7 @@
;; is a midi channel number and val is a signal of sets representing active
;; notes on that channel.
;;
-;; Create a nother function, `(send-to-bus bus-name sigs)`. `bus-name` is the
+;; Create another function, `(send-to-bus bus-name sigs)`. `bus-name` is the
;; name of a midi bus on this machine. If a bus with that name exists, it will
;; start reading note values from `sigs`.
;;
diff --git a/src/scratch.clj b/src/scratch.clj
index 80baa83..ed2d464 100644
--- a/src/scratch.clj
+++ b/src/scratch.clj
@@ -1,5 +1,5 @@
(ns scratch
- (:require [midi :refer [print-all-midi-devices >bus <bus] :as midi]
+ (:require [midi :as midi]
[missionary.core :as m]))
#_(print-all-midi-devices)
@@ -7,10 +7,17 @@
(def midi-keyboard "CoreMIDI4J - Minilab3 MIDI")
(def run
- (midi/<bus midi-keyboard midi/keyboard))
+ (midi/<bus midi-keyboard
+ (fn [v]
+ (m/ap
+ ;; 2 is the number of message types, e.g. :key
+ (let [[t f] (m/?> 2 (midi/keyboard v))]
+ [t (rest (m/?< f))])))))
+#_
(def cancel
(run prn prn))
+#_
(cancel)