(ns main (:require [missionary.core :as m] [clojure.set :refer [difference]])) ;; How many times per second are output continuous values sampled and turned ;; into events? (def sample-rate (atom 1)) ;; Temporary atom to explore the concept of note state as a continuous value (def notes-on (atom #{})) (def >notes-on (m/signal (m/watch notes-on))) (defn play-note [v] (swap! notes-on conj v)) (defn stop-note [v] (swap! notes-on disj v)) (def clock (m/ap (loop [] (m/amb (m/? (m/sleep (/ 1000 @sample-rate))) :tick (recur))))) #_(play-note 1) #_(stop-note 1) ;; convert the continuous time >notes-on flow to a series of discrete midi note on and off events (def output (m/eduction (map (fn [{:keys [note-on note-off]}] {:note-on note-on :note-off note-off})) (m/reductions (fn [{:keys [active note-on note-off]} [curr _]] {:note-on (difference (difference curr active) note-on) :note-off (difference (difference active curr) note-off) :active curr}) #{} (m/sample vector >notes-on clock)))) (def cancel ((m/reduce prn output) {} {})) (cancel)