From 945eb221209a6c3c00b2f0fcbbc7e19b343ee9d9 Mon Sep 17 00:00:00 2001 From: Jake Zerrer Date: Fri, 7 Nov 2025 15:42:03 -0500 Subject: Add new instrument --- src/unheard/instrument/util.clj | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/unheard/instrument/util.clj (limited to 'src/unheard/instrument/util.clj') 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))))) -- cgit v1.2.3