1use crate::articulations::Articulation;
15use crate::clef::Clef;
16use crate::defaults::FloatType;
17use crate::duration::Duration;
18use crate::error::{Error, Result};
19use crate::expressions::{Expression, Ornament, split_expressions};
20use crate::key::KeySignature;
21use crate::meter::{BeamedNote, TimeSignature};
22use crate::notation::{BeamType, StemDirection, Tie, TieType};
23use crate::note::Note;
24use crate::pitch::Accidental;
25use crate::pitch::{AccidentalDisplayOptions, Pitch};
26use crate::rest::Rest;
27use crate::stream::{Stream, StreamElement, StreamEvent, StreamKind};
28
29mod score;
30
31#[cfg(feature = "musicxml")]
32pub(crate) use score::{
33 Kept, accidentals_made, for_each_measure, keeping_spanners, make_measure_notation,
34 make_part_notation, tuplet_brackets_made,
35};
36pub(crate) use score::{
37 beams_made, element_at_durations, make_part_notation_by, make_part_notation_keeping_spanners,
38};
39pub use score::{
40 consolidate_completed_tuplets, make_notation, make_tuplet_brackets, split_at_durations,
41 split_elements_to_complete_tuplets,
42};
43
44fn ornaments_decided(
52 note: &mut Note,
53 key: &KeySignature,
54 past: &[Pitch],
55 past_measure: &[Pitch],
56 altered: &[Pitch],
57 cautionary_not_immediate_repeat: bool,
58) -> Vec<Pitch> {
59 if note.expressions().is_empty() {
60 return Vec::new();
61 }
62 make_ornamental_accidentals(
63 note,
64 key,
65 &AccidentalDisplayOptions {
66 pitch_past: past,
67 pitch_past_measure: past_measure,
68 altered_pitches: altered,
69 cautionary_not_immediate_repeat,
70 ..AccidentalDisplayOptions::default()
71 },
72 )
73 .unwrap_or_default()
74}
75
76pub fn make_ornamental_accidentals(
99 note: &mut Note,
100 key: &KeySignature,
101 options: &AccidentalDisplayOptions<'_>,
102) -> Result<Vec<Pitch>> {
103 let source = note.pitch().clone();
104 let mut decided = Vec::new();
105 for expression in note.expressions_mut() {
106 let Expression::Ornament(ornament) = expression else {
107 continue;
108 };
109 let mut played = ornament.ornamental_pitches(&source, key)?;
110 if played.is_empty() {
111 continue;
112 }
113 ornament.update_accidental_display(&mut played, options);
114 write_back(ornament, &played);
115 decided.extend(played);
116 }
117 Ok(decided)
118}
119
120fn write_back(ornament: &mut Ornament, played: &[Pitch]) {
125 let shown = |pitch: &Pitch| -> Option<Accidental> {
126 let accidental = pitch.accidental();
127 accidental.display_status().map(|_| accidental.clone())
128 };
129 if ornament.is_a("Turn") {
130 if let Some(upper) = played.first().and_then(shown) {
131 ornament.set_upper_accidental(Some(upper));
132 }
133 if let Some(lower) = played.get(1).and_then(shown) {
134 ornament.set_lower_accidental(Some(lower));
135 }
136 } else if let Some(accidental) = played.first().and_then(shown) {
137 let _ = ornament.set_accidental(Some(accidental));
140 }
141}
142
143pub fn realize_ornaments(stream: &Stream) -> Result<Stream> {
168 let mut in_force = None;
169 realized_ornaments(stream, &mut in_force)
170}
171
172fn realized_ornaments(stream: &Stream, in_force: &mut Option<KeySignature>) -> Result<Stream> {
176 let mut realized = stream.clone_empty();
177 for event in stream.events() {
178 let element = event.element();
179 match element {
180 StreamElement::Stream(inner) => {
181 let inner = realized_ornaments(inner, in_force)?;
182 realized.push(StreamElement::Stream(Box::new(inner)));
183 }
184 StreamElement::KeySignature(signature) => {
185 *in_force = Some(signature.clone());
186 realized.push(element.clone());
187 }
188 StreamElement::Key(key) => {
189 *in_force = Some(key.key_signature());
190 realized.push(element.clone());
191 }
192 _ => played_into(element, in_force.as_ref(), &mut realized)?,
193 }
194 }
195 Ok(realized)
196}
197
198fn played_into(
201 element: &StreamElement,
202 in_force: Option<&KeySignature>,
203 realized: &mut Stream,
204) -> Result<()> {
205 let expressions = match element {
206 StreamElement::Note(note) => note.expressions(),
207 StreamElement::Chord(chord) => chord.expressions(),
208 StreamElement::Rest(rest) => rest.expressions(),
209 StreamElement::Unpitched(unpitched) => unpitched.written().expressions(),
210 _ => &[],
211 };
212 let ornaments: Vec<&Ornament> = expressions
213 .iter()
214 .filter_map(|expression| match expression {
215 Expression::Ornament(ornament) => Some(&**ornament),
216 _ => None,
217 })
218 .collect();
219 if ornaments.is_empty() {
220 realized.push(element.clone());
221 return Ok(());
222 }
223 let StreamElement::Note(note) = element else {
224 return Err(Error::Expression(format!(
225 "Cannot realize an ornament on {}",
226 element
227 .music21_classes()
228 .first()
229 .copied()
230 .unwrap_or("that element")
231 )));
232 };
233 let default = KeySignature::new(0);
236 let key = in_force.unwrap_or(&default);
237 for ornament in ornaments {
238 let played = ornament.realize(note, key)?;
239 for before in played.before {
240 realized.push(before);
241 }
242 if let Some(main) = played.main {
243 realized.push(main);
244 }
245 for after in played.after {
246 realized.push(after);
247 }
248 }
249 Ok(())
250}
251
252pub fn make_beams(stream: &mut Stream) -> Result<()> {
265 if stream.kind() == StreamKind::Measure {
266 let meter = meter_in(stream);
267 if let Some(meter) = meter {
268 beam_measure(stream, &meter)?;
269 }
270 } else {
271 let loose: Vec<(FloatType, TimeSignature)> = stream
273 .events()
274 .iter()
275 .filter_map(|event| match event.element() {
276 StreamElement::TimeSignature(meter) => Some((event.offset(), meter.clone())),
277 _ => None,
278 })
279 .collect();
280 let mut stated: Option<(FloatType, TimeSignature)> = None;
282 for event in stream.events_mut() {
283 let offset = event.offset();
284 let StreamElement::Stream(measure) = event.element_mut() else {
285 continue;
286 };
287 if measure.kind() != StreamKind::Measure {
288 continue;
289 }
290 if let Some(own) = meter_in(measure) {
291 stated = Some((offset, own));
292 }
293 let outside = loose.iter().rev().find(|(at, _)| *at <= offset + 1e-9);
294 let meter = match (&stated, outside) {
295 (Some((at, _)), Some((loose_at, meter))) if loose_at > at => Some(meter),
296 (Some((_, meter)), _) => Some(meter),
297 (None, outside) => outside.map(|(_, meter)| meter),
298 };
299 if let Some(meter) = meter {
300 beam_measure(measure, meter)?;
301 }
302 }
303 }
304 set_stem_direction_for_beam_groups(stream);
305 Ok(())
306}
307
308fn meter_in(measure: &Stream) -> Option<TimeSignature> {
311 measure
312 .events()
313 .iter()
314 .find_map(|event| match event.element() {
315 StreamElement::TimeSignature(meter) if event.offset() == 0.0 => Some(meter.clone()),
316 _ => None,
317 })
318}
319
320fn beam_measure(measure: &mut Stream, meter: &TimeSignature) -> Result<()> {
321 let padding = (measure.padding_left(), measure.padding_right());
322 let has_voices = measure.events().iter().any(|event| {
323 event
324 .element()
325 .as_stream()
326 .is_some_and(|inner| inner.kind() == StreamKind::Voice)
327 });
328 if has_voices {
329 for event in measure.events_mut() {
330 if let StreamElement::Stream(voice) = event.element_mut()
331 && voice.kind() == StreamKind::Voice
332 {
333 beam_line(voice, meter, padding)?;
334 }
335 }
336 Ok(())
337 } else {
338 beam_line(measure, meter, padding)
339 }
340}
341
342fn beam_line(
345 line: &mut Stream,
346 meter: &TimeSignature,
347 (padding_left, padding_right): (FloatType, FloatType),
348) -> Result<()> {
349 let is_general_note = |element: &StreamElement| {
351 matches!(
352 element,
353 StreamElement::Note(_)
354 | StreamElement::Chord(_)
355 | StreamElement::Rest(_)
356 | StreamElement::Unpitched(_)
357 | StreamElement::PercussionChord(_)
358 | StreamElement::ChordSymbol(_)
359 )
360 };
361 let count = line
362 .events()
363 .iter()
364 .filter(|event| is_general_note(event.element()))
365 .count();
366 if count <= 1 {
367 return Ok(());
368 }
369 let mut places: Vec<usize> = Vec::new();
370 let mut notes: Vec<BeamedNote> = Vec::new();
371 for (place, event) in line.events().iter().enumerate() {
372 let element = event.element();
373 if !is_general_note(element) {
374 continue;
375 }
376 let duration = element.duration();
377 if duration.is_some_and(|duration| duration.is_grace()) {
378 continue;
379 }
380 let sounds = !matches!(
381 element,
382 StreamElement::Rest(_) | StreamElement::ChordSymbol(_)
383 );
384 places.push(place);
385 notes.push(BeamedNote {
386 offset: event.offset(),
387 quarter_length: element.quarter_length(),
388 duration_type: duration
390 .and_then(|duration| match duration.components().as_slice() {
391 [(duration_type, _)] => Some(*duration_type),
392 _ => None,
393 })
394 .unwrap_or(crate::duration::DurationType::Quarter),
395 sounds,
396 });
397 }
398 let summed: FloatType = notes.iter().map(|note| note.quarter_length).sum();
399 let bar = meter.bar_quarter_length();
400 if summed > bar + 1e-9 {
402 return Ok(());
403 }
404 let highest = notes
405 .iter()
406 .map(|note| note.offset + note.quarter_length)
407 .fold(0.0, FloatType::max);
408 let start = if padding_left != 0.0 {
412 op_frac(padding_left)
413 } else if padding_right != 0.0 {
414 0.0
415 } else if highest < bar - 1e-9 {
416 bar - highest
417 } else {
418 0.0
419 };
420 for place in &places {
425 let element = line.events_mut()[*place].element_mut();
426 let Some(mut duration) = element.duration().cloned() else {
427 continue;
428 };
429 if duration.expression_is_inferred()
430 && duration.linked()
431 && duration.tuplets().is_empty()
432 && duration.components().len() <= 1
433 {
434 duration.set_expression_is_inferred(false);
435 score::set_duration(element, duration);
436 }
437 }
438 let beams = meter.beams_for(¬es, start, None)?;
439 for (place, beams) in places.into_iter().zip(beams) {
440 let beams = beams.unwrap_or_default();
441 match line.events_mut()[place].element_mut() {
442 StreamElement::Note(note) => note.set_beams(beams),
443 StreamElement::Chord(chord) => chord.set_beams(beams),
444 StreamElement::Unpitched(stroke) => stroke.written_mut().set_beams(beams),
445 StreamElement::PercussionChord(chord) => chord.written_mut().set_beams(beams),
446 _ => {}
447 }
448 }
449 Ok(())
450}
451
452struct Stemmed {
454 path: Vec<usize>,
456 offset: FloatType,
457 first_beam: Option<BeamType>,
458 direction: StemDirection,
459 pitches: Vec<Pitch>,
460}
461
462fn gather(
463 stream: &Stream,
464 base: FloatType,
465 path: &mut Vec<usize>,
466 out: &mut Vec<Stemmed>,
467 clefs: &mut Vec<(FloatType, Clef)>,
468) {
469 for (index, event) in stream.events().iter().enumerate() {
470 path.push(index);
471 let offset = base + event.offset();
472 match event.element() {
473 StreamElement::Stream(inner) => gather(inner, offset, path, out, clefs),
474 StreamElement::Clef(clef) => clefs.push((offset, clef.clone())),
475 StreamElement::Note(note) => out.push(Stemmed {
476 path: path.clone(),
477 offset,
478 first_beam: note.beams().by_number(1).and_then(|beam| beam.beam_type()),
479 direction: note.stem_direction(),
480 pitches: vec![note.pitch().clone()],
481 }),
482 StreamElement::Chord(chord) => out.push(Stemmed {
483 path: path.clone(),
484 offset,
485 first_beam: chord.beams().by_number(1).and_then(|beam| beam.beam_type()),
486 direction: chord.stem_direction(),
487 pitches: chord.pitches(),
488 }),
489 _ => {}
490 }
491 path.pop();
492 }
493}
494
495fn set_direction(stream: &mut Stream, path: &[usize], direction: StemDirection) {
496 let Some((first, rest)) = path.split_first() else {
497 return;
498 };
499 let Some(event) = stream.events_mut().get_mut(*first) else {
500 return;
501 };
502 match event.element_mut() {
503 StreamElement::Stream(inner) => set_direction(inner, rest, direction),
504 StreamElement::Note(note) => note.set_stem_direction(direction),
505 StreamElement::Chord(chord) => chord.set_stem_direction(direction),
506 _ => {}
507 }
508}
509
510pub fn set_stem_direction_for_beam_groups(stream: &mut Stream) {
518 let mut notes = Vec::new();
519 let mut clefs = Vec::new();
520 gather(stream, 0.0, &mut Vec::new(), &mut notes, &mut clefs);
521
522 let mut groups: Vec<Vec<usize>> = Vec::new();
523 let mut current: Vec<usize> = Vec::new();
524 let mut inside = false;
525 for (index, note) in notes.iter().enumerate() {
526 if note.first_beam == Some(BeamType::Start) {
527 inside = true;
528 }
529 if inside {
530 current.push(index);
531 }
532 if note.first_beam == Some(BeamType::Stop) {
533 groups.push(std::mem::take(&mut current));
534 inside = false;
535 }
536 }
537 if !current.is_empty() {
538 groups.push(current);
539 }
540
541 let settable = |direction: StemDirection| {
542 matches!(
543 direction,
544 StemDirection::Up | StemDirection::Down | StemDirection::Unspecified
545 )
546 };
547 for group in groups {
548 let Some(first) = group.first().map(|index| ¬es[*index]) else {
549 continue;
550 };
551 let mut said: Vec<StemDirection> = Vec::new();
552 for index in &group {
553 let direction = notes[*index].direction;
554 if settable(direction) && !said.contains(&direction) {
555 said.push(direction);
556 }
557 }
558 let consistent = !said.contains(&StemDirection::Unspecified) && said.len() < 2;
559 let Some((_, clef)) = clefs
560 .iter()
561 .rev()
562 .find(|(offset, _)| *offset <= first.offset)
563 else {
564 continue;
565 };
566 let pitches: Vec<Pitch> = group
567 .iter()
568 .flat_map(|index| notes[*index].pitches.iter().cloned())
569 .collect();
570 let Ok(direction) = clef.stem_direction_for_pitches(&pitches, true, false) else {
571 continue;
572 };
573 for index in &group {
574 let note = ¬es[*index];
575 if !settable(note.direction) {
576 continue;
577 }
578 if note.direction != StemDirection::Unspecified && consistent {
579 continue;
580 }
581 set_direction(stream, ¬e.path, direction);
582 }
583 }
584}
585
586struct Placed {
588 offset: FloatType,
589 end: FloatType,
590 voice: Option<usize>,
591 element: StreamElement,
592}
593
594struct Bar {
596 start: FloatType,
597 end: FloatType,
598 own: Vec<StreamEvent>,
599 voices: Vec<Vec<StreamEvent>>,
600}
601
602pub fn op_frac(value: FloatType) -> FloatType {
606 if value < 0.0 {
607 return -op_frac(-value);
608 }
609 match crate::duration::limited_fraction(value, 65535) {
610 Some((numerator, denominator)) if denominator != 0 => {
611 let snapped = numerator as FloatType / denominator as FloatType;
612 if (snapped - value).abs() < 1e-9 {
613 snapped
614 } else {
615 value
616 }
617 }
618 _ => value,
619 }
620}
621
622pub(crate) fn sorted_events(mut events: Vec<StreamEvent>) -> Vec<StreamEvent> {
625 events.sort_by(event_order);
626 events
627}
628
629#[cfg(feature = "musicxml")]
632pub(crate) fn insert_sorted(stream: &mut Stream, offset: FloatType, element: StreamElement) {
633 let event = StreamEvent::new(offset, element);
634 let mut events = stream.events().to_vec();
635 let place = events
636 .iter()
637 .position(|held| event_order(held, &event).is_gt())
638 .unwrap_or(events.len());
639 events.insert(place, event);
640 let spanners = stream.spanners().to_vec();
641 *stream = stream.with_events(events);
642 for spanner in spanners {
643 stream.add_spanner(spanner);
644 }
645}
646
647pub(crate) fn event_order(left: &StreamEvent, right: &StreamEvent) -> std::cmp::Ordering {
650 let grace = |event: &StreamEvent| {
651 event
652 .element()
653 .duration()
654 .is_some_and(crate::duration::Duration::is_grace)
655 };
656 left.offset()
657 .total_cmp(&right.offset())
658 .then(
659 left.element()
660 .class_sort_order()
661 .cmp(&right.element().class_sort_order()),
662 )
663 .then(grace(right).cmp(&grace(left)))
664}
665
666fn placed(offset: FloatType, voice: Option<usize>, element: &StreamElement) -> Placed {
667 Placed {
668 offset,
669 end: op_frac(offset + element.quarter_length()),
670 voice,
671 element: element.clone(),
672 }
673}
674
675pub fn make_measures(stream: &Stream) -> Result<Stream> {
704 make_measures_by(stream, &[])
705}
706
707pub fn make_measures_by(stream: &Stream, given: &[(FloatType, TimeSignature)]) -> Result<Stream> {
711 let is_part_like = |element: &StreamElement| {
712 element
713 .as_stream()
714 .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
715 };
716 if stream
717 .events()
718 .iter()
719 .any(|event| is_part_like(event.element()))
720 {
721 let mut made = stream.clone();
722 for event in made.events_mut() {
723 if let StreamElement::Stream(inner) = event.element_mut() {
724 **inner = make_measures_by(inner, given)?;
725 }
726 }
727 return Ok(made);
728 }
729
730 let voices = stream.voices();
733 let voice_count = voices.len();
734 let mut waiting: Vec<Placed> = Vec::new();
735 if voice_count > 0 {
736 for event in stream.events() {
737 let is_voice = event
738 .element()
739 .as_stream()
740 .is_some_and(|inner| inner.kind() == StreamKind::Voice);
741 if !is_voice {
742 waiting.push(placed(event.offset(), None, event.element()));
743 }
744 }
745 for (index, voice) in voices.iter().enumerate() {
746 for event in sorted_events(voice.flatten().events().to_vec()) {
747 waiting.push(placed(event.offset(), Some(index), event.element()));
748 }
749 }
750 } else {
751 for event in sorted_events(stream.flatten().events().to_vec()) {
752 waiting.push(placed(event.offset(), None, event.element()));
753 }
754 }
755
756 let mut meters: Vec<(FloatType, TimeSignature)> = waiting
758 .iter()
759 .filter_map(|item| match &item.element {
760 StreamElement::TimeSignature(meter) => Some((item.offset, meter.clone())),
761 _ => None,
762 })
763 .collect();
764 meters.sort_by(|left, right| left.0.total_cmp(&right.0));
765 if meters.first().is_none_or(|(offset, _)| *offset > 0.0) {
766 meters.insert(0, (0.0, TimeSignature::new(4, 4)?));
767 }
768 if !given.is_empty() {
769 meters = given.to_vec();
770 meters.sort_by(|left, right| left.0.total_cmp(&right.0));
771 }
772
773 let own_clef = waiting.iter().position(|item| {
776 item.voice.is_none() && item.offset == 0.0 && matches!(item.element, StreamElement::Clef(_))
777 });
778 let clef = match own_clef.map(|index| &waiting[index].element) {
779 Some(StreamElement::Clef(clef)) => clef.clone(),
780 _ => {
781 let mut pitches: Vec<Pitch> = Vec::new();
782 for item in &waiting {
783 match &item.element {
784 StreamElement::Note(note) => pitches.push(note.pitch().clone()),
785 StreamElement::Chord(chord) => pitches.extend(chord.pitches()),
786 StreamElement::ChordSymbol(symbol) => {
787 pitches.extend(symbol.pitches().unwrap_or_default());
788 }
789 _ => {}
790 }
791 }
792 Clef::best_for(&pitches, false)
793 }
794 };
795 let key = waiting.iter().find_map(|item| match &item.element {
796 element @ (StreamElement::KeySignature(_) | StreamElement::Key(_))
797 if item.voice.is_none() && item.offset == 0.0 =>
798 {
799 Some(element.clone())
800 }
801 _ => None,
802 });
803
804 let end = waiting
805 .iter()
806 .map(|item| item.end)
807 .fold(0.0, FloatType::max);
808
809 let mut bars: Vec<Bar> = Vec::new();
812 let mut offset = 0.0;
813 let mut last_meter: Option<usize> = None;
814 loop {
815 let here = meters
816 .iter()
817 .rposition(|(at, _)| *at <= offset)
818 .unwrap_or(0);
819 let mut own = Vec::new();
820 if last_meter != Some(here) {
821 last_meter = Some(here);
822 own.push(StreamEvent::new(0.0, meters[here].1.clone()));
823 }
824 if bars.is_empty() {
825 own.push(StreamEvent::new(0.0, clef.clone()));
826 if voice_count > 0
828 && let Some(key) = &key
829 {
830 own.push(StreamEvent::new(0.0, key.clone()));
831 }
832 }
833 let length = meters[here].1.bar_quarter_length();
834 if length == 0.0 {
835 return Err(crate::error::Error::Meter(format!(
836 "time signature {} has no duration",
837 meters[here].1.ratio_string()
838 )));
839 }
840 let next = op_frac(offset + length);
841 bars.push(Bar {
842 start: offset,
843 end: next,
844 own,
845 voices: vec![Vec::new(); voice_count],
846 });
847 offset = next;
848 if offset >= end {
849 break;
850 }
851 }
852
853 let mut loose: Vec<StreamEvent> = Vec::new();
854 for (index, item) in waiting.into_iter().enumerate() {
855 let Some(bar) = bars
856 .iter_mut()
857 .find(|bar| bar.start <= item.offset && item.offset < bar.end)
858 else {
859 if item.offset == item.end && item.offset == end {
862 loose.push(StreamEvent::new(item.offset, item.element));
863 continue;
864 }
865 return Err(crate::error::Error::Meter(format!(
866 "cannot place an element with start/end {}/{} within any measures",
867 item.offset, item.end
868 )));
869 };
870 let within = op_frac(item.offset - bar.start);
871 if own_clef == Some(index) {
872 continue;
873 }
874 if within == 0.0 && matches!(item.element, StreamElement::TimeSignature(_)) {
875 continue;
876 }
877 match item.voice {
878 None => bar.own.push(StreamEvent::new(within, item.element)),
879 Some(voice) => bar.voices[voice].push(StreamEvent::new(within, item.element)),
880 }
881 }
882
883 let count = bars.len();
884 let mut events: Vec<StreamEvent> = Vec::new();
885 for (index, bar) in bars.into_iter().enumerate() {
886 let mut own = bar.own;
887 for (id, voice) in bar.voices.into_iter().enumerate() {
888 let mut voice = Stream::new().with_events(sorted_events(voice));
889 voice.set_kind(StreamKind::Voice);
890 voice.set_id(Some(id.to_string()));
891 own.push(StreamEvent::new(0.0, voice));
892 }
893 let mut measure = Stream::new().with_events(sorted_events(own));
894 measure.set_kind(StreamKind::Measure);
895 measure.set_number(index as crate::defaults::IntegerType + 1);
896 if index + 1 == count {
897 measure.set_right_barline(Some(crate::bar::Barline::new(
898 crate::bar::BarlineType::Final,
899 )));
900 }
901 events.push(StreamEvent::new(bar.start, measure));
902 }
903 events.extend(loose);
904 Ok(stream.with_events(events))
905}
906
907pub(crate) fn is_general_note(element: &StreamElement) -> bool {
910 matches!(
911 element,
912 StreamElement::Note(_)
913 | StreamElement::Chord(_)
914 | StreamElement::Rest(_)
915 | StreamElement::Unpitched(_)
916 | StreamElement::PercussionChord(_)
917 | StreamElement::ChordSymbol(_)
918 )
919}
920
921pub(crate) fn is_not_rest(element: &StreamElement) -> bool {
923 is_general_note(element) && !matches!(element, StreamElement::Rest(_))
924}
925
926fn is_voice(element: &StreamElement) -> bool {
927 element
928 .as_stream()
929 .is_some_and(|inner| inner.kind() == StreamKind::Voice)
930}
931
932fn set_quarter_length(element: &mut StreamElement, quarter_length: FloatType) -> Result<()> {
934 let duration = Duration::new(quarter_length)?;
935 match element {
936 StreamElement::Note(note) => note.set_duration(duration),
937 StreamElement::Chord(chord) => chord.set_duration(duration),
938 StreamElement::Rest(rest) => rest.set_duration(duration),
939 StreamElement::Unpitched(stroke) => stroke.written_mut().set_duration(duration),
940 StreamElement::PercussionChord(chord) => chord.written_mut().set_duration(duration),
941 _ => {}
942 }
943 Ok(())
944}
945
946fn split_tie(note: &mut Note) -> TieType {
949 match note.tie().map(Tie::tie_type) {
950 Some(TieType::Start) => TieType::Continue,
951 Some(TieType::Stop) => {
952 let mut tie = note
953 .tie()
954 .cloned()
955 .unwrap_or_else(|| Tie::new(TieType::Stop));
956 tie.set_tie_type(TieType::Continue);
957 note.set_tie(Some(tie));
958 TieType::Stop
959 }
960 Some(TieType::Continue) => TieType::Continue,
961 _ => {
962 note.set_tie(Some(Tie::new(TieType::Start)));
963 TieType::Stop
964 }
965 }
966}
967
968fn hide_tied_accidental(first: &Note, second: &mut Note) {
970 let Some(accidental) = first.pitch().written_accidental() else {
971 return;
972 };
973 if accidental.display_type() == "even-tied" {
974 return;
975 }
976 let mut pitch = second.pitch().clone();
977 if let Some(accidental) = pitch.written_accidental_mut() {
978 accidental.set_display_status(Some(false));
979 second.set_pitch(pitch);
980 }
981}
982
983pub(crate) fn split_element(
989 element: &StreamElement,
990 at: FloatType,
991) -> Result<(StreamElement, StreamElement)> {
992 let whole = element.quarter_length();
993 let first_length = Duration::new(at)?;
994 let second_length = Duration::new(op_frac(whole - at))?;
995 let share = |marks: &[Articulation]| -> (Vec<Articulation>, Vec<Articulation>) {
997 let mut first = Vec::new();
998 let mut second = Vec::new();
999 for mark in marks {
1000 match mark.tie_attach() {
1001 "first" => first.push(mark.clone()),
1002 "last" => second.push(mark.clone()),
1003 _ => {
1004 first.push(mark.clone());
1005 second.push(mark.clone());
1006 }
1007 }
1008 }
1009 (first, second)
1010 };
1011 let split_note = |note: &Note| -> (Note, Note) {
1012 let mut first = note.clone();
1013 let mut second = note.clone();
1014 second.lyrics_mut().clear();
1015 let (kept, moved) = share(note.articulations());
1016 *first.articulations_mut() = kept;
1017 *second.articulations_mut() = moved;
1018 let (kept, moved) = split_expressions(note.expressions());
1019 *first.expressions_mut() = kept;
1020 *second.expressions_mut() = moved;
1021 first.set_duration(first_length.clone());
1022 second.set_duration(second_length.clone());
1023 let closing = split_tie(&mut first);
1024 second.set_tie(Some(Tie::new(closing)));
1025 hide_tied_accidental(&first, &mut second);
1026 (first, second)
1027 };
1028 match element {
1029 StreamElement::Note(note) => {
1030 let (first, second) = split_note(note);
1031 Ok((first.into(), second.into()))
1032 }
1033 StreamElement::Unpitched(stroke) => {
1034 let (first_note, second_note) = split_note(stroke.written());
1035 let mut first = stroke.clone();
1036 let mut second = stroke.clone();
1037 *first.written_mut() = first_note;
1038 *second.written_mut() = second_note;
1039 Ok((first.into(), second.into()))
1040 }
1041 StreamElement::Chord(chord) => {
1042 let mut first = chord.clone();
1043 let mut second = chord.clone();
1044 let (kept, moved) = share(chord.articulations());
1045 *first.articulations_mut() = kept;
1046 *second.articulations_mut() = moved;
1047 let (kept, moved) = split_expressions(chord.expressions());
1048 *first.expressions_mut() = kept;
1049 *second.expressions_mut() = moved;
1050 first.set_duration(first_length);
1051 second.set_duration(second_length);
1052 if let Some(singer) = second.notes_mut().first_mut() {
1054 singer.lyrics_mut().clear();
1055 }
1056 for (one, other) in first.notes_mut().iter_mut().zip(second.notes_mut()) {
1057 let closing = split_tie(one);
1058 other.set_tie(Some(Tie::new(closing)));
1059 hide_tied_accidental(one, other);
1060 }
1061 Ok((first.into(), second.into()))
1062 }
1063 StreamElement::PercussionChord(chord) => {
1064 let mut first = chord.clone();
1065 let mut second = chord.clone();
1066 let (kept, moved) = split_expressions(chord.written().expressions());
1067 *first.written_mut().expressions_mut() = kept;
1068 *second.written_mut().expressions_mut() = moved;
1069 first.written_mut().set_duration(first_length);
1070 second.written_mut().set_duration(second_length);
1071 Ok((first.into(), second.into()))
1072 }
1073 StreamElement::Rest(rest) => {
1074 let mut first = rest.clone();
1075 let mut second = rest.clone();
1076 second.lyrics_mut().clear();
1077 let (kept, moved) = split_expressions(rest.expressions());
1078 *first.expressions_mut() = kept;
1079 *second.expressions_mut() = moved;
1080 first.set_duration(first_length);
1081 second.set_duration(second_length);
1082 Ok((first.into(), second.into()))
1083 }
1084 _ => Err(Error::Duration(
1085 "only a note, a chord or a rest is cut at a bar".to_string(),
1086 )),
1087 }
1088}
1089
1090fn nearest_multiple(number: FloatType, unit: FloatType) -> (FloatType, FloatType, FloatType) {
1093 let round7 = |value: FloatType| (value * 1e7).round_ties_even() / 1e7;
1094 let multiple = (number / unit).floor();
1095 let low = unit * multiple;
1096 let high = unit * (multiple + 1.0);
1097 if low <= number && number <= low + unit / 2.0 {
1098 (low, round7(number - low), round7(number - low))
1099 } else {
1100 (high, round7(high - number), round7(number - high))
1101 }
1102}
1103
1104fn best_match(
1108 target: FloatType,
1109 divisors: &[u32],
1110 zero_allowed: bool,
1111 gap: FloatType,
1112) -> (FloatType, FloatType, FloatType, FloatType) {
1113 let mut best: Option<(FloatType, FloatType, FloatType, FloatType)> = None;
1114 for divisor in divisors {
1115 let unit = 1.0 / FloatType::from(*divisor);
1116 let (mut found, mut error, _) = nearest_multiple(target, unit);
1117 if !zero_allowed && found == 0.0 {
1118 found = unit;
1119 error = ((target - found) * 1e7).round_ties_even().abs() / 1e7;
1120 }
1121 let remaining = if gap % unit == 0.0 {
1122 0.0
1123 } else {
1124 (gap - found).max(0.0)
1125 };
1126 let candidate = (remaining, error, unit, found);
1127 let better = best.is_none_or(|held| {
1128 candidate
1129 .0
1130 .total_cmp(&held.0)
1131 .then(candidate.1.total_cmp(&held.1))
1132 .then(candidate.2.total_cmp(&held.2))
1133 .then(candidate.3.total_cmp(&held.3))
1134 .is_lt()
1135 });
1136 if better {
1137 best = Some(candidate);
1138 }
1139 }
1140 best.unwrap_or((0.0, 0.0, 1.0, target))
1141}
1142
1143pub const QUANTIZATION_DIVISORS: [u32; 2] = [4, 3];
1146
1147pub fn quantize(stream: &mut Stream, divisors: &[u32]) -> Result<()> {
1155 let divisors: &[u32] = if divisors.is_empty() {
1156 &QUANTIZATION_DIVISORS
1157 } else {
1158 divisors
1159 };
1160 let mut events = stream.events().to_vec();
1161 for index in 0..events.len() {
1162 let original = events[index].offset();
1163 let sign = if original < 0.0 { -1.0 } else { 1.0 };
1164 let offset = op_frac(best_match(original.abs(), divisors, true, 0.0).3 * sign);
1165 let mut element = events[index].element().clone();
1166
1167 let is_grace = element.duration().is_some_and(Duration::is_grace);
1168 let length = element.quarter_length().max(0.0);
1169 let zero_allowed = !is_not_rest(&element) || is_grace;
1170 let ahead = events[index + 1..]
1173 .iter()
1174 .map(|event| best_match(event.offset(), divisors, true, 0.0).3)
1175 .find(|landing| *landing > offset);
1176 let gap = ahead.map_or(0.0, |landing| op_frac(landing - offset));
1177 let matched = best_match(length, divisors, zero_allowed, gap).3;
1178 let is_stream = matches!(element, StreamElement::Stream(_));
1179 if !is_grace && !is_stream && !(matched == 0.0 && matches!(element, StreamElement::Rest(_)))
1180 {
1181 set_quarter_length(&mut element, op_frac(matched))?;
1182 }
1183 let dropped = matched == 0.0 && matches!(element, StreamElement::Rest(_));
1184 events[index] = StreamEvent::new(offset, element);
1185 if dropped {
1186 events[index] = StreamEvent::new(FloatType::NAN, events[index].element().clone());
1188 }
1189 }
1190 events.retain(|event| !event.offset().is_nan());
1191 *stream = stream.with_events(sorted_events(events));
1192 Ok(())
1193}
1194
1195fn most_at_once(spans: &[(FloatType, FloatType)]) -> usize {
1198 let overlaps = |left: (FloatType, FloatType), right: (FloatType, FloatType)| {
1199 let (first, second) = if right.0 < left.0 || (right.0 == left.0 && right.1 < left.1) {
1200 (right, left)
1201 } else {
1202 (left, right)
1203 };
1204 second.0 < first.1
1205 };
1206 let mut layering: Vec<Vec<usize>> = vec![Vec::new(); spans.len()];
1207 for source in 0..spans.len() {
1208 for target in source + 1..spans.len() {
1209 if overlaps(spans[source], spans[target]) {
1210 layering[source].push(target);
1211 layering[target].push(source);
1212 } else {
1213 break;
1214 }
1215 }
1216 }
1217 for list in &mut layering {
1218 list.sort_unstable();
1219 }
1220 let mut groups: Vec<(FloatType, Vec<usize>)> = Vec::new();
1222 for (source, others) in layering.iter().enumerate() {
1223 if others.is_empty() {
1224 continue;
1225 }
1226 let mut destination: Option<FloatType> = None;
1227 for other in others {
1228 let mut store = true;
1229 if let Some((key, _)) = groups.iter().find(|(_, held)| held.contains(other)) {
1230 store = false;
1231 destination = Some(*key);
1232 }
1233 let key = *destination.get_or_insert(spans[source].0);
1234 if store {
1235 match groups.iter_mut().find(|(held, _)| *held == key) {
1236 Some((_, held)) => held.push(*other),
1237 None => groups.push((key, vec![*other])),
1238 }
1239 }
1240 }
1241 if !groups.iter().any(|(_, held)| held.contains(&source)) {
1242 let key = destination.unwrap_or(spans[source].0);
1243 match groups.iter_mut().find(|(held, _)| *held == key) {
1244 Some((_, held)) => held.push(source),
1245 None => groups.push((key, vec![source])),
1246 }
1247 }
1248 }
1249 groups
1250 .iter()
1251 .map(|(_, held)| held.len())
1252 .max()
1253 .unwrap_or(1)
1254 .max(1)
1255}
1256
1257pub fn make_voices(measure: &mut Stream) {
1265 let events = measure.events().to_vec();
1266 let spans: Vec<(FloatType, FloatType)> = events
1267 .iter()
1268 .filter(|event| is_not_rest(event.element()))
1269 .map(|event| (event.offset(), op_frac(event.end_offset())))
1270 .collect();
1271 let count = most_at_once(&spans);
1272 if count == 1 {
1273 return;
1274 }
1275 let mut voices: Vec<(FloatType, Vec<StreamEvent>)> = vec![(0.0, Vec::new()); count];
1276 let mut kept: Vec<StreamEvent> = Vec::new();
1277 for event in events {
1278 if !is_not_rest(event.element()) {
1279 if !matches!(event.element(), StreamElement::Rest(_)) {
1281 kept.push(event);
1282 }
1283 continue;
1284 }
1285 let offset = event.offset();
1286 let end = op_frac(event.end_offset());
1287 if let Some((highest, held)) = voices.iter_mut().find(|(highest, _)| *highest <= offset) {
1288 *highest = highest.max(end);
1289 held.push(event);
1290 }
1291 }
1292 for (_, held) in voices {
1293 if held.is_empty() {
1294 continue;
1295 }
1296 let mut voice = Stream::new().with_events(held);
1297 voice.set_kind(StreamKind::Voice);
1298 kept.push(StreamEvent::new(0.0, voice));
1299 }
1300 *measure = measure.with_events(sorted_events(kept));
1301}
1302
1303fn meters_of(part: &Stream) -> Result<Vec<(FloatType, TimeSignature)>> {
1306 let mut meters: Vec<(FloatType, TimeSignature)> = part
1307 .recurse()
1308 .into_iter()
1309 .filter_map(|(offset, element)| match element {
1310 StreamElement::TimeSignature(meter) => Some((offset, meter.clone())),
1311 _ => None,
1312 })
1313 .collect();
1314 meters.sort_by(|left, right| left.0.total_cmp(&right.0));
1315 let mut group: Vec<usize> = (0..meters.len()).collect();
1319 for index in 0..meters.len() {
1320 if !meters[index].1.is_restated() {
1321 continue;
1322 }
1323 let ratio = meters[index].1.ratio_string();
1324 if let Some(earlier) = (0..index)
1325 .rev()
1326 .find(|earlier| meters[*earlier].1.ratio_string() == ratio)
1327 {
1328 group[index] = group[earlier];
1329 }
1330 }
1331 for index in (0..meters.len()).rev() {
1332 let last = (0..meters.len())
1333 .rev()
1334 .find(|other| group[*other] == group[index])
1335 .unwrap_or(index);
1336 meters[index].0 = meters[last].0;
1337 }
1338 meters.sort_by(|left, right| left.0.total_cmp(&right.0));
1339 if meters.first().is_none_or(|(offset, _)| *offset > 0.0) {
1340 meters.insert(0, (0.0, TimeSignature::new(4, 4)?));
1341 }
1342 Ok(meters)
1343}
1344
1345fn flatten_unnecessary_voices(measure: &mut Stream) {
1349 let events = measure.events().to_vec();
1350 if !events.iter().any(|event| is_voice(event.element())) {
1351 return;
1352 }
1353 let full = events
1354 .iter()
1355 .filter(|event| {
1356 event
1357 .element()
1358 .as_stream()
1359 .is_some_and(|inner| inner.kind() == StreamKind::Voice && !inner.is_empty())
1360 })
1361 .count();
1362 let mut kept: Vec<StreamEvent> = Vec::new();
1363 let mut freed: Vec<StreamEvent> = Vec::new();
1364 for event in events {
1365 match event.element() {
1366 StreamElement::Stream(inner) if inner.kind() == StreamKind::Voice => {
1367 if inner.is_empty() {
1368 continue;
1369 }
1370 if full == 1 {
1371 let shift = event.offset();
1372 freed.extend(inner.events().iter().map(|held| {
1373 StreamEvent::new(shift + held.offset(), held.element().clone())
1374 }));
1375 } else {
1376 kept.push(event);
1377 }
1378 }
1379 _ => kept.push(event),
1380 }
1381 }
1382 kept.extend(freed);
1383 *measure = measure.with_events(sorted_events(kept));
1384}
1385
1386pub fn make_ties(stream: &mut Stream) -> Result<()> {
1395 make_ties_of(stream, is_general_note)
1396}
1397
1398fn make_ties_of(stream: &mut Stream, wanted: fn(&StreamElement) -> bool) -> Result<()> {
1399 let part_like = |element: &StreamElement| {
1400 element
1401 .as_stream()
1402 .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
1403 };
1404 if stream
1405 .events()
1406 .iter()
1407 .any(|event| part_like(event.element()))
1408 {
1409 let mut events = stream.events().to_vec();
1410 for event in &mut events {
1411 if let StreamElement::Stream(inner) = event.element_mut() {
1412 make_ties_of(inner, wanted)?;
1413 }
1414 }
1415 let spanners = stream.spanners().to_vec();
1416 *stream = stream.with_events(events);
1417 for spanner in spanners {
1418 stream.add_spanner(spanner);
1419 }
1420 return Ok(());
1421 }
1422 let meters = meters_of(stream)?;
1423 let mut others: Vec<StreamEvent> = Vec::new();
1424 let mut measures: Vec<(FloatType, Stream)> = Vec::new();
1425 for event in stream.events() {
1426 match event.element() {
1427 StreamElement::Stream(inner) if inner.kind() == StreamKind::Measure => {
1428 measures.push((event.offset(), (**inner).clone()));
1429 }
1430 _ => others.push(event.clone()),
1431 }
1432 }
1433 if measures.is_empty() {
1434 return Err(Error::Meter(
1435 "cannot process a stream without measures".to_string(),
1436 ));
1437 }
1438
1439 let mut index = 0;
1440 while index < measures.len() {
1441 let start = measures[index].0;
1442 let meter = meters
1443 .iter()
1444 .rfind(|(at, _)| *at <= start)
1445 .map_or(&meters[0].1, |(_, meter)| meter);
1446 let bar = meter.bar_quarter_length();
1447 let has_voices = measures[index]
1448 .1
1449 .events()
1450 .iter()
1451 .any(|event| is_voice(event.element()));
1452
1453 let mut remains: Vec<(Option<String>, StreamElement)> = Vec::new();
1455 let mut cut = |line: &mut Stream, id: Option<String>| -> Result<()> {
1456 let mut events = line.events().to_vec();
1457 for event in &mut events {
1458 if !wanted(event.element()) {
1459 continue;
1460 }
1461 let offset = event.offset();
1462 let end = op_frac(event.end_offset());
1463 if end - bar <= 1e-9 || offset >= bar - 1e-9 {
1464 continue;
1465 }
1466 let (first, remain) = split_element(event.element(), op_frac(bar - offset))?;
1467 *event = StreamEvent::new(offset, first);
1468 remains.push((id.clone(), remain));
1469 }
1470 *line = line.with_events(events);
1471 Ok(())
1472 };
1473 {
1474 let measure = &mut measures[index].1;
1475 if has_voices {
1476 let mut events = measure.events().to_vec();
1477 for event in &mut events {
1478 if let StreamElement::Stream(voice) = event.element_mut()
1479 && voice.kind() == StreamKind::Voice
1480 {
1481 let id = voice.id().map(str::to_string);
1482 cut(voice, id)?;
1483 }
1484 }
1485 *measure = measure.with_events(events);
1486 } else {
1487 cut(measure, None)?;
1488 }
1489 }
1490 if remains.is_empty() {
1491 index += 1;
1492 continue;
1493 }
1494 if index + 1 == measures.len() {
1495 let mut next = Stream::with_kind(StreamKind::Measure);
1496 next.set_number(measures[index].1.number() + 1);
1497 measures.push((op_frac(start + bar), next));
1498 }
1499 let next = &mut measures[index + 1].1;
1500 let next_had_voices = next.events().iter().any(|event| is_voice(event.element()));
1501 for (id, remain) in remains {
1502 let mut events = next.events().to_vec();
1503 let voice_at = |events: &[StreamEvent], wanted: Option<&str>| -> Option<usize> {
1504 events.iter().position(|event| {
1505 event.element().as_stream().is_some_and(|inner| {
1506 inner.kind() == StreamKind::Voice
1507 && wanted.is_none_or(|wanted| inner.id() == Some(wanted))
1508 })
1509 })
1510 };
1511 let destination = if next_had_voices {
1512 if has_voices {
1513 id.as_deref().and_then(|id| voice_at(&events, Some(id)))
1514 } else {
1515 voice_at(&events, None)
1516 }
1517 } else if has_voices {
1518 let (moved, kept): (Vec<StreamEvent>, Vec<StreamEvent>) = events
1521 .into_iter()
1522 .partition(|event| is_general_note(event.element()));
1523 events = kept;
1524 let mut voice = Stream::new().with_events(moved);
1525 voice.set_kind(StreamKind::Voice);
1526 events.push(StreamEvent::new(0.0, voice));
1527 events = sorted_events(events);
1528 voice_at(&events, None)
1529 } else {
1530 None
1531 };
1532 match destination {
1533 Some(place) => {
1534 if let StreamElement::Stream(voice) = events[place].element_mut() {
1535 let mut held = voice.events().to_vec();
1536 held.push(StreamEvent::new(0.0, remain));
1537 **voice = voice.with_events(sorted_events(held));
1538 }
1539 }
1540 None => {
1541 events.push(StreamEvent::new(0.0, remain));
1542 events = sorted_events(events);
1543 }
1544 }
1545 *next = next.with_events(events);
1546 }
1547 index += 1;
1548 }
1549
1550 for (offset, mut measure) in measures {
1551 flatten_unnecessary_voices(&mut measure);
1552 others.push(StreamEvent::new(offset, measure));
1553 }
1554 *stream = stream.with_events(sorted_events(others));
1555 Ok(())
1556}
1557
1558pub(crate) fn fill_line(
1562 line: &mut Stream,
1563 low: FloatType,
1564 high: FloatType,
1565 hidden: bool,
1566) -> Result<()> {
1567 let mut events = line.events().to_vec();
1568 let lowest = events
1569 .iter()
1570 .map(StreamEvent::offset)
1571 .fold(FloatType::INFINITY, FloatType::min);
1572 let lowest = if lowest.is_finite() { lowest } else { 0.0 };
1573 let highest = op_frac(line.end_offset());
1574 let rest = |at: FloatType, length: FloatType| -> Result<StreamEvent> {
1575 let mut rest = Rest::new(Duration::new(op_frac(length))?);
1576 rest.set_hidden(hidden);
1577 Ok(StreamEvent::new(at, rest))
1578 };
1579 if lowest - low > 1e-9 {
1580 events.push(rest(low, lowest - low)?);
1581 }
1582 if high - highest > 1e-9 {
1583 events.push(rest(highest, high - highest)?);
1584 }
1585 events = sorted_events(events);
1586 let mut gaps: Vec<StreamEvent> = Vec::new();
1587 let mut reached = 0.0;
1588 for event in &events {
1589 if event.offset() - reached > 1e-9 {
1590 gaps.push(rest(reached, event.offset() - reached)?);
1591 }
1592 reached = op_frac(FloatType::max(reached, event.end_offset()));
1593 }
1594 events.extend(gaps);
1595 *line = line.with_events(sorted_events(events));
1596 Ok(())
1597}
1598
1599pub fn make_rests(stream: &mut Stream) -> Result<()> {
1607 fill_rests(stream, None, false)
1608}
1609
1610pub(crate) fn fill_rests(
1615 stream: &mut Stream,
1616 range: Option<(FloatType, FloatType)>,
1617 hidden: bool,
1618) -> Result<()> {
1619 let is_part = |element: &StreamElement| {
1620 element
1621 .as_stream()
1622 .is_some_and(|inner| matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff))
1623 };
1624 if stream.events().iter().any(|event| is_part(event.element())) {
1625 let mut events = stream.events().to_vec();
1626 for event in &mut events {
1627 if let StreamElement::Stream(inner) = event.element_mut()
1628 && matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff)
1629 {
1630 let spanners = inner.spanners().to_vec();
1631 fill_rests(inner, range, hidden)?;
1632 inner.clear_spanners();
1633 for spanner in spanners {
1634 inner.add_spanner(spanner);
1635 }
1636 }
1637 }
1638 let spanners = stream.spanners().to_vec();
1639 *stream = stream.with_events(events);
1640 for spanner in spanners {
1641 stream.add_spanner(spanner);
1642 }
1643 return Ok(());
1644 }
1645 let has_measures = stream.events().iter().any(|event| {
1646 event
1647 .element()
1648 .as_stream()
1649 .is_some_and(|inner| inner.kind() == StreamKind::Measure)
1650 });
1651 if !has_measures {
1652 let (low, high) = range.unwrap_or((0.0, stream.end_offset()));
1653 let has_voices = stream
1654 .events()
1655 .iter()
1656 .any(|event| is_voice(event.element()));
1657 if has_voices {
1658 let mut events = stream.events().to_vec();
1659 for event in &mut events {
1660 if let StreamElement::Stream(voice) = event.element_mut()
1661 && voice.kind() == StreamKind::Voice
1662 {
1663 fill_line(voice, low, high, hidden)?;
1664 }
1665 }
1666 let spanners = stream.spanners().to_vec();
1667 *stream = stream.with_events(events);
1668 for spanner in spanners {
1669 stream.add_spanner(spanner);
1670 }
1671 } else {
1672 let spanners = stream.spanners().to_vec();
1673 fill_line(stream, low, high, hidden)?;
1674 for spanner in spanners {
1675 stream.add_spanner(spanner);
1676 }
1677 }
1678 return Ok(());
1679 }
1680 let mut events = stream.events().to_vec();
1681 let loose: Vec<(FloatType, TimeSignature)> = events
1683 .iter()
1684 .filter_map(|event| match event.element() {
1685 StreamElement::TimeSignature(meter) => Some((event.offset(), meter.clone())),
1686 _ => None,
1687 })
1688 .collect();
1689 let mut meter: Option<TimeSignature> = None;
1690 for event in &mut events {
1691 let offset = event.offset();
1692 let StreamElement::Stream(measure) = event.element_mut() else {
1693 continue;
1694 };
1695 if measure.kind() != StreamKind::Measure {
1696 continue;
1697 }
1698 if let Some(own) = meter_in(measure) {
1699 meter = Some(own);
1700 }
1701 let bar = match &meter {
1705 Some(meter) => meter.bar_quarter_length(),
1706 None => match loose.iter().rev().find(|(at, _)| *at < offset) {
1707 Some((_, meter)) => meter.bar_quarter_length(),
1708 None => crate::meter::best_time_signature(measure)
1709 .map_or_else(|_| measure.end_offset(), |meter| meter.bar_quarter_length()),
1710 },
1711 };
1712 let target = FloatType::max(
1713 op_frac(bar - measure.padding_left() - measure.padding_right()),
1714 0.0,
1715 );
1716 let mut held = measure.events().to_vec();
1717 for inner in &mut held {
1718 if let StreamElement::Stream(voice) = inner.element_mut()
1719 && voice.kind() == StreamKind::Voice
1720 {
1721 fill_line(voice, 0.0, target, hidden)?;
1722 }
1723 }
1724 **measure = measure.with_events(held);
1725 fill_line(measure, 0.0, target.min(bar), hidden)?;
1726 }
1727 *stream = stream.with_events(events);
1728 make_ties_of(stream, |element| matches!(element, StreamElement::Rest(_)))?;
1729 let mut events = stream.events().to_vec();
1730 let mut reached = 0.0;
1731 for event in &mut events {
1732 if let StreamElement::Stream(measure) = event.element()
1733 && measure.kind() == StreamKind::Measure
1734 {
1735 let length = measure.end_offset();
1736 *event = StreamEvent::new(reached, event.element().clone());
1737 reached = op_frac(reached + length);
1738 }
1739 }
1740 *stream = stream.with_events(sorted_events(events));
1741 Ok(())
1742}
1743
1744fn key_signature_in(measure: &Stream) -> Option<crate::key::KeySignature> {
1747 measure
1748 .events()
1749 .iter()
1750 .find_map(|event| match event.element() {
1751 StreamElement::KeySignature(signature) if event.offset() == 0.0 => {
1752 Some(signature.clone())
1753 }
1754 StreamElement::Key(key) if event.offset() == 0.0 => Some(key.key_signature()),
1755 _ => None,
1756 })
1757}
1758
1759fn diatonic_names(signature: &crate::key::KeySignature) -> Vec<String> {
1762 signature
1763 .scale("major")
1764 .and_then(|scale| scale.pitches())
1765 .map(|pitches| pitches.iter().map(Pitch::name).collect())
1766 .unwrap_or_default()
1767}
1768
1769fn pitches_in_order(stream: &Stream) -> Vec<Pitch> {
1773 let mut out = Vec::new();
1774 for event in stream.events() {
1775 match event.element() {
1776 StreamElement::Stream(inner) => out.extend(pitches_in_order(inner)),
1777 StreamElement::ChordSymbol(symbol) => {
1778 out.extend(symbol.pitches().unwrap_or_default());
1779 }
1780 element => out.extend(element.pitches()),
1781 }
1782 }
1783 out
1784}
1785
1786pub fn make_accidentals(stream: &mut Stream) {
1797 make_accidentals_by(stream, true);
1798}
1799
1800pub(crate) fn make_accidentals_by(stream: &mut Stream, cautionary_not_immediate_repeat: bool) {
1804 let part_like = |element: &StreamElement| {
1805 element
1806 .as_stream()
1807 .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
1808 };
1809 let mut events = stream.events().to_vec();
1810 if events.iter().any(|event| part_like(event.element())) {
1811 for event in &mut events {
1812 if let StreamElement::Stream(inner) = event.element_mut() {
1813 make_accidentals_by(inner, cautionary_not_immediate_repeat);
1814 }
1815 }
1816 let spanners = stream.spanners().to_vec();
1817 *stream = stream.with_events(events);
1818 for spanner in spanners {
1819 stream.add_spanner(spanner);
1820 }
1821 return;
1822 }
1823
1824 let mut signature: Option<crate::key::KeySignature> = None;
1825 let mut diatonic: Vec<String> = Vec::new();
1826 let mut past_measure: Vec<Pitch> = Vec::new();
1827 let mut tied: Option<Vec<String>> = None;
1828 let mut previous: Option<(Vec<Pitch>, Option<Vec<String>>)> = None;
1831 for event in &mut events {
1832 let StreamElement::Stream(measure) = event.element_mut() else {
1833 continue;
1834 };
1835 if measure.kind() != StreamKind::Measure {
1836 continue;
1837 }
1838 let own = key_signature_in(measure);
1839 if let Some((pitches, open)) = &previous {
1840 if own.is_none() {
1841 past_measure = pitches.clone();
1842 } else if signature.is_some() {
1843 past_measure = pitches
1844 .iter()
1845 .filter(|pitch| !diatonic.contains(&pitch.name()))
1846 .cloned()
1847 .collect();
1848 }
1849 if let Some(open) = open {
1850 tied = Some(if own.is_some() {
1854 Vec::new()
1855 } else {
1856 open.clone()
1857 });
1858 }
1859 }
1860 if let Some(own) = own {
1861 diatonic = diatonic_names(&own);
1862 signature = Some(own);
1863 }
1864 let altered = signature
1865 .as_ref()
1866 .and_then(|signature| signature.altered_pitches().ok())
1867 .unwrap_or_default();
1868
1869 let mut past: Vec<Pitch> = Vec::new();
1870 let mut open: Vec<String> = tied.clone().unwrap_or_default();
1871 let mut last_sounding: Option<Vec<String>> = None;
1872 let mut ornamental: Vec<Pitch> = Vec::new();
1876 let in_force = signature.clone().unwrap_or_else(|| KeySignature::new(0));
1877 measure.for_each_mut(&mut |_, element| match element {
1878 StreamElement::Note(note) => {
1879 let mut pitch = note.pitch().clone();
1880 pitch.update_accidental_display(&AccidentalDisplayOptions {
1881 pitch_past: &past,
1882 pitch_past_measure: &past_measure,
1883 altered_pitches: &altered,
1884 last_note_was_tied: open.contains(&pitch.name_with_octave()),
1885 cautionary_not_immediate_repeat,
1886 ..AccidentalDisplayOptions::default()
1887 });
1888 note.set_pitch(pitch.clone());
1889 open.clear();
1890 if note
1891 .tie()
1892 .is_some_and(|tie| tie.tie_type() != TieType::Stop)
1893 {
1894 open.push(pitch.name_with_octave());
1895 }
1896 last_sounding = Some(open.clone());
1897 past.push(pitch);
1898 let played = ornaments_decided(
1901 note,
1902 &in_force,
1903 &past,
1904 &past_measure,
1905 &altered,
1906 cautionary_not_immediate_repeat,
1907 );
1908 past.extend(played.iter().cloned());
1909 ornamental.extend(played);
1910 }
1911 StreamElement::Chord(chord) => {
1912 let mut seen: Vec<String> = Vec::new();
1913 for index in 0..chord.notes().len() {
1914 let others: Vec<Pitch> = chord
1915 .notes()
1916 .iter()
1917 .enumerate()
1918 .filter(|(other, _)| *other != index)
1919 .map(|(_, note)| note.pitch().clone())
1920 .collect();
1921 let note = &mut chord.notes_mut()[index];
1922 let mut pitch = note.pitch().clone();
1923 pitch.update_accidental_display(&AccidentalDisplayOptions {
1924 pitch_past: &past,
1925 pitch_past_measure: &past_measure,
1926 other_simultaneous_pitches: &others,
1927 altered_pitches: &altered,
1928 last_note_was_tied: open.contains(&pitch.name_with_octave()),
1929 cautionary_not_immediate_repeat,
1930 ..AccidentalDisplayOptions::default()
1931 });
1932 note.set_pitch(pitch.clone());
1933 if note
1934 .tie()
1935 .is_some_and(|tie| tie.tie_type() != TieType::Stop)
1936 {
1937 seen.push(pitch.name_with_octave());
1938 }
1939 let played = ornaments_decided(
1940 note,
1941 &in_force,
1942 &past,
1943 &past_measure,
1944 &altered,
1945 cautionary_not_immediate_repeat,
1946 );
1947 ornamental.extend(played);
1948 }
1949 open = seen;
1950 last_sounding = Some(open.clone());
1951 past.extend(chord.notes().iter().map(|note| note.pitch().clone()));
1952 }
1953 StreamElement::ChordSymbol(symbol) => {
1954 let mut sounded = symbol.pitches().unwrap_or_default();
1958 for index in 0..sounded.len() {
1959 let others: Vec<Pitch> = sounded
1960 .iter()
1961 .enumerate()
1962 .filter(|(other, _)| *other != index)
1963 .map(|(_, pitch)| pitch.clone())
1964 .collect();
1965 let tied = open.contains(&sounded[index].name_with_octave());
1966 sounded[index].update_accidental_display(&AccidentalDisplayOptions {
1967 pitch_past: &past,
1968 pitch_past_measure: &past_measure,
1969 other_simultaneous_pitches: &others,
1970 altered_pitches: &altered,
1971 last_note_was_tied: tied,
1972 ..AccidentalDisplayOptions::default()
1973 });
1974 }
1975 let given = |named: &Pitch| {
1978 sounded
1979 .iter()
1980 .find(|pitch| {
1981 pitch.step() == named.step() && pitch.alter() == named.alter()
1982 })
1983 .and_then(Pitch::written_accidental)
1984 .cloned()
1985 };
1986 if symbol.root().written_accidental().is_none()
1987 && let Some(accidental) = given(symbol.root())
1988 {
1989 let mut root = symbol.root().clone();
1990 root.set_written_accidental(Some(accidental));
1991 symbol.set_root(root);
1992 }
1993 if let Some(bass) = symbol.bass().cloned()
1994 && bass.written_accidental().is_none()
1995 && let Some(accidental) = given(&bass)
1996 {
1997 let mut bass = bass;
1998 bass.set_written_accidental(Some(accidental));
1999 symbol.set_bass(Some(bass));
2000 }
2001 open.clear();
2002 last_sounding = Some(Vec::new());
2003 past.extend(sounded);
2004 }
2005 StreamElement::Rest(_) => open.clear(),
2006 StreamElement::Unpitched(_) | StreamElement::PercussionChord(_) => {
2007 open.clear();
2008 last_sounding = Some(Vec::new());
2009 }
2010 _ => {}
2011 });
2012 tied = Some(open);
2013 let mut held = pitches_in_order(measure);
2014 held.extend(ornamental);
2015 previous = Some((held, last_sounding));
2016 }
2017 *stream = stream.with_events(events);
2018}
2019
2020#[cfg(test)]
2021mod tests {
2022 use super::*;
2023 use crate::{Duration, Note};
2024
2025 fn eighths(names: &[&str]) -> Stream {
2026 let mut measure = Stream::with_kind(StreamKind::Measure);
2027 measure.insert(0.0, Clef::treble());
2028 measure.insert(0.0, TimeSignature::new(2, 4).unwrap());
2029 for (index, name) in names.iter().enumerate() {
2030 let note = Note::from_name(name)
2031 .unwrap()
2032 .with_duration(Duration::eighth());
2033 measure.insert(index as FloatType * 0.5, note);
2034 }
2035 measure
2036 }
2037
2038 fn beams_and_stems(measure: &Stream) -> Vec<(Option<BeamType>, StemDirection)> {
2039 measure
2040 .events()
2041 .iter()
2042 .filter_map(|event| match event.element() {
2043 StreamElement::Note(note) => Some((
2044 note.beams().by_number(1).and_then(|beam| beam.beam_type()),
2045 note.stem_direction(),
2046 )),
2047 _ => None,
2048 })
2049 .collect()
2050 }
2051
2052 #[test]
2053 fn eighths_are_beamed_by_the_beat_and_stemmed_together() {
2054 let mut part = Stream::with_kind(StreamKind::Part);
2057 part.insert(0.0, eighths(&["C5", "D5", "E4", "F4"]));
2058 make_beams(&mut part).unwrap();
2059 let measure = part.measures()[0];
2060 assert_eq!(
2061 beams_and_stems(measure),
2062 [
2063 (Some(BeamType::Start), StemDirection::Down),
2064 (Some(BeamType::Stop), StemDirection::Down),
2065 (Some(BeamType::Start), StemDirection::Up),
2066 (Some(BeamType::Stop), StemDirection::Up),
2067 ]
2068 );
2069 }
2070
2071 #[test]
2072 fn a_measure_with_no_meter_is_left_alone() {
2073 let mut measure = Stream::with_kind(StreamKind::Measure);
2074 for (index, name) in ["C4", "D4"].iter().enumerate() {
2075 let note = Note::from_name(name)
2076 .unwrap()
2077 .with_duration(Duration::eighth());
2078 measure.insert(index as FloatType * 0.5, note);
2079 }
2080 let mut part = Stream::with_kind(StreamKind::Part);
2081 part.insert(0.0, measure);
2082 make_beams(&mut part).unwrap();
2083 assert!(
2084 beams_and_stems(part.measures()[0])
2085 .iter()
2086 .all(|(beam, stem)| beam.is_none() && *stem == StemDirection::Unspecified)
2087 );
2088 }
2089}
2090
2091#[cfg(test)]
2092mod realize_tests {
2093 use super::*;
2094 use crate::expressions::{Ornament, OrnamentKind};
2095 use crate::{Chord, Duration, Note};
2096
2097 fn described(stream: &Stream) -> Vec<String> {
2098 stream
2099 .events()
2100 .iter()
2101 .map(|event| match event.element() {
2102 StreamElement::Stream(inner) => {
2103 format!("[{}]", described(inner).join(" "))
2104 }
2105 StreamElement::Note(note) => format!(
2106 "{}@{}",
2107 note.pitch().name_with_octave(),
2108 note.duration().map_or(0.0, Duration::quarter_length)
2109 ),
2110 element => element
2111 .music21_classes()
2112 .first()
2113 .copied()
2114 .unwrap_or("other")
2115 .to_string(),
2116 })
2117 .collect()
2118 }
2119
2120 fn ornamented(name: &str, length: FloatType, kinds: &[OrnamentKind]) -> Note {
2121 let mut note = Note::from_name(name)
2122 .unwrap()
2123 .with_duration(Duration::new(length).unwrap());
2124 for kind in kinds {
2125 note.expressions_mut().push(Ornament::of_kind(*kind).into());
2126 }
2127 note
2128 }
2129
2130 #[test]
2131 fn a_mordent_is_played_where_the_note_stood() {
2132 let mut first = Stream::with_kind(StreamKind::Measure);
2136 first.insert(0.0, TimeSignature::new(4, 4).unwrap());
2137 first.push(ornamented("C4", 4.0, &[OrnamentKind::Mordent]));
2138 let mut second = Stream::with_kind(StreamKind::Measure);
2139 second.push(
2140 Note::from_name("D4")
2141 .unwrap()
2142 .with_duration(Duration::new(4.0).unwrap()),
2143 );
2144 let mut score = Stream::new();
2145 score.push(first);
2146 score.push(second);
2147 let realized = realize_ornaments(&score).unwrap();
2148 assert_eq!(
2149 described(&realized),
2150 [
2151 "[TimeSignature C4@0.125 B3@0.125 C4@3.75]".to_string(),
2152 "[D4@4]".to_string()
2153 ]
2154 );
2155 }
2156
2157 #[test]
2158 fn a_note_carrying_two_ornaments_is_heard_twice() {
2159 let mut measure = Stream::with_kind(StreamKind::Measure);
2162 measure.push(ornamented(
2163 "C4",
2164 2.0,
2165 &[OrnamentKind::Mordent, OrnamentKind::InvertedMordent],
2166 ));
2167 let realized = realize_ornaments(&measure).unwrap();
2168 assert_eq!(
2169 described(&realized).join(" "),
2170 "C4@0.125 B3@0.125 C4@1.75 C4@0.125 D4@0.125 C4@1.75"
2171 );
2172 }
2173
2174 #[test]
2175 fn the_key_in_force_says_what_the_neighbour_is() {
2176 let mut measure = Stream::with_kind(StreamKind::Measure);
2180 measure.insert(0.0, KeySignature::new(-3));
2181 measure.push(ornamented("A4", 0.5, &[OrnamentKind::Trill]));
2182 let realized = realize_ornaments(&measure).unwrap();
2183 assert_eq!(
2184 described(&realized).join(" "),
2185 "KeySignature A4@0.125 Bb4@0.125 A4@0.125 Bb4@0.125"
2186 );
2187 }
2188
2189 #[test]
2190 fn an_ornament_on_a_chord_is_refused() {
2191 let mut measure = Stream::with_kind(StreamKind::Measure);
2194 let mut chord = Chord::new("C4 E4 G4").unwrap();
2195 chord.set_duration(Duration::new(1.0).unwrap());
2196 chord
2197 .expressions_mut()
2198 .push(Ornament::of_kind(OrnamentKind::Mordent).into());
2199 measure.push(chord);
2200 assert!(realize_ornaments(&measure).is_err());
2201 }
2202}
2203
2204#[cfg(test)]
2205mod ornamental_tests {
2206 use super::*;
2207 use crate::expressions::{Ornament, OrnamentKind};
2208 use crate::{Duration, Note};
2209
2210 fn trilled(name: &str) -> Note {
2211 let mut note = Note::from_name(name)
2212 .unwrap()
2213 .with_duration(Duration::new(1.0).unwrap());
2214 note.expressions_mut()
2215 .push(Ornament::of_kind(OrnamentKind::Trill).into());
2216 note
2217 }
2218
2219 fn shown(note: &Note) -> Option<String> {
2220 let Some(crate::expressions::Expression::Ornament(ornament)) = note.expressions().first()
2221 else {
2222 return None;
2223 };
2224 ornament
2225 .accidental()
2226 .map(|accidental| format!("{} {:?}", accidental.name(), accidental.display_status()))
2227 }
2228
2229 #[test]
2230 fn a_trill_above_a_flat_already_heard_shows_a_natural() {
2231 let mut note = trilled("A4");
2234 let past = [crate::Pitch::from_name("Bb4").unwrap()];
2235 let played = make_ornamental_accidentals(
2236 &mut note,
2237 &KeySignature::new(0),
2238 &AccidentalDisplayOptions {
2239 pitch_past: &past,
2240 ..AccidentalDisplayOptions::default()
2241 },
2242 )
2243 .expect("the trill plays its neighbour");
2244 assert_eq!(
2245 played
2246 .iter()
2247 .map(crate::Pitch::name_with_octave)
2248 .collect::<Vec<_>>(),
2249 ["B4".to_string()]
2250 );
2251 assert_eq!(shown(¬e).as_deref(), Some("natural Some(true)"));
2252 }
2253
2254 #[test]
2255 fn a_trill_whose_neighbour_needs_nothing_says_nothing() {
2256 let mut note = trilled("A4");
2257 let played = make_ornamental_accidentals(
2258 &mut note,
2259 &KeySignature::new(0),
2260 &AccidentalDisplayOptions::default(),
2261 )
2262 .expect("the trill plays its neighbour");
2263 assert_eq!(played.len(), 1);
2264 assert_eq!(shown(¬e), None);
2267 }
2268
2269 #[test]
2270 fn an_ornament_of_a_fixed_size_is_left_as_it_stands() {
2271 let mut note = Note::from_name("A4")
2275 .unwrap()
2276 .with_duration(Duration::new(1.0).unwrap());
2277 note.expressions_mut()
2278 .push(Ornament::of_kind(OrnamentKind::HalfStepTrill).into());
2279 let past = [crate::Pitch::from_name("Bb4").unwrap()];
2280 let played = make_ornamental_accidentals(
2281 &mut note,
2282 &KeySignature::new(0),
2283 &AccidentalDisplayOptions {
2284 pitch_past: &past,
2285 ..AccidentalDisplayOptions::default()
2286 },
2287 )
2288 .expect("the trill plays its neighbour");
2289 assert_eq!(played.len(), 1);
2290 assert_eq!(shown(¬e), None);
2291 }
2292}