1#![doc = include_str!("../README.md")]
2
3pub use bjorklund::{bjorklund, Bjorklund};
4pub use event_cache::EventCache;
5use num_rational::Rational64;
6pub use slice::SliceEvents;
7pub use span::Span;
8use std::{
9 fmt,
10 ops::{Add, Mul, Sub},
11 sync::Arc,
12};
13
14pub mod bjorklund;
15pub mod ctrl;
16mod event_cache;
17pub mod mini;
18pub mod slice;
19mod span;
20
21pub mod prelude {
22 pub use crate::{
23 atom,
24 ctrl::{self, note, sound, Controls},
25 euclid, euclid_bool, euclid_bool_dist, euclid_full, euclid_full_off, euclid_off,
26 euclid_off_bool, euclid_off_bool_dist, fastcat, fit_cycle, fit_span, indices, inner_join,
27 join, m, outer_join, saw, saw2, signal, silence, slowcat, span, stack, steady, timecat,
28 Pattern, Rational, Scalar, Span,
29 };
30}
31
32pub trait Pattern {
37 type Value;
39 type Events: Iterator<Item = Event<Self::Value>>;
41
42 fn query(&self, span: Span) -> Self::Events;
59
60 fn query_cycle(&self) -> Self::Events {
62 self.query(span!(0 / 1, 1 / 1))
63 }
64
65 fn into_dyn(self) -> DynPattern<Self::Value>
71 where
72 Self: 'static + Sized,
73 {
74 DynPattern::new(self)
75 }
76
77 fn filter<F>(self, predicate: F) -> impl Pattern<Value = Self::Value>
79 where
80 Self: Sized,
81 F: Fn(&Self::Value) -> bool,
82 {
83 let predicate = Arc::new(predicate);
84 move |span| {
85 let predicate = predicate.clone();
86 self.query(span).filter(move |ev| predicate(&ev.value))
87 }
88 }
89
90 fn filter_events<F>(self, predicate: F) -> impl Pattern<Value = Self::Value>
92 where
93 Self: Sized,
94 F: Fn(&Event<Self::Value>) -> bool,
95 {
96 let predicate = Arc::new(predicate);
97 move |span| {
98 let predicate = predicate.clone();
99 self.query(span).filter(move |ev| predicate(ev))
100 }
101 }
102
103 fn map<T, F>(self, map: F) -> MapValues<Self, F>
105 where
106 Self: Sized,
107 F: Fn(Self::Value) -> T,
108 {
109 let pattern = self;
110 let map = Arc::new(map);
111 MapValues { pattern, map }
112 }
113
114 fn map_query_points<F>(self, map: F) -> MapQueryPoints<Self, F>
116 where
117 Self: Sized,
118 F: Fn(Rational) -> Rational,
119 {
120 let pattern = self;
121 MapQueryPoints { pattern, map }
122 }
123
124 fn map_event_points<F>(self, map: F) -> MapEventPoints<Self, F>
127 where
128 Self: Sized,
129 F: Fn(Rational) -> Rational,
130 {
131 let pattern = self;
132 let map = Arc::new(map);
133 MapEventPoints { pattern, map }
134 }
135
136 fn map_event_lens<F>(self, map: F) -> impl Pattern<Value = Self::Value>
140 where
141 Self: Sized,
142 F: Fn(Rational) -> Rational,
143 {
144 self.map_events(move |ev| ev.map_len(&map))
145 }
146
147 fn map_events<F, T>(self, map: F) -> MapEvents<Self, F>
149 where
150 Self: Sized,
151 F: Fn(Event<Self::Value>) -> Event<T>,
152 {
153 let pattern = self;
154 let map = Arc::new(map);
155 MapEvents { pattern, map }
156 }
157
158 fn map_events_iter<E, F, T>(self, map: F) -> MapEventsIter<Self, F>
160 where
161 Self: Sized,
162 F: Fn(Self::Events) -> E,
163 E: Iterator<Item = Event<T>>,
164 {
165 let pattern = self;
166 MapEventsIter { pattern, map }
167 }
168
169 fn rate(self, rate: Rational) -> Rate<Self>
171 where
172 Self: Sized,
173 {
174 let pattern = self;
175 Rate { pattern, rate }
176 }
177
178 fn shift(self, amount: Rational) -> impl Pattern<Value = Self::Value>
180 where
181 Self: 'static + Sized,
182 {
183 self.map_query_points(move |t| t - amount)
184 .map_event_points(move |t| t + amount)
185 }
186
187 fn apply_with<P, F, B>(self, apply: P) -> impl Pattern<Value = B>
194 where
195 Self: 'static + Sized,
196 Self::Value: Clone,
197 P: 'static + Pattern<Value = F>,
198 F: Fn(ApplyEvent<Self::Value>) -> (B, Option<Span>),
199 {
200 let apply = Arc::new(apply);
201 move |span: Span| {
202 let apply = apply.clone();
203 self.query(span).flat_map(move |ev| {
204 apply.query(span).flat_map(move |ef| {
205 let ev = ev.clone();
206 ev.span.active.intersect(ef.span.active).map(|active| {
207 let new = ApplyEvent {
208 value: ev.value,
209 active,
210 left: EventSpan::new(ev.span.active, ev.span.whole),
211 right: EventSpan::new(ef.span.active, ef.span.whole),
212 };
213 let (value, whole) = (ef.value)(new);
214 Event::new(value, active, whole)
215 })
216 })
217 })
218 }
219 }
220
221 fn apply<P, F, G, B>(self, apply: P, structure: G) -> impl Pattern<Value = B>
229 where
230 Self: 'static + Sized,
231 Self::Value: Clone,
232 P: 'static + Pattern<Value = F>,
233 F: Fn(Self::Value) -> B,
234 G: 'static + Fn(Span, Span) -> Span,
235 {
236 let structure = Arc::new(structure);
237 let apply = apply.map(move |f| {
238 let structure = structure.clone();
239 move |e: ApplyEvent<_>| {
240 let value = f(e.value);
241 let whole = e
242 .left
243 .whole
244 .and_then(|lw| e.right.whole.map(|rw| (*structure)(lw, rw)));
245 (value, whole)
246 }
247 });
248 self.apply_with(apply)
249 }
250
251 fn app<P, F, B>(self, apply: P) -> impl Pattern<Value = B>
257 where
258 Self: 'static + Sized,
259 Self::Value: Clone,
260 P: 'static + Pattern<Value = F>,
261 F: Fn(Self::Value) -> B,
262 {
263 self.apply(apply, |l, r| {
264 l.intersect(r)
265 .expect("if `active` spans intersect, `whole` must too")
266 })
267 }
268
269 fn appl<P, F, B>(self, apply: P) -> impl Pattern<Value = B>
275 where
276 Self: 'static + Sized,
277 Self::Value: Clone,
278 P: 'static + Pattern<Value = F>,
279 F: Fn(Self::Value) -> B,
280 {
281 self.apply(apply, |l, _| l)
282 }
283
284 fn appr<P, F, B>(self, apply: P) -> impl Pattern<Value = B>
290 where
291 Self: 'static + Sized,
292 Self::Value: Clone,
293 P: 'static + Pattern<Value = F>,
294 F: Fn(Self::Value) -> B,
295 {
296 self.apply(apply, |_, r| r)
297 }
298
299 fn merge_with<P, F, T>(self, other: P, merge: F) -> impl Pattern<Value = T>
302 where
303 Self: 'static + Sized,
304 Self::Value: Clone,
305 P: 'static + Pattern,
306 P::Value: Clone,
307 F: 'static + Fn(Self::Value, P::Value) -> T,
308 {
309 let merge = Arc::new(merge);
310 let apply = other.map(move |o: P::Value| {
311 let f = merge.clone();
312 move |s: Self::Value| (*f)(s, o.clone())
313 });
314 self.app(apply)
315 }
316
317 fn merge_extend<P>(self, other: P) -> impl Pattern<Value = Self::Value>
323 where
324 Self: 'static + Sized,
325 Self::Value: Clone + Extend<<P::Value as IntoIterator>::Item>,
326 P: 'static + Pattern,
327 P::Value: Clone + IntoIterator,
328 {
329 self.merge_with(other, |mut s, o| {
330 s.extend(o);
331 s
332 })
333 }
334
335 fn polar(self) -> impl Pattern<Value = Self::Value>
337 where
338 Self: Sized,
339 Self::Value: Polar,
340 {
341 self.map(Polar::polar)
342 }
343
344 fn phase(self) -> impl Pattern<Value = [Rational; 2]>
347 where
348 Self: Sized,
349 {
350 self.map_events_iter(|evs| {
351 evs.filter_map(|ev| ev.span.active_phase().map(|phase| ev.map(|_| phase)))
352 })
353 }
354
355 fn debug_span(&self, span: Span) -> PatternDebug<Self::Value, Self::Events>
359 where
360 Self: Sized,
361 {
362 let pattern = self;
363 PatternDebug { pattern, span }
364 }
365
366 fn debug(&self) -> PatternDebug<Self::Value, Self::Events>
370 where
371 Self: Sized,
372 {
373 self.debug_span(span!(0 / 1, 1 / 1))
374 }
375}
376
377pub trait Sample {
381 type Value;
383 fn sample(&self, rational: Rational) -> Self::Value;
385}
386
387pub trait Polar:
389 Sized + One + Add<Output = Self> + Mul<Output = Self> + Sub<Output = Self>
390{
391 fn polar(self) -> Self {
394 self * (Self::ONE + Self::ONE) - Self::ONE
395 }
396}
397
398pub trait One {
400 const ONE: Self;
401}
402
403pub trait ToF64Lossy {
405 fn to_f64_lossy(self) -> f64;
407}
408
409pub type Rational = Rational64;
414pub type Scalar = i64;
416
417pub struct DynPattern<T>(Arc<dyn Pattern<Value = T, Events = BoxEvents<T>>>);
422
423pub struct BoxEvents<T>(Box<dyn Iterator<Item = Event<T>>>);
425
426pub struct PatternDebug<'p, V, E> {
428 pattern: &'p dyn Pattern<Value = V, Events = E>,
429 span: Span,
430}
431
432#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
434pub struct Event<T> {
435 pub span: EventSpan,
437 pub value: T,
439}
440
441#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
444pub struct ApplyEvent<T> {
445 pub left: EventSpan,
447 pub right: EventSpan,
449 pub active: Span,
451 pub value: T,
453}
454
455#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
457pub struct EventSpan {
458 pub whole: Option<Span>,
463 pub active: Span,
465}
466
467#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
469pub struct Signal<S>(S);
470
471#[derive(Debug)]
473pub struct MapEvents<P, F> {
474 pattern: P,
475 map: Arc<F>,
476}
477
478#[derive(Debug)]
480pub struct MapValues<P, F> {
481 pattern: P,
482 map: Arc<F>,
483}
484
485#[derive(Debug)]
487pub struct MapQueryPoints<P, F> {
488 pattern: P,
489 map: F,
490}
491
492#[derive(Debug)]
494pub struct MapEventPoints<P, F> {
495 pattern: P,
496 map: Arc<F>,
497}
498
499#[derive(Debug)]
501pub struct MapEventsIter<P, F> {
502 pattern: P,
503 map: F,
504}
505
506#[derive(Debug)]
508pub struct Rate<P> {
509 pattern: P,
510 rate: Rational,
511}
512
513#[derive(Debug)]
515pub struct EventsMap<I, F> {
516 events: I,
517 map: Arc<F>,
518}
519
520#[derive(Debug)]
522pub struct EventsMapValues<I, F> {
523 events: I,
524 map: Arc<F>,
525}
526
527#[derive(Debug)]
529pub struct EventsMapPoints<I, F> {
530 events: I,
531 map: Arc<F>,
532}
533
534#[derive(Debug)]
536pub struct EventsRate<I> {
537 events: I,
538 rate: Rational,
539}
540
541impl<T> Event<T> {
544 pub fn new(value: T, active: Span, whole: Option<Span>) -> Self {
545 let span = EventSpan::new(active, whole);
546 Self { span, value }
547 }
548
549 pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Event<U> {
550 let Event { span, value } = self;
551 let value = map(value);
552 Event::new(value, span.active, span.whole)
553 }
554
555 pub fn map_spans(self, map: impl Fn(Span) -> Span) -> Self {
556 let active = map(self.span.active);
557 let whole = self.span.whole.map(&map);
558 let value = self.value;
559 Self::new(value, active, whole)
560 }
561
562 pub fn map_points(self, map: impl Fn(Rational) -> Rational) -> Self {
563 self.map_spans(|span| span.map(&map))
564 }
565
566 pub fn map_len(self, map: impl Fn(Rational) -> Rational) -> Self {
567 self.map_spans(|s| s.map_len(&map))
568 }
569
570 pub fn by_ref(&self) -> Event<&T> {
571 Event::new(&self.value, self.span.active, self.span.whole)
572 }
573}
574
575impl<'a, T: Clone> Event<&'a T> {
576 pub fn cloned(self) -> Event<T> {
577 Event::new(self.value.clone(), self.span.active, self.span.whole)
578 }
579}
580
581impl EventSpan {
582 pub fn new(active: Span, whole: Option<Span>) -> Self {
583 EventSpan { active, whole }
584 }
585
586 pub fn intersect(self, other: Self) -> Option<Self> {
587 self.active.intersect(other.active).map(|active| {
588 let whole = self
589 .whole
590 .and_then(|sw| other.whole.and_then(|ow| sw.intersect(ow)));
591 Self { whole, active }
592 })
593 }
594
595 pub fn whole_or_active(&self) -> Span {
596 self.whole.unwrap_or(self.active)
597 }
598
599 pub fn active_phase(&self) -> Option<[Rational; 2]> {
601 let whole = self.whole?;
602 let active = self.active;
603 let lerp_whole = |r: Rational| (r - whole.start) / whole.len();
604 let start = lerp_whole(active.start);
605 let end = lerp_whole(active.end);
606 Some([start, end])
607 }
608}
609
610impl<T> BoxEvents<T> {
611 fn new<E>(es: E) -> Self
612 where
613 E: 'static + Iterator<Item = Event<T>>,
614 {
615 Self(Box::new(es) as Box<_>)
616 }
617}
618
619impl<T> DynPattern<T> {
620 fn new<P>(pattern: P) -> Self
621 where
622 P: 'static + Pattern<Value = T>,
623 T: 'static,
624 {
625 let arc = Arc::new(pattern.map_events_iter(BoxEvents::new))
626 as Arc<dyn Pattern<Value = T, Events = BoxEvents<T>>>;
627 DynPattern(arc)
628 }
629}
630
631impl<F, I, T> Pattern for F
634where
635 F: Fn(Span) -> I,
636 I: Iterator<Item = Event<T>>,
637{
638 type Value = T;
639 type Events = I;
640 fn query(&self, span: Span) -> Self::Events {
641 (*self)(span)
642 }
643}
644
645impl<T> Pattern for DynPattern<T> {
646 type Value = T;
647 type Events = BoxEvents<T>;
648 fn query(&self, span: Span) -> Self::Events {
649 self.0.query(span)
650 }
651}
652
653impl<S: Sample> Pattern for Signal<S> {
654 type Value = S::Value;
655 type Events = std::iter::Once<Event<Self::Value>>;
656 fn query(&self, active @ Span { start, end }: Span) -> Self::Events {
657 let Signal(s) = self;
658 let value = s.sample(start + ((end - start) / 2));
659 let whole = None;
660 let event = Event::new(value, active, whole);
661 std::iter::once(event)
662 }
663}
664
665impl<P, F, T> Pattern for MapValues<P, F>
666where
667 P: Pattern,
668 F: Fn(P::Value) -> T,
669{
670 type Value = T;
671 type Events = EventsMapValues<P::Events, F>;
672 fn query(&self, span: Span) -> Self::Events {
673 let Self { pattern, map } = self;
674 let events = pattern.query(span);
675 let map = map.clone();
676 EventsMapValues { events, map }
677 }
678}
679
680impl<P, F> Pattern for MapQueryPoints<P, F>
681where
682 P: Pattern,
683 F: Fn(Rational) -> Rational,
684{
685 type Value = P::Value;
686 type Events = P::Events;
687 fn query(&self, span: Span) -> Self::Events {
688 let span = span.map(&self.map);
689 self.pattern.query(span)
690 }
691}
692
693impl<P, F> Pattern for MapEventPoints<P, F>
694where
695 P: Pattern,
696 F: Fn(Rational) -> Rational,
697{
698 type Value = P::Value;
699 type Events = EventsMapPoints<P::Events, F>;
700 fn query(&self, span: Span) -> Self::Events {
701 let Self { pattern, map } = self;
702 let events = pattern.query(span);
703 let map = map.clone();
704 EventsMapPoints { events, map }
705 }
706}
707
708impl<P, F, T> Pattern for MapEvents<P, F>
709where
710 P: Pattern,
711 F: Fn(Event<P::Value>) -> Event<T>,
712{
713 type Value = T;
714 type Events = EventsMap<P::Events, F>;
715 fn query(&self, span: Span) -> Self::Events {
716 let events = self.pattern.query(span);
717 let map = self.map.clone();
718 EventsMap { events, map }
719 }
720}
721
722impl<P, F, E, T> Pattern for MapEventsIter<P, F>
723where
724 P: Pattern,
725 F: Fn(P::Events) -> E,
726 E: Iterator<Item = Event<T>>,
727{
728 type Value = T;
729 type Events = E;
730 fn query(&self, span: Span) -> Self::Events {
731 let Self { pattern, map } = self;
732 let events = pattern.query(span);
733 map(events)
734 }
735}
736
737impl<P> Pattern for Rate<P>
738where
739 P: Pattern,
740{
741 type Value = P::Value;
742 type Events = EventsRate<P::Events>;
743 fn query(&self, span: Span) -> Self::Events {
744 let Self { ref pattern, rate } = *self;
745 let span = span.map(|p| p * rate);
746 let events = pattern.query(span);
747 EventsRate { events, rate }
748 }
749}
750
751impl<I, F, T, U> Iterator for EventsMap<I, F>
752where
753 I: Iterator<Item = Event<T>>,
754 F: Fn(Event<T>) -> Event<U>,
755{
756 type Item = Event<U>;
757 fn next(&mut self) -> Option<Self::Item> {
758 self.events.next().map(&*self.map)
759 }
760}
761
762impl<I, F, T, U> Iterator for EventsMapValues<I, F>
763where
764 I: Iterator<Item = Event<T>>,
765 F: Fn(T) -> U,
766{
767 type Item = Event<U>;
768 fn next(&mut self) -> Option<Self::Item> {
769 self.events.next().map(|ev| ev.map(&*self.map))
770 }
771}
772
773impl<I, F, T> Iterator for EventsMapPoints<I, F>
774where
775 I: Iterator<Item = Event<T>>,
776 F: Fn(Rational) -> Rational,
777{
778 type Item = Event<T>;
779 fn next(&mut self) -> Option<Self::Item> {
780 self.events.next().map(|ev| ev.map_points(&*self.map))
781 }
782}
783
784impl<I, T> Iterator for EventsRate<I>
785where
786 I: Iterator<Item = Event<T>>,
787{
788 type Item = Event<T>;
789 fn next(&mut self) -> Option<Self::Item> {
790 if self.rate == Rational::from(0) {
791 return None;
792 }
793 self.events
794 .next()
795 .map(|ev| ev.map_points(|p| p / self.rate))
796 }
797}
798
799impl<T> Iterator for BoxEvents<T> {
800 type Item = Event<T>;
801 fn next(&mut self) -> Option<Self::Item> {
802 self.0.next()
803 }
804}
805
806impl<F, T> Sample for F
807where
808 F: Fn(Rational) -> T,
809{
810 type Value = T;
811 fn sample(&self, r: Rational) -> Self::Value {
812 (*self)(r)
813 }
814}
815
816impl<T> Polar for T where T: One + Add<Output = Self> + Mul<Output = Self> + Sub<Output = Self> {}
817
818impl One for Rational {
819 const ONE: Self = Rational::new_raw(1, 1);
820}
821
822impl Ord for EventSpan {
823 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
824 self.whole_or_active().cmp(&other.whole_or_active())
825 }
826}
827
828impl PartialOrd for EventSpan {
829 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
830 Some(self.cmp(other))
831 }
832}
833
834impl<T> Clone for DynPattern<T> {
835 fn clone(&self) -> Self {
836 Self(self.0.clone())
837 }
838}
839
840impl ToF64Lossy for Rational {
841 fn to_f64_lossy(self) -> f64 {
842 *self.numer() as f64 / *self.denom() as f64
843 }
844}
845
846impl<T> fmt::Debug for Event<T>
847where
848 T: fmt::Debug,
849{
850 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
851 let mut d = f.debug_struct("Event");
852 if let Some(whole) = self.span.whole {
853 d.field("whole", &whole);
854 }
855 d.field("active", &self.span.active)
856 .field("value", &self.value)
857 .finish()
858 }
859}
860
861impl<'p, V, E> fmt::Debug for PatternDebug<'p, V, E>
862where
863 E: Iterator<Item = Event<V>>,
864 V: fmt::Debug,
865{
866 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
867 let events = self.pattern.query(self.span);
868 f.debug_list().entries(events).finish()
869 }
870}
871
872impl<'p, V> fmt::Debug for DynPattern<V>
873where
874 V: fmt::Debug,
875{
876 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
877 self.debug().fmt(f)
878 }
879}
880
881pub fn signal<S: Sample>(sample: S) -> impl Pattern<Value = S::Value> {
885 Signal(sample)
886}
887
888pub fn steady<T: Clone>(t: T) -> impl Pattern<Value = T> {
891 signal(move |_| t.clone())
892}
893
894pub fn silence<T>() -> impl Pattern<Value = T> {
897 |_| std::iter::empty()
898}
899
900pub fn atom<T: Clone>(t: T) -> impl Pattern<Value = T> {
903 move |span: Span| {
904 let t = t.clone();
905 span.cycles().map(move |active| {
906 let start = active.start.floor();
907 let end = start + 1;
908 let whole = Some(Span { start, end });
909 let value = t.clone();
910 Event::new(value, active, whole)
911 })
912 }
913}
914
915pub fn saw() -> impl Pattern<Value = Rational> {
917 signal(|r: Rational| r - r.floor())
918}
919
920pub fn saw2() -> impl Pattern<Value = Rational> {
922 saw().polar()
923}
924
925pub fn indices() -> impl Pattern<Value = Scalar> {
927 atom(()).map_events(|ev| ev.map(|_| ev.span.active.start.to_integer()))
928}
929
930pub fn slowcat<I>(patterns: I) -> impl Pattern<Value = <I::Item as Pattern>::Value>
934where
935 I: IntoIterator,
936 I::Item: Pattern,
937{
938 let patterns: Arc<[I::Item]> = patterns.into_iter().collect();
939 move |span: Span| {
940 let ps = patterns.clone();
941 span.cycles().flat_map(move |cycle| {
942 let sam = cycle.start.floor();
943 let ps_len = Scalar::try_from(ps.len()).expect("failed to cast usize to Scalar");
944 let ixr = rem_euclid(sam, Rational::from(ps_len));
945 let ix = usize::try_from(ixr.to_integer()).expect("failed to cast index to usize");
946 let p = &ps[ix];
947 p.query(cycle)
948 })
949 }
950}
951
952pub fn fastcat<I>(patterns: I) -> impl Pattern<Value = <I::Item as Pattern>::Value>
955where
956 I: IntoIterator,
957 I::Item: Pattern,
958 I::IntoIter: ExactSizeIterator,
959{
960 let patterns = patterns.into_iter();
961 let n = Scalar::try_from(patterns.len()).expect("pattern count out of range");
962 let rate = Rational::from_integer(n);
963 slowcat(patterns).rate(rate)
964}
965
966pub fn timecat<I, P>(patterns: I) -> impl Pattern<Value = P::Value>
969where
970 I: IntoIterator<Item = (Rational, P)>,
971 I::IntoIter: ExactSizeIterator,
972 P: Pattern,
973{
974 let mut total_ratio = Rational::default();
976 let patterns: Vec<(Rational, P)> = patterns
977 .into_iter()
978 .inspect(|(r, _)| total_ratio += r)
979 .collect();
980 let mut start = Rational::default();
982 let patterns: Arc<[(Span, P)]> = patterns
983 .into_iter()
984 .map(|(r, p)| {
985 let len = r / total_ratio;
986 let end = start + len;
987 let span = Span::new(start, end);
988 start = end;
989 (span, p)
990 })
991 .collect();
992 move |span: Span| {
994 let ps = patterns.clone();
995 span.cycles().flat_map(move |cycle| {
996 let sam = cycle.start.floor();
997 let ps = ps.clone();
998 (0..ps.len())
999 .filter_map(move |i| {
1000 let (p_span, pattern) = &ps[i];
1001 let p_span = p_span.map(|r| r + sam);
1002 cycle.intersect(p_span).map(|sect| {
1003 pattern.query(sect).map(move |mut ev| {
1004 ev.span.whole = Some(p_span);
1005 ev
1006 })
1007 })
1008 })
1009 .flatten()
1010 })
1011 }
1012}
1013
1014pub fn stack<I>(patterns: I) -> impl Pattern<Value = <I::Item as Pattern>::Value>
1018where
1019 I: IntoIterator,
1020 I::Item: Pattern,
1021{
1022 let patterns: Arc<[I::Item]> = patterns.into_iter().collect();
1023 move |span: Span| {
1024 let ps = patterns.clone();
1025 (0..ps.len()).flat_map(move |ix| ps[ix].query(span))
1026 }
1027}
1028
1029pub fn join<P: Pattern>(pp: impl Pattern<Value = P>) -> impl Pattern<Value = P::Value> {
1037 move |span: Span| {
1038 pp.query(span).flat_map(move |o_ev: Event<P>| {
1039 o_ev.value.query(o_ev.span.active).filter_map(move |i_ev| {
1040 o_ev.span.intersect(i_ev.span).map(|span| {
1041 let value = i_ev.value;
1042 Event { span, value }
1043 })
1044 })
1045 })
1046 }
1047}
1048
1049pub fn inner_join<P: Pattern>(pp: impl Pattern<Value = P>) -> impl Pattern<Value = P::Value> {
1051 move |q_span: Span| {
1052 pp.query(q_span).flat_map(move |o_ev: Event<P>| {
1053 o_ev.value.query(o_ev.span.active).filter_map(move |i_ev| {
1054 let whole = i_ev.span.whole;
1055 q_span.intersect(i_ev.span.active).map(|active| {
1056 let span = EventSpan { whole, active };
1057 let value = i_ev.value;
1058 Event { span, value }
1059 })
1060 })
1061 })
1062 }
1063}
1064
1065pub fn outer_join<P: Pattern>(pp: impl Pattern<Value = P>) -> impl Pattern<Value = P::Value> {
1067 move |q_span: Span| {
1068 pp.query(q_span).flat_map(move |o_ev: Event<P>| {
1069 let i_q_span = Span::instant(o_ev.span.whole_or_active().start);
1070 o_ev.value.query(i_q_span).filter_map(move |i_ev| {
1071 let whole = o_ev.span.whole;
1072 q_span.intersect(o_ev.span.active).map(|active| {
1073 let span = EventSpan { whole, active };
1074 let value = i_ev.value;
1075 Event { span, value }
1076 })
1077 })
1078 })
1079 }
1080}
1081
1082pub fn fit_span<T>(
1085 src: Span,
1086 dst: Span,
1087 p: impl 'static + Pattern<Value = T>,
1088) -> impl Pattern<Value = T> {
1089 let rate = src.len() / dst.len();
1091 let rate_adjusted = p.rate(rate);
1092 let new_src = src.map(|r| r * rate);
1094 let amount = dst.start - new_src.start;
1096 let shifted = rate_adjusted.shift(amount);
1097 shifted
1098}
1099
1100pub fn fit_cycle<T>(dst: Span, p: impl 'static + Pattern<Value = T>) -> impl Pattern<Value = T> {
1102 fit_span(span!(0 / 1, 1 / 1), dst, p)
1103}
1104
1105fn rem_euclid(r: Rational, d: Rational) -> Rational {
1106 r - (d * (r / d).floor())
1107}
1108
1109pub fn euclid(k: usize, n: usize) -> impl Pattern {
1113 filter_euclid(euclid_bool(k, n))
1114}
1115
1116pub fn euclid_full(k: usize, n: usize) -> impl Pattern {
1119 filter_euclid_full(euclid_bool_dist(k, n))
1120}
1121
1122pub fn euclid_off(k: usize, n: usize, off: isize) -> impl Pattern {
1125 filter_euclid(euclid_off_bool(k, n, off))
1126}
1127
1128pub fn euclid_full_off(k: usize, n: usize, off: isize) -> impl Pattern {
1131 filter_euclid_full(euclid_off_bool_dist(k, n, off))
1132}
1133
1134pub fn euclid_bool(k: usize, n: usize) -> impl Pattern<Value = bool> {
1137 fastcat(bjorklund(k, n).map(atom))
1138}
1139
1140pub fn euclid_bool_dist(k: usize, n: usize) -> impl Pattern<Value = (bool, usize)> {
1145 let bs: Vec<_> = bjorklund(k, n).collect();
1146 let distances = bjorklund::distances(bs.clone());
1147 fastcat(bs.into_iter().zip(distances).map(atom))
1148}
1149
1150pub fn euclid_off_bool(k: usize, n: usize, off: isize) -> impl Pattern<Value = bool> {
1153 let ni = isize::try_from(n).unwrap();
1154 let off: usize = off.rem_euclid(ni).try_into().unwrap();
1155 let bs: Vec<_> = bjorklund(k, n).collect();
1156 let bs: Vec<_> = bjorklund::offset(bs, off).collect();
1157 fastcat(bs.into_iter().map(atom))
1158}
1159
1160pub fn euclid_off_bool_dist(k: usize, n: usize, off: isize) -> impl Pattern<Value = (bool, usize)> {
1163 let ni = isize::try_from(n).unwrap();
1164 let off: usize = off.rem_euclid(ni).try_into().unwrap();
1165 let bs: Vec<_> = bjorklund(k, n).collect();
1166 let bs: Vec<_> = bjorklund::offset(bs, off).collect();
1167 let distances = bjorklund::distances(bs.clone());
1168 fastcat(bs.into_iter().zip(distances).map(atom))
1169}
1170
1171fn filter_euclid(p: impl Pattern<Value = bool>) -> impl Pattern {
1174 move |span| p.query(span).filter(|ev| ev.value)
1175}
1176
1177fn filter_euclid_full(p: impl Pattern<Value = (bool, usize)>) -> impl Pattern {
1181 move |span| {
1182 p.query(span).filter_map(|ev| {
1183 let (b, n) = ev.value;
1184 if !b {
1185 return None;
1186 }
1187 let r = Rational::new(n.try_into().unwrap(), 1);
1188 Some(ev.map_len(|len| len * r))
1189 })
1190 }
1191}
1192
1193#[test]
1196fn test_rem_euclid() {
1197 let d = Rational::from(5);
1199 for i in (0..10).map(Rational::from) {
1200 assert_eq!(rem_euclid(i, d), i % d);
1201 }
1202
1203 let d = Rational::from(3);
1205 let test = (-9..=0).rev().map(Rational::from);
1206 let expected = [0, 2, 1].into_iter().cycle().map(Rational::from);
1207 for (a, b) in test.zip(expected) {
1208 dbg!(a, rem_euclid(a, d));
1209 assert_eq!(rem_euclid(a, d), b);
1210 }
1211
1212 let d = Rational::new(1, 2);
1214 let test = (0..10).map(|i| Rational::new(i, 10));
1215 let expected = (0..5).cycle().map(|i| Rational::new(i, 10));
1216 for (a, b) in test.zip(expected) {
1217 assert_eq!(rem_euclid(a, d), b);
1218 }
1219}
1220
1221#[test]
1222fn test_shift() {
1223 let a = || m![bd ~ bd ~];
1224 let b = || m![~ bd ~ bd];
1225 assert_eq!(
1226 a().shift((1, 4).into()).query_cycle().collect::<Vec<_>>(),
1227 b().query_cycle().collect::<Vec<_>>(),
1228 );
1229 assert_eq!(
1230 a().shift((5, 4).into()).query_cycle().collect::<Vec<_>>(),
1231 b().query_cycle().collect::<Vec<_>>(),
1232 );
1233 assert_eq!(
1234 a().query_cycle().collect::<Vec<_>>(),
1235 b().shift((-1, 4).into()).query_cycle().collect::<Vec<_>>(),
1236 );
1237 assert_eq!(
1238 a().query_cycle().collect::<Vec<_>>(),
1239 b().shift((-3, 4).into()).query_cycle().collect::<Vec<_>>(),
1240 );
1241 assert_eq!(
1242 a().shift((1, 8).into()).query_cycle().collect::<Vec<_>>(),
1243 b().shift((-1, 8).into()).query_cycle().collect::<Vec<_>>(),
1244 );
1245 assert!(
1246 a().shift((1, 8).into()).query_cycle().collect::<Vec<_>>()
1247 != b().query_cycle().collect::<Vec<_>>()
1248 );
1249}
1250
1251#[test]
1252fn test_join() {
1253 let pp = |active @ whole| std::iter::once(Event::new(m![1.0 1.0], active, Some(whole)));
1254 let p = join(pp);
1255 let mut q = p.query(span!(0 / 1, 2 / 1));
1256 let q0 = span!(0 / 1, 1 / 2);
1257 let q1 = span!(1 / 2, 1 / 1);
1258 let q2 = span!(1 / 1, 3 / 2);
1259 let q3 = span!(3 / 2, 2 / 1);
1260 assert_eq!(q.next(), Some(Event::new(1.0, q0, Some(q0))));
1261 assert_eq!(q.next(), Some(Event::new(1.0, q1, Some(q1))));
1262 assert_eq!(q.next(), Some(Event::new(1.0, q2, Some(q2))));
1263 assert_eq!(q.next(), Some(Event::new(1.0, q3, Some(q3))));
1264 assert_eq!(q.next(), None);
1265}
1266
1267#[test]
1268fn test_merge_extend() {
1269 let p = ctrl::sound(atom("hello")).merge_extend(ctrl::note(atom(4.0)));
1270 dbg!(p.debug_span(span!(0 / 1, 4 / 1)));
1271 let mut cycle = p.query(span!(0 / 1, 1 / 1));
1272 let mut expected = std::collections::BTreeMap::new();
1273 expected.insert(ctrl::SOUND.to_string(), ctrl::Value::String("hello".into()));
1274 expected.insert(ctrl::NOTE.to_string(), ctrl::Value::F64(4.0));
1275 assert_eq!(cycle.next().unwrap().value, expected);
1276 assert_eq!(cycle.next(), None);
1277}
1278
1279#[test]
1280fn test_apply() {
1281 let a = atom(1.0).rate(2.into());
1282 let b = atom(|v| v + 2.0).rate(3.into());
1283 let p = a.app(b);
1284 let v: Vec<_> = p.query(span!(0 / 1, 1 / 1)).collect();
1285 let s0 = span!(0 / 1, 1 / 3);
1292 let s1 = span!(1 / 3, 1 / 2);
1293 let s2 = span!(1 / 2, 2 / 3);
1294 let s3 = span!(2 / 3, 1 / 1);
1295 assert_eq!(v[0], Event::new(3.0, s0, Some(s0)));
1296 assert_eq!(v[1], Event::new(3.0, s1, Some(s1)));
1297 assert_eq!(v[2], Event::new(3.0, s2, Some(s2)));
1298 assert_eq!(v[3], Event::new(3.0, s3, Some(s3)));
1299 assert_eq!(v.len(), 4);
1300}
1301
1302#[test]
1303fn test_rate() {
1304 let p = atom("hello");
1305 let mut q = p.query(span!(0 / 1, 1 / 1));
1307 assert!(q.next().is_some());
1308 assert!(q.next().is_none());
1309 let p = p.rate(Rational::new(2, 1));
1311 let mut q = p.query(span!(0 / 1, 1 / 1));
1312 assert!(q.next().is_some());
1313 assert!(q.next().is_some());
1314 assert!(q.next().is_none());
1315 let p = p.rate(Rational::new(1, 4));
1317 let mut q = p.query(span!(0 / 1, 2 / 1));
1318 assert!(q.next().is_some());
1319 assert!(q.next().is_none());
1320}
1321
1322#[test]
1323fn test_slowcat() {
1324 let a = atom("a");
1325 let b = atom("b");
1326 let cat = slowcat([a.into_dyn(), b.into_dyn()]);
1327 let span = span!(0 / 1, 5 / 2);
1328 let mut es = cat
1329 .query(span)
1330 .map(|ev| (ev.value, ev.span.active, ev.span.whole));
1331 assert_eq!(
1332 Some(("a", span!(0 / 1, 1 / 1), Some(span!(0 / 1, 1 / 1)))),
1333 es.next()
1334 );
1335 assert_eq!(
1336 Some(("b", span!(1 / 1, 2 / 1), Some(span!(1 / 1, 2 / 1)))),
1337 es.next()
1338 );
1339 assert_eq!(
1340 Some(("a", span!(2 / 1, 5 / 2), Some(span!(2 / 1, 3 / 1)))),
1341 es.next()
1342 );
1343 assert_eq!(None, es.next());
1344}
1345
1346#[test]
1347fn test_fastcat() {
1348 let a = atom("a");
1349 let b = atom("b");
1350 let cat = fastcat([a.into_dyn(), b.into_dyn()]);
1351 let span = span!(0 / 1, 5 / 4);
1352 let mut es = cat
1353 .query(span)
1354 .map(|ev| (ev.value, ev.span.active, ev.span.whole));
1355 assert_eq!(
1356 Some(("a", span!(0 / 1, 1 / 2), Some(span!(0 / 1, 1 / 2)))),
1357 es.next()
1358 );
1359 assert_eq!(
1360 Some(("b", span!(1 / 2, 1 / 1), Some(span!(1 / 2, 1 / 1)))),
1361 es.next()
1362 );
1363 assert_eq!(
1364 Some(("a", span!(1 / 1, 5 / 4), Some(span!(1 / 1, 3 / 2)))),
1365 es.next()
1366 );
1367 assert_eq!(None, es.next());
1368}
1369
1370#[test]
1371fn test_timecat() {
1372 let a = atom("a");
1373 let b = atom("b");
1374 let cat = timecat([(Rational::from(1), a), (Rational::from(2), b)]);
1375 let span = span!(1 / 4, 3 / 2);
1376 dbg!(cat.debug_span(span));
1377 let mut es = cat
1378 .query(span)
1379 .map(|ev| (ev.value, ev.span.active, ev.span.whole));
1380 assert_eq!(
1381 es.next(),
1382 Some(("a", span!(1 / 4, 1 / 3), Some(span!(0 / 1, 1 / 3)))),
1383 );
1384 assert_eq!(
1385 es.next(),
1386 Some(("b", span!(1 / 3, 1 / 1), Some(span!(1 / 3, 1 / 1)))),
1387 );
1388 assert_eq!(
1389 es.next(),
1390 Some(("a", span!(1 / 1, 4 / 3), Some(span!(1 / 1, 4 / 3)))),
1391 );
1392 assert_eq!(
1393 es.next(),
1394 Some(("b", span!(4 / 3, 3 / 2), Some(span!(4 / 3, 2 / 1)))),
1395 );
1396 assert_eq!(es.next(), None);
1397}
1398
1399#[test]
1400fn test_span_cycles() {
1401 let span = span!(0 / 1, 3 / 1);
1402 assert_eq!(span.cycles().count(), 3);
1403}
1404
1405#[test]
1406fn test_saw() {
1407 let max = 10;
1408 for n in 0..=max {
1409 let r = Rational::new(n, max);
1410 let i = span!(r);
1411 let v1 = saw().query(i).map(|ev| ev.value).next().unwrap();
1412 let v2 = saw2().query(i).map(|ev| ev.value).next().unwrap();
1413 println!("{}: v1={}, v2={}", r, v1, v2);
1414 }
1415
1416 let p = saw();
1417 let a = span!(1 / 2);
1418 let b = span!(-1 / 2);
1419 assert_eq!(
1420 p.query(a).next().unwrap().value,
1421 p.query(b).next().unwrap().value
1422 );
1423
1424 let a = span!(1 / 4);
1425 let b = span!(-3 / 4);
1426 assert_eq!(
1427 p.query(a).next().unwrap().value,
1428 p.query(b).next().unwrap().value
1429 );
1430}
1431
1432#[test]
1433fn test_dyn_pattern() {
1434 let _patterns: Vec<DynPattern<_>> = vec![
1435 saw().into_dyn(),
1436 saw2().into_dyn(),
1437 silence().into_dyn(),
1438 steady(Rational::new(1, 1)).into_dyn(),
1439 atom(Rational::new(0, 1)).into_dyn(),
1440 ];
1441}
1442
1443#[test]
1444fn test_steady() {
1445 let max = 10;
1446 for n in 0..=max {
1447 let i = span!(Rational::new(n, max));
1448 let v = steady("hello").query(i).map(|ev| ev.value).next().unwrap();
1449 assert_eq!(v, "hello");
1450 }
1451}
1452
1453#[test]
1454fn test_silence() {
1455 let max = 10;
1456 for n in 0..=max {
1457 let i = span!(Rational::new(n, max));
1458 assert!(silence::<Rational>().query(i).next().is_none());
1459 }
1460}
1461
1462#[test]
1463fn test_pattern_reuse() {
1464 let saw_ = saw();
1465 let max = 10;
1466 for n in 0..=max {
1467 let i = span!(Rational::new(n, max));
1468 let ev1 = saw_.query(i).next().unwrap();
1469 let ev2 = saw().query(i).next().unwrap();
1470 assert_eq!(ev1, ev2);
1471 }
1472}
1473
1474#[test]
1475fn test_atom() {
1476 let span = span!(0 / 1, 3 / 1);
1477 let pattern = atom("hello");
1478 let mut values = pattern.query(span).map(|ev| ev.value);
1479 assert_eq!(Some("hello"), values.next());
1480 assert_eq!(Some("hello"), values.next());
1481 assert_eq!(Some("hello"), values.next());
1482 assert_eq!(None, values.next());
1483}
1484
1485#[test]
1486fn test_atom_whole() {
1487 let span = span!(0 / 1, 7 / 2);
1488 let pattern = atom("hello");
1489 let mut events = pattern.query(span);
1490 {
1491 let mut values = events.by_ref().map(|ev| ev.value);
1492 assert_eq!(Some("hello"), values.next());
1493 assert_eq!(Some("hello"), values.next());
1494 assert_eq!(Some("hello"), values.next());
1495 }
1496 let event = events.next().unwrap();
1497 let active = span!(3 / 1, 7 / 2);
1498 let whole = Some(span!(3 / 1, 4 / 1));
1499 assert_eq!(active, event.span.active);
1500 assert_eq!(whole, event.span.whole);
1501 assert_eq!(None, events.next());
1502}
1503
1504#[test]
1505fn test_debug() {
1506 let p = atom("hello");
1507 println!("{:?}", p.debug());
1508 println!("{:?}", p.debug_span(span!(2 / 1, 7 / 2)));
1509}
1510
1511#[test]
1512fn test_fit_span() {
1513 let p = || atom("a");
1514 let src = span!(0 / 1, 1 / 1);
1515 let dst = span!(1 / 2, 3 / 4);
1516 let pfs = fit_span(src, dst, p());
1517 let mut es = pfs
1518 .query(dst)
1519 .map(|ev| (ev.value, ev.span.active, ev.span.whole));
1520 assert_eq!(
1521 es.next(),
1522 Some(("a", span!(1 / 2, 3 / 4), Some(span!(1 / 2, 3 / 4)))),
1523 );
1524 assert!(es.next().is_none());
1525 let pfc = fit_cycle(dst, p());
1526 let pfs_es = pfs.query(span!(0 / 1, 4 / 1));
1527 let pfc_es = pfc.query(span!(0 / 1, 4 / 1));
1528 assert_eq!(pfs_es.collect::<Vec<_>>(), pfc_es.collect::<Vec<_>>());
1529}
1530
1531#[test]
1532fn test_phase() {
1533 let p = atom(()).phase();
1534 let span = span!(1 / 4, 3 / 4);
1535 let mut es = p.query(span).map(|ev| ev.value);
1536 assert_eq!(es.next(), Some([Rational::new(1, 4), Rational::new(3, 4)]));
1537 assert!(es.next().is_none());
1538 let span = span!(1 / 8, 3 / 2);
1539 let mut es = p.query(span).map(|ev| ev.value);
1540 assert_eq!(es.next(), Some([Rational::new(1, 8), Rational::new(1, 1)]));
1541 assert_eq!(es.next(), Some([Rational::new(0, 1), Rational::new(1, 2)]));
1542 assert!(es.next().is_none());
1543}