(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] (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)))))