diff options
| author | Jake Zerrer <him@jakezerrer.com> | 2025-11-26 09:02:27 -0500 |
|---|---|---|
| committer | Jake Zerrer <him@jakezerrer.com> | 2025-11-26 13:10:08 -0500 |
| commit | 076288da762787ae2874204c5212df8571ff4564 (patch) | |
| tree | bf5bbcd5cdb2f38288683fd03817ab2172c87ac9 /src/unheard/interval.clj | |
| parent | 0b6ceecd47cc1faf715419914c77f68a5d789727 (diff) | |
Have claude create RatioValueInterval
Diffstat (limited to 'src/unheard/interval.clj')
| -rw-r--r-- | src/unheard/interval.clj | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/unheard/interval.clj b/src/unheard/interval.clj new file mode 100644 index 0000000..2ec5645 --- /dev/null +++ b/src/unheard/interval.clj @@ -0,0 +1,88 @@ +(ns unheard.interval + "Custom IInterval implementation for Clojure ratios with arbitrary values." + (:import [com.brein.time.timeintervals.intervals IInterval] + [com.brein.time.timeintervals.collections ListIntervalCollection])) + +(deftype RatioValueInterval [start end value] + IInterval + (getNormStart [_] start) + (getNormEnd [_] end) + (getUniqueIdentifier [_] (str "[" start "," end "]")) + (compareTo [_ other] + (let [start-cmp (compare start (.getNormStart ^RatioValueInterval other))] + (if (zero? start-cmp) + (compare end (.getNormEnd ^RatioValueInterval other)) + start-cmp))) + Object + (toString [_] (str "[" start ", " end "] -> " value))) + +;; Public API + +(defn ratio-interval + "Create a RatioValueInterval with ratio boundaries and arbitrary value. + + Args: + start - Clojure ratio for interval start (inclusive) + end - Clojure ratio for interval end (inclusive) + value - Arbitrary data to associate with interval + + Returns: + Instance of RatioValueInterval implementing IInterval<Ratio> + + Example: + (ratio-interval 1/4 3/4 {:note :C :velocity 64})" + [start end value] + (->RatioValueInterval start end value)) + +(defn interval-value + "Get the value associated with a RatioValueInterval. + + Args: + interval - A RatioValueInterval instance + + Returns: + The value stored in the interval" + [^RatioValueInterval interval] + (.value interval)) + +(defn overlaps? + "Check if two intervals overlap. + + Two intervals [a,b] and [c,d] overlap if max(a,c) <= min(b,d)" + [^RatioValueInterval iv1 ^RatioValueInterval iv2] + (let [start1 (.getNormStart iv1) + end1 (.getNormEnd iv1) + start2 (.getNormStart iv2) + end2 (.getNormEnd iv2)] + (<= (max (compare start1 start2)) (min (compare end1 end2))))) + +(defn find-overlaps + "Find all intervals in a collection that overlap with the query interval. + + Args: + coll - A collection of intervals (any Iterable) + query - The interval to query for overlaps + + Returns: + A sequence of intervals that overlap with the query" + [coll ^RatioValueInterval query] + (let [q-start (.getNormStart query) + q-end (.getNormEnd query)] + (filter (fn [^RatioValueInterval iv] + (let [start (.getNormStart iv) + end (.getNormEnd iv)] + ;; Intervals overlap if: start <= q-end AND end >= q-start + (and (<= (compare start q-end) 0) + (>= (compare end q-start) 0)))) + coll))) + +(defn create-ratio-interval-collection + "Create a simple ListIntervalCollection for RatioValueInterval instances. + + This uses a simple list-based collection. Use find-overlaps to query for + overlapping intervals. + + Returns: + Configured IntervalCollection ready to accept ratio-interval instances" + [] + (ListIntervalCollection.)) |
