diff options
| author | Jake Zerrer <him@jakezerrer.com> | 2025-10-16 19:43:42 -0400 |
|---|---|---|
| committer | Jake Zerrer <him@jakezerrer.com> | 2025-10-17 19:24:11 -0400 |
| commit | 4ff62448f9adbb75e79f528ca4528e0faf4399a3 (patch) | |
| tree | afcb1bcc5961197b8e4775a215bb445867fdece4 /src/main.clj | |
| parent | a36b60a8ee2a293d0c9783cbe59da2a8d9c1b195 (diff) | |
Improve poly; pass clock as argument
Diffstat (limited to 'src/main.clj')
| -rw-r--r-- | src/main.clj | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/src/main.clj b/src/main.clj index 74982ed..57eedad 100644 --- a/src/main.clj +++ b/src/main.clj @@ -2,7 +2,8 @@ (:require [missionary.core :as m] [clojure.set :refer [difference union]] [portal :refer [>portal-main rec show-portal hide-portal +cap -cap cap]] - [notation :refer [melody]])) + [notation :as notation] + [example-song :refer [melody]])) ;; How many times per second are output continuous values sampled and turned ;; into events? @@ -56,9 +57,10 @@ :tick (recur))))) -(def output +(defn output "Convert the continuous time >notes-on flow to a series of discrete midi note on and off events." + [composition] (m/eduction (comp (remove #(= (select-keys % [:note-on :note-off]) {:note-on #{} :note-off #{}})) (dedupe)) @@ -74,19 +76,20 @@ ;; but not at all if nothing has changed (m/sample vector - melody + composition clock)))) -(def process-midi-toggle-events +(defn process-midi-toggle-events "Listen for changes on midi-enabled? When playback is disabled, send a note-off event for each active note and then zero out notes-on." + [composition] (m/ap (let [local-midi-enabled? (atom nil) local-active (atom #{}) [tag value] (m/amb= [:midi-enabled? (m/?< >midi-enabled?)] - [:note-event (m/?< output)])] + [:note-event (m/?< (output composition))])] (case tag :midi-enabled? (let [midi-enabled? value @@ -110,10 +113,11 @@ (defonce engine (atom nil)) -(def set->midi-events +(defn set->midi-events "Convert set representation of notes to midi events" + [composition] (m/ap - (let [{:keys [note-on note-off]} (m/?< process-midi-toggle-events)] + (let [{:keys [note-on note-off]} (m/?< (process-midi-toggle-events composition))] (m/amb= (loop [notes note-on] (if (first notes) @@ -126,17 +130,18 @@ (recur (rest notes))) (m/amb))))))) -(def main - (m/ap (m/amb= (m/?< (rec :root set->midi-events)) +(defn main + [composition] + (m/ap (m/amb= (m/?< (rec :root (set->midi-events composition))) (m/?< >portal-main)))) (defn start-engine "Start playback engine." - [] + [composition] (when (not @engine) (reset! engine (do (enable-midi) - ((m/reduce {} {} main) {} {}))))) + ((m/reduce {} {} (main composition)) {} {}))))) (defn stop-engine "Stop playback engine." @@ -147,14 +152,17 @@ (reset! engine nil))) (comment - (start-engine) - - (cap) - + (let [[>clock set-clock] (notation/clock)] + (def >clock >clock) + (def set-clock set-clock)) (+cap :root :notes-set) + (start-engine (melody >clock)) + (set-clock 0) (show-portal) + (cap) + (play-notes 1 2 3 4 5) (stop-notes 4 5) |
