summaryrefslogtreecommitdiff
path: root/src/unheard/instrument/util.clj
blob: 7c99f8bd754e043fc9d17bb285ba9b89ecdbe0dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
(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)))))