summaryrefslogtreecommitdiff
path: root/src/unheard/instrument/util.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/unheard/instrument/util.clj')
-rw-r--r--src/unheard/instrument/util.clj39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/unheard/instrument/util.clj b/src/unheard/instrument/util.clj
new file mode 100644
index 0000000..0faa5b5
--- /dev/null
+++ b/src/unheard/instrument/util.clj
@@ -0,0 +1,39 @@
+(ns unheard.instrument.util
+ (:require [missionary.core :as m])
+ (:import [javax.sound.midi ShortMessage]))
+
+(def matching-control-change
+ (filter (fn [^ShortMessage m] (= (.getCommand m) ShortMessage/CONTROL_CHANGE))))
+
+(defn matching-channel [ch]
+ (filter (fn [^ShortMessage m] (= (.getChannel m) ch))))
+
+(defn matching-data-1 [d1]
+ (filter (fn [^ShortMessage m] (= (.getData1 m) d1))))
+
+(def get-data-2
+ (map (fn [^ShortMessage m] (.getData2 m))))
+
+(defn matching-control
+ "Returns a function filtering flow of ShortMessage `f` down to control
+ change messages where channel is `ch` and data-1 is `k`, and then returning
+ a signal of values for data-2. Initial value of signal will be `init`.
+
+ Though a little esoteric sounding, this is actually quite useful.
+ The signal returned by this is useful for representing knobs, faders, and
+ pads on a midi controller.
+ "
+ [init ch k]
+ (fn [f]
+ ;; TODO: Should be signal
+ (m/stream
+ (m/reductions {} init
+ (m/eduction
+ (comp
+ matching-control-change
+ (matching-channel ch)
+ (matching-data-1 k)
+ get-data-2
+ ;; TODO git-bug f109911
+ (dedupe))
+ f)))))