summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/unheard/cycles.clj41
1 files changed, 39 insertions, 2 deletions
diff --git a/src/unheard/cycles.clj b/src/unheard/cycles.clj
index 5511d64..b134ad7 100644
--- a/src/unheard/cycles.clj
+++ b/src/unheard/cycles.clj
@@ -43,6 +43,22 @@
[& args]
{:v (vec args) :type :p})
+(defn rate
+ "Rate modifier: scales the speed of a pattern by a given ratio.
+
+ A ratio > 1 speeds up the pattern (fits more cycles in the same time).
+ A ratio < 1 slows down the pattern (stretches it over more time).
+ A ratio of 2 means the pattern runs twice as fast.
+ A ratio of 1/2 means the pattern runs at half speed.
+
+ Equivalent to TidalCycles/Strudel '*' and '/' operators.
+
+ Examples:
+ (rate 2 (l :a :b)) - runs the list twice as fast
+ (rate 1/2 (f :a :b :c)) - runs the fork at half speed"
+ [ratio node]
+ {:v node :rate ratio :type :rate})
+
(defn scalar? [x]
(not (and (map? x) (:type x))))
@@ -67,7 +83,12 @@
(= :p (:type node))
(let [children (:v node)]
- (reduce lcm 1 (map compute-cycle children)))))
+ (reduce lcm 1 (map compute-cycle children)))
+
+ (= :rate (:type node))
+ ;; Rate doesn't change the cycle count - it just compresses/expands time
+ ;; The parent sees the same cycle count as the child
+ (compute-cycle (:v node))))
(defn unfold-node [node start end iteration]
(let [duration (- end start)]
@@ -96,7 +117,23 @@
(let [children (:v node)]
(mapcat (fn [child]
(unfold-node child start end iteration))
- children)))))
+ children))
+
+ (= :rate (:type node))
+ (let [ratio (:rate node)
+ child (:v node)
+ child-base-cycle (compute-cycle child)
+ ;; rate scales how many times the base pattern repeats
+ ;; rate 2 means fit 2x cycles in this span
+ ;; rate 1/2 means fit 0.5x cycles (half a cycle)
+ num-child-cycles (* ratio child-base-cycle)
+ child-cycle-duration (/ duration num-child-cycles)]
+ (vec (mapcat (fn [i]
+ (unfold-node child
+ (+ start (* i child-cycle-duration))
+ (+ start (* (inc i) child-cycle-duration))
+ i))
+ (range num-child-cycles)))))))
(defn unfold
"Unfolds a pattern tree into concrete time intervals.