diff options
| author | Jake Zerrer <him@jakezerrer.com> | 2025-11-26 15:10:20 -0500 |
|---|---|---|
| committer | Jake Zerrer <him@jakezerrer.com> | 2025-12-02 11:43:03 -0500 |
| commit | 6f58e667587937948055194018e44338b2c38323 (patch) | |
| tree | 6319c35250d20fd7132f2348cf0a616bf4ab8439 | |
| parent | d9c4799bd25de09e0cea9fa9c4b384ae977c8cec (diff) | |
Create improved beat clock
WIP various changes
| -rw-r--r-- | src/unheard/clock.clj | 69 |
1 files changed, 16 insertions, 53 deletions
diff --git a/src/unheard/clock.clj b/src/unheard/clock.clj index 23da73e..d38b52a 100644 --- a/src/unheard/clock.clj +++ b/src/unheard/clock.clj @@ -51,6 +51,7 @@ (def cancel ((m/reduce prn nil >mono-clock) prn prn)) + (reset! mono-clock-freq 50) (reset! mono-clock-freq 10) (reset! mono-clock-freq 1) (cancel)) @@ -64,21 +65,25 @@ "Counts beats at `bpm`. Guaranteed not to lose or gain time." (m/signal (m/relieve - (let [init-beat 1] + (let [init-beat 0] (m/reductions {} init-beat (m/ap (let [state (object-array 2) - _ (aset state 0 (System/nanoTime)) - _ (aset state 1 init-beat) + last-beat-time-idx 0 + last-beat-number-idx 1 + _ (aset state last-beat-time-idx (System/nanoTime)) + _ (aset state last-beat-number-idx init-beat) [t bpm] (m/?< (m/latest vector >mono-clock >bpm)) - last-tick (aget state 0) - last-beat (aget state 1) - next-tick (+ last-tick (* 100000000000 (/ 1 bpm)))] - (if (< next-tick t) - (do (aset state 0 next-tick) - (aset state 1 (inc last-beat)) - (inc last-beat)) - (m/amb))))))))) + last-beat-time (aget state last-beat-time-idx) + next-beat-time (+ last-beat-time (* 1000000000 (/ 60 bpm))) + last-beat-number (aget state last-beat-number-idx) + t-since-beat-start (- t last-beat-time) + pct-through-current-beat (/ t-since-beat-start (- next-beat-time last-beat-time))] + (when (<= next-beat-time t) + ;; TODO confirm this won't lose or gain time + (aset state last-beat-time-idx next-beat-time) + (aset state last-beat-number-idx (inc last-beat-number))) + (+ last-beat-number pct-through-current-beat)))))))) (comment (def cancel @@ -89,45 +94,3 @@ (reset! mono-clock-freq 120) (reset! mono-clock-freq 1) (cancel)) - -(defonce numerator (atom 4)) -(defonce >numerator - (m/signal - (m/watch numerator))) - -(def >measure-clock - "Emits measure count. Increases at the end of the current measure. - Follows changes to numerator." - (m/signal - (m/relieve - (let [init-measure 1] - (m/reductions {} init-measure - (m/ap - (let [state (object-array 2) - last-measure-idx 0 - last-downbeat-idx 1 - _ (aset state last-measure-idx init-measure) - _ (aset state last-downbeat-idx init-measure) - [beat numerator] (m/?< (m/latest vector >beat-clock >numerator)) - last-measure (aget state last-measure-idx) - last-downbeat (aget state last-downbeat-idx) - next-downbeat (+ last-downbeat numerator)] - (if (<= next-downbeat beat) - (do (aset state last-measure-idx (inc last-measure)) - (aset state last-downbeat-idx next-downbeat) - (inc last-measure)) - (m/amb))))))))) - -(comment - (def cancel - ((m/reduce prn nil (m/latest vector >beat-clock >measure-clock)) prn prn)) - - (reset! mono-clock-freq 120) - (reset! bpm 120) - (reset! bpm -120) - (reset! bpm 160) - (reset! numerator 2) - (reset! numerator 3) - (reset! numerator 4) - - (cancel)) |
