(ns scratch (:require [unheard.midi :as midi] [unheard.midi.percussion :refer [kick snare hat]] [unheard.clock :refer [clock]] [unheard.theory :refer [note poly]] [missionary.core :as m])) #_(print-all-midi-devices) (def midi-keyboard "CoreMIDI4J - Minilab3 MIDI") (defn song [>c >tonic] (poly (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))) ;; 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/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))] (if (= t :control) (m/amb (if (and (= ch 0) (= k 74)) (do (reset! c v) (m/amb)) (m/amb)) (if (and (= ch 0) (= k 71)) (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)