summaryrefslogtreecommitdiff
path: root/dev/scratch.clj
blob: 53267f90b72d6ec669fab4b47b9c76196515eb3c (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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
(ns scratch
  (:require [unheard.midi :as midi]
            [unheard.midi.percussion :refer [kick snare hat]]
            [unheard.instrument.minilab3 :as minilab3]
            [unheard.instrument.omx-27 :as omx-27]
            [unheard.theory :refer [note poly]]
            [missionary.core :as m])
  (:import [javax.sound.midi ShortMessage]))

#_(print-all-midi-devices)

(defn triad [>c >tonic]
  (poly
   ;; This is a major cord,
   ;; held 32 32nd notes.
   ;; The tonic can vary.
   (note >c 0 32 >tonic)
   (note >c 0 32 (m/latest #(+ % 4) >tonic))
   (note >c 0 32 (m/latest #(+ % 7) >tonic))))

(defn song
  [{:keys [clock tonic]}]
  (poly
   (triad clock tonic)

   #_
   (triad clock (m/latest #(+ % 12) tonic))

   ;; The rest of the "song" is a drum pattern.
   (note clock 1 1 (m/ap kick))
   (note clock 9 1 (m/ap kick))
   (note clock 17 1 (m/ap kick))
   (note clock 25 1 (m/ap kick))

   (note clock 1 1 (m/ap hat))
   (note clock 5 1 (m/ap hat))
   (note clock 9 1 (m/ap hat))
   (note clock 13 1 (m/ap hat))
   (note clock 17 1 (m/ap hat))
   (note clock 21 1 (m/ap hat))
   (note clock 25 1 (m/ap hat))
   (note clock 29 1 (m/ap hat))

   (note clock 5 1 (m/ap snare))
   (note clock 13 1 (m/ap snare))
   (note clock 21 1 (m/ap snare))
   (note clock 29 1 (m/ap snare))))

;; TODO: Move into /dev
;; Add logging
(defn debug-flow [f]
  ((m/reduce prn nil
             (m/ap (m/?< f))) prn prn))

(def run
  (midi/<bus minilab3/device-name
             (fn [v]
               (m/signal
                (m/ap
                  ;; 2 is the number of message types, e.g. :key
                 (let [controls (midi/controller v minilab3/config)
                       clock (get-in controls [:knob 1])
                       tonic (get-in controls [:knob 2])
                       song-config {:clock clock
                                    :tonic tonic}
                       p (song song-config)]
                   (m/?< (m/latest vector clock p))))))))


(def cancel (run {} {}))

(cancel)