1use crate::{
20 chord::Chord, defaults::FloatType, duration::Duration, error::Result, interval::Interval,
21 key::KeySignature, meter::TimeSignature, note::Note, pitch::Pitch, rest::Rest,
22 tempo::MetronomeMark,
23};
24
25#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub enum StreamKind {
32 #[default]
34 Stream,
35 Voice,
37 Measure,
39 Part,
41 PartStaff,
43 Score,
45 Opus,
47}
48
49impl StreamKind {
50 pub const ALL: [StreamKind; 7] = [
52 StreamKind::Stream,
53 StreamKind::Voice,
54 StreamKind::Measure,
55 StreamKind::Part,
56 StreamKind::PartStaff,
57 StreamKind::Score,
58 StreamKind::Opus,
59 ];
60
61 pub fn as_str(self) -> &'static str {
63 match self {
64 StreamKind::Stream => "Stream",
65 StreamKind::Voice => "Voice",
66 StreamKind::Measure => "Measure",
67 StreamKind::Part => "Part",
68 StreamKind::PartStaff => "PartStaff",
69 StreamKind::Score => "Score",
70 StreamKind::Opus => "Opus",
71 }
72 }
73}
74
75impl std::fmt::Display for StreamKind {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 f.write_str(self.as_str())
78 }
79}
80
81#[derive(Clone, Debug)]
83#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
84pub enum StreamElement {
85 Note(Note),
87 Chord(Chord),
89 Rest(Rest),
91 Stream(Box<Stream>),
94 KeySignature(KeySignature),
96 TimeSignature(TimeSignature),
98 MetronomeMark(MetronomeMark),
100}
101
102impl StreamElement {
103 pub fn duration(&self) -> Option<&Duration> {
108 match self {
109 Self::Note(note) => note.duration(),
110 Self::Chord(chord) => chord.duration(),
111 Self::Rest(rest) => Some(rest.duration()),
112 Self::Stream(_)
113 | Self::KeySignature(_)
114 | Self::TimeSignature(_)
115 | Self::MetronomeMark(_) => None,
116 }
117 }
118
119 pub fn quarter_length(&self) -> FloatType {
125 match self {
126 Self::Stream(stream) => stream.end_offset(),
127 Self::KeySignature(_) | Self::TimeSignature(_) | Self::MetronomeMark(_) => 0.0,
128 _ => self
129 .duration()
130 .map(Duration::quarter_length)
131 .unwrap_or_else(|| Duration::default().quarter_length()),
132 }
133 }
134
135 pub fn pitches(&self) -> Vec<Pitch> {
138 match self {
139 Self::Note(note) => vec![note.pitch().clone()],
140 Self::Chord(chord) => chord.pitches(),
141 Self::Stream(stream) => stream.pitches(),
142 Self::Rest(_)
143 | Self::KeySignature(_)
144 | Self::TimeSignature(_)
145 | Self::MetronomeMark(_) => Vec::new(),
146 }
147 }
148
149 pub fn as_stream(&self) -> Option<&Stream> {
151 match self {
152 Self::Stream(stream) => Some(stream),
153 _ => None,
154 }
155 }
156
157 pub fn is_note_or_chord(&self) -> bool {
160 matches!(self, Self::Note(_) | Self::Chord(_))
161 }
162
163 pub fn transpose(&self, interval: &Interval) -> Result<Self> {
168 match self {
169 Self::Note(note) => {
170 let mut out = note.clone();
171 out.set_pitch(interval.transpose_pitch(note.pitch())?);
172 Ok(Self::Note(out))
173 }
174 Self::Chord(chord) => Ok(Self::Chord(chord.transpose(interval)?)),
175 Self::Rest(rest) => Ok(Self::Rest(rest.clone())),
176 Self::Stream(stream) => Ok(Self::Stream(Box::new(stream.transpose(interval)?))),
177 Self::KeySignature(key) => Ok(Self::KeySignature(key.transpose(interval)?)),
178 Self::TimeSignature(meter) => Ok(Self::TimeSignature(meter.clone())),
179 Self::MetronomeMark(mark) => Ok(Self::MetronomeMark(mark.clone())),
180 }
181 }
182}
183
184impl From<Note> for StreamElement {
185 fn from(value: Note) -> Self {
186 Self::Note(value)
187 }
188}
189
190impl From<Chord> for StreamElement {
191 fn from(value: Chord) -> Self {
192 Self::Chord(value)
193 }
194}
195
196impl From<Rest> for StreamElement {
197 fn from(value: Rest) -> Self {
198 Self::Rest(value)
199 }
200}
201
202impl From<Stream> for StreamElement {
203 fn from(value: Stream) -> Self {
204 Self::Stream(Box::new(value))
205 }
206}
207
208impl From<KeySignature> for StreamElement {
209 fn from(value: KeySignature) -> Self {
210 Self::KeySignature(value)
211 }
212}
213
214impl From<TimeSignature> for StreamElement {
215 fn from(value: TimeSignature) -> Self {
216 Self::TimeSignature(value)
217 }
218}
219
220impl From<MetronomeMark> for StreamElement {
221 fn from(value: MetronomeMark) -> Self {
222 Self::MetronomeMark(value)
223 }
224}
225
226#[derive(Clone, Debug)]
228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
229pub struct StreamEvent {
230 offset: FloatType,
231 element: StreamElement,
232}
233
234impl StreamEvent {
235 pub fn new(offset: FloatType, element: impl Into<StreamElement>) -> Self {
237 Self {
238 offset,
239 element: element.into(),
240 }
241 }
242
243 pub fn offset(&self) -> FloatType {
245 self.offset
246 }
247
248 pub fn element_mut(&mut self) -> &mut StreamElement {
250 &mut self.element
251 }
252
253 pub fn element(&self) -> &StreamElement {
255 &self.element
256 }
257
258 pub fn end_offset(&self) -> FloatType {
260 self.offset + self.element.quarter_length()
261 }
262}
263
264#[derive(Clone, Debug, Default)]
266#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
267#[must_use]
268pub struct Stream {
269 #[cfg_attr(feature = "serde", serde(default))]
270 kind: StreamKind,
271 events: Vec<StreamEvent>,
272}
273
274impl Stream {
275 pub fn new() -> Self {
277 Self::default()
278 }
279
280 pub fn with_kind(kind: StreamKind) -> Self {
282 Self {
283 kind,
284 events: Vec::new(),
285 }
286 }
287
288 pub fn kind(&self) -> StreamKind {
290 self.kind
291 }
292
293 pub fn set_kind(&mut self, kind: StreamKind) {
295 self.kind = kind;
296 }
297
298 pub fn from_events(events: impl IntoIterator<Item = StreamEvent>) -> Self {
300 let mut stream = Self {
301 kind: StreamKind::Stream,
302 events: events.into_iter().collect(),
303 };
304 stream.sort_events();
305 stream
306 }
307
308 pub fn insert(&mut self, offset: FloatType, element: impl Into<StreamElement>) {
310 self.events.push(StreamEvent::new(offset, element));
311 self.sort_events();
312 }
313
314 pub fn push(&mut self, element: impl Into<StreamElement>) {
316 let element = element.into();
317 let offset = self.end_offset();
318 self.events.push(StreamEvent::new(offset, element));
319 }
320
321 pub fn events_mut(&mut self) -> &mut [StreamEvent] {
323 &mut self.events
324 }
325
326 pub fn events(&self) -> &[StreamEvent] {
328 &self.events
329 }
330
331 pub fn iter(&self) -> impl Iterator<Item = &StreamEvent> {
333 self.events.iter()
334 }
335
336 pub fn len(&self) -> usize {
339 self.events.len()
340 }
341
342 pub fn is_empty(&self) -> bool {
344 self.events.is_empty()
345 }
346
347 pub fn flatten(&self) -> Self {
353 let mut flattened = Self::with_kind(self.kind);
354 self.flatten_into(0.0, &mut flattened.events);
355 flattened.sort_events();
356 flattened
357 }
358
359 fn flatten_into(&self, base: FloatType, out: &mut Vec<StreamEvent>) {
360 for event in &self.events {
361 let offset = base + event.offset;
362 match &event.element {
363 StreamElement::Stream(stream) => stream.flatten_into(offset, out),
364 element => out.push(StreamEvent::new(offset, element.clone())),
365 }
366 }
367 }
368
369 pub fn recurse(&self) -> Vec<(FloatType, &StreamElement)> {
372 let mut out = Vec::new();
373 self.recurse_into(0.0, &mut out);
374 out
375 }
376
377 fn recurse_into<'a>(&'a self, base: FloatType, out: &mut Vec<(FloatType, &'a StreamElement)>) {
378 for event in &self.events {
379 let offset = base + event.offset;
380 out.push((offset, &event.element));
381 if let StreamElement::Stream(stream) = &event.element {
382 stream.recurse_into(offset, out);
383 }
384 }
385 }
386
387 pub fn streams_of_kind(&self, kind: StreamKind) -> Vec<&Stream> {
390 self.events
391 .iter()
392 .filter_map(|event| event.element.as_stream())
393 .filter(|stream| stream.kind == kind)
394 .collect()
395 }
396
397 pub fn parts(&self) -> Vec<&Stream> {
399 self.streams_of_kind(StreamKind::Part)
400 }
401
402 pub fn measures(&self) -> Vec<&Stream> {
404 self.streams_of_kind(StreamKind::Measure)
405 }
406
407 pub fn voices(&self) -> Vec<&Stream> {
409 self.streams_of_kind(StreamKind::Voice)
410 }
411
412 pub fn notes(&self) -> Vec<(FloatType, StreamElement)> {
415 self.flatten()
416 .events
417 .into_iter()
418 .filter(|event| event.element.is_note_or_chord())
419 .map(|event| (event.offset, event.element))
420 .collect()
421 }
422
423 pub fn end_offset(&self) -> FloatType {
426 self.events
427 .iter()
428 .map(StreamEvent::end_offset)
429 .fold(0.0, FloatType::max)
430 }
431
432 pub fn pitches(&self) -> Vec<Pitch> {
434 self.flatten()
435 .events
436 .iter()
437 .flat_map(|event| event.element.pitches())
438 .collect()
439 }
440
441 pub fn key_signature_at(&self, offset: FloatType) -> Option<KeySignature> {
448 self.in_force_at(offset, |element| match element {
449 StreamElement::KeySignature(key) => Some(key.clone()),
450 _ => None,
451 })
452 }
453
454 pub fn time_signature_at(&self, offset: FloatType) -> Option<TimeSignature> {
456 self.in_force_at(offset, |element| match element {
457 StreamElement::TimeSignature(meter) => Some(meter.clone()),
458 _ => None,
459 })
460 }
461
462 pub fn metronome_mark_at(&self, offset: FloatType) -> Option<MetronomeMark> {
464 self.in_force_at(offset, |element| match element {
465 StreamElement::MetronomeMark(mark) => Some(mark.clone()),
466 _ => None,
467 })
468 }
469
470 fn in_force_at<T>(
472 &self,
473 offset: FloatType,
474 read: impl Fn(&StreamElement) -> Option<T>,
475 ) -> Option<T> {
476 self.flatten()
477 .events
478 .iter()
479 .take_while(|event| event.offset <= offset)
480 .filter_map(|event| read(&event.element))
481 .last()
482 }
483
484 pub fn transpose(&self, interval: &Interval) -> Result<Self> {
486 let events = self
487 .events
488 .iter()
489 .map(|event| {
490 Ok(StreamEvent::new(
491 event.offset,
492 event.element.transpose(interval)?,
493 ))
494 })
495 .collect::<Result<Vec<_>>>()?;
496 let mut out = Self::with_kind(self.kind);
497 out.events = events;
498 out.sort_events();
499 Ok(out)
500 }
501
502 fn sort_events(&mut self) {
503 self.events.sort_by(|left, right| {
504 left.offset
505 .partial_cmp(&right.offset)
506 .unwrap_or(std::cmp::Ordering::Equal)
507 });
508 }
509}
510
511impl<'a> IntoIterator for &'a Stream {
512 type Item = &'a StreamEvent;
513 type IntoIter = std::slice::Iter<'a, StreamEvent>;
514
515 fn into_iter(self) -> Self::IntoIter {
516 self.events.iter()
517 }
518}
519
520#[cfg(test)]
521mod tests {
522 #[test]
523 fn a_stream_says_what_kind_it_is_and_walks_its_events() {
524 use super::{Stream, StreamElement, StreamEvent, StreamKind};
525 use crate::note::Note;
526 use crate::pitch::Pitch;
527 use crate::tempo::MetronomeMark;
528
529 assert_eq!(StreamKind::Voice.as_str(), "Voice");
530 assert_eq!(StreamKind::Voice.to_string(), "Voice");
531 let mut stream = Stream::new();
532 assert!(stream.is_empty());
533 stream.set_kind(StreamKind::Voice);
534 assert_eq!(stream.kind(), StreamKind::Voice);
535 assert!(matches!(
536 StreamElement::from(MetronomeMark::new(120.0)),
537 StreamElement::MetronomeMark(_)
538 ));
539
540 let note = Note::from_pitch(Pitch::from_name("C4").unwrap());
541 let rebuilt = Stream::from_events([StreamEvent::new(0.0, note)]);
542 assert_eq!(rebuilt.iter().count(), 1);
543 assert!(!rebuilt.is_empty());
544 assert!(rebuilt.voices().is_empty());
545 let mut outer = Stream::new();
546 outer.push(stream);
547 assert_eq!(outer.voices().len(), 1);
548 }
549
550 use super::*;
551
552 #[test]
553 fn a_stream_iterates_by_reference() {
554 let mut stream = Stream::new();
555 stream.push(Note::from_name("C4").unwrap());
556 stream.push(Note::from_name("E4").unwrap());
557
558 let offsets: Vec<FloatType> = (&stream).into_iter().map(StreamEvent::offset).collect();
559 assert_eq!(offsets, vec![0.0, 1.0]);
560 assert_eq!((&stream).into_iter().count(), stream.len());
561 }
562
563 #[test]
564 fn stream_push_uses_durations() {
565 let mut stream = Stream::new();
566 stream.push(
567 Note::from_name("C4")
568 .unwrap()
569 .with_duration(Duration::half()),
570 );
571 stream.push(Rest::from_quarter_length(0.5).unwrap());
572 assert_eq!(stream.events()[0].offset(), 0.0);
573 assert_eq!(stream.events()[1].offset(), 2.0);
574 assert_eq!(stream.end_offset(), 2.5);
575 }
576
577 #[test]
578 fn stream_transposes_notes_and_chords() {
579 let mut stream = Stream::new();
580 stream.push(Note::from_name("C4").unwrap());
581 stream.push(Chord::new("E4 G4").unwrap());
582 let out = stream
583 .transpose(&Interval::from_name("M2").unwrap())
584 .unwrap();
585 let names = out
586 .pitches()
587 .iter()
588 .map(Pitch::name_with_octave)
589 .collect::<Vec<_>>();
590 assert_eq!(names, vec!["D4", "F#4", "A4"]);
591 }
592
593 fn two_measure_score() -> Stream {
596 let mut first = Stream::with_kind(StreamKind::Measure);
597 first.insert(0.0, KeySignature::new(2));
598 first.insert(0.0, TimeSignature::new(4, 4).unwrap());
599 first.push(Note::from_name("D4").unwrap());
600 first.push(Note::from_name("E4").unwrap());
601 first.push(Note::from_name("F#4").unwrap());
602 first.push(Note::from_name("G4").unwrap());
603
604 let mut second = Stream::with_kind(StreamKind::Measure);
605 second.insert(0.0, KeySignature::new(-1));
606 second.push(Note::from_name("A4").unwrap());
607 second.push(Note::from_name("B-4").unwrap());
608
609 let mut part = Stream::with_kind(StreamKind::Part);
610 part.push(first);
611 part.push(second);
612
613 let mut score = Stream::with_kind(StreamKind::Score);
614 score.push(part);
615 score
616 }
617
618 #[test]
619 fn a_nested_stream_flattens_onto_one_timeline() {
620 let score = two_measure_score();
621 assert_eq!(score.kind(), StreamKind::Score);
622 assert_eq!(score.len(), 1, "a score holds its one part, not its notes");
623 assert_eq!(score.parts().len(), 1);
624 assert_eq!(score.parts()[0].measures().len(), 2);
625
626 let notes = score.notes();
628 let offsets: Vec<FloatType> = notes.iter().map(|(offset, _)| *offset).collect();
629 assert_eq!(offsets, vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
630 assert_eq!(score.end_offset(), 6.0);
631
632 let names: Vec<String> = score
633 .pitches()
634 .iter()
635 .map(Pitch::name_with_octave)
636 .collect();
637 assert_eq!(names, ["D4", "E4", "F#4", "G4", "A4", "B-4"]);
638
639 assert_eq!(score.recurse().len(), 1 + 2 + 6 + 3);
641 assert_eq!(score.flatten().len(), 6 + 3);
642 }
643
644 #[test]
645 fn the_key_in_force_is_the_last_one_written_before_it() {
646 let score = two_measure_score();
647 assert_eq!(score.key_signature_at(0.0).unwrap().sharps(), Some(2));
648 assert_eq!(score.key_signature_at(3.5).unwrap().sharps(), Some(2));
649 assert_eq!(score.key_signature_at(4.0).unwrap().sharps(), Some(-1));
651 assert_eq!(score.key_signature_at(100.0).unwrap().sharps(), Some(-1));
652 assert_eq!(
653 score.time_signature_at(5.0).unwrap().ratio_string(),
654 "4/4",
655 "a metre stays in force across the bar that follows it"
656 );
657 assert!(score.metronome_mark_at(0.0).is_none());
658
659 let mut late = Stream::new();
661 late.insert(2.0, KeySignature::new(3));
662 assert!(late.key_signature_at(1.0).is_none());
663 assert_eq!(late.key_signature_at(2.0).unwrap().sharps(), Some(3));
664 }
665
666 #[test]
667 fn transposing_a_score_moves_its_key_signatures_too() {
668 let score = two_measure_score();
669 let up = score
670 .transpose(&Interval::from_name("M2").unwrap())
671 .unwrap();
672 assert_eq!(up.key_signature_at(0.0).unwrap().sharps(), Some(4));
673 assert_eq!(up.key_signature_at(4.0).unwrap().sharps(), Some(1));
674 let names: Vec<String> = up.pitches().iter().map(Pitch::name_with_octave).collect();
675 assert_eq!(names, ["E4", "F#4", "G#4", "A4", "B4", "C5"]);
676 assert_eq!(up.kind(), StreamKind::Score);
677 }
678}