(ns unheard.theory (:require [missionary.core :as m] [clojure.set :refer [union]])) (defn note [>clock start duration >value] (m/cp (let [[c v] (m/?< (m/latest vector >clock >value))] (if (<= start c (dec (+ start duration))) #{v} #{})))) (defn poly [& notes] (m/signal (m/cp (apply union (m/?< (apply m/latest vector notes)))))) ;; TODO: Group could actually wrap note, rather than using explicitly ;; WIll introduce a lot of GC churn, though (defn group [clock start end content] (m/cp (let [content (m/signal content)] (if (m/?< (m/latest #(<= start % end) clock)) (m/?< content) (m/amb #{}))))) ;; TODO: ;; - Note literals turn into numbers ;; - Represent keyboard as byte array of shorts ;; - play a note increments, stop a note decrements ;; - Multiple instruments ;; - Mapping inputs to vars ;; - Inputs get declared at the top of a track ;; - Devices get mapped to declared inputs ;; - Notion of scenes that change mapping of inputs to vars ;; - Loops