summaryrefslogtreecommitdiff
path: root/dev/scratch.clj
blob: 9775320c6c3a53abb5b980994ed5d02355d0f44b (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
73
74
75
76
77
(ns scratch
  (:require [unheard.midi :as midi]
            [unheard.midi.percussion :refer [kick snare hat]]
            [unheard.instrument.minilab3 :as minilab3]
            [unheard.midi-util :as mu]
            [unheard.clock :refer [clock]]
            [unheard.theory :refer [note poly]]
            [missionary.core :as m]))

#_(print-all-midi-devices)

(def midi-keyboard  "CoreMIDI4J - Minilab3 MIDI")

(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
  [>c >tonic]
  (poly
   (triad >c >tonic)
   (triad >c (m/latest #(+ % 12) >tonic))

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

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

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

(def run
  (midi/<bus midi-keyboard
             (fn [v]
               (m/ap
                 ;; 2 is the number of message types, e.g. :key
                (let [[>c c] (clock)
                      tonic (atom 0)
                      >tonic (m/signal (m/watch tonic))
                      p (song >c >tonic)]
                  (m/amb=
                   (let [[t f] (m/?> 2 (midi/keyboard v))
                         [ch k v] (rest (m/?< f))
                         chkv [ch k v]]
                     (if (mu/control-message? t)
                       (m/amb
                        (if (minilab3/is-knob 1 chkv) 
                          (do (reset! c v) (m/amb))
                          (m/amb))
                        (if (minilab3/is-knob 2 chkv) 
                          (do (reset! tonic v) (m/amb))
                          (m/amb)))
                       (m/amb)))
                   [:n (m/?< (m/eduction (dedupe) p))]
                   [:c (m/?< (m/eduction (dedupe) >c))]))))))

(def cancel
  (run prn prn))

(cancel)