Skip to main content

music21_rs/makenotation/
mod.rs

1//! Working out what a score leaves unsaid: music21's `stream.makeNotation`.
2//!
3//! What a reader of another format needs is here: cutting a line into
4//! measures, tying what runs past a barline, filling measures out with
5//! rests, putting overlapping notes in voices, moving notes onto a grid,
6//! beaming the notes of each measure by its meter and pointing the stems of
7//! each beamed group one way.
8//!
9//! [`make_notation`] is the whole of it in music21's order, for a score
10//! that says only what sounds: measures, accidentals, ties, tuplets
11//! completed and bracketed, beams. [`split_at_durations`] cuts a length no
12//! single note value writes into values that do.
13
14use 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
44/// [`make_ornamental_accidentals`] for one note of a measure being
45/// decided, with what it answered where it could.
46///
47/// An ornament whose notes cannot be worked out at all -- a general
48/// mordent that has not said which way it goes -- is left as it stands and
49/// counts for nothing, where music21 raises out of the whole step; nothing
50/// any reader here builds carries one.
51fn 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
76/// Decides whether each accidental this note's ornaments imply is shown,
77/// and writes it onto the ornament: music21's
78/// `makeOrnamentalAccidentals`.
79///
80/// The notes an ornament plays are read in `key`, decided as
81/// [`Ornament::update_accidental_display`] decides them -- never
82/// simultaneous with anything and never tied, an ornamental note being
83/// neither -- and what is decided is written back onto the ornament's own
84/// accidental, which is where the MusicXML writer reads the mark from.
85/// The pitches decided are answered in music21's order, so a caller can
86/// count them among the pitches already heard, as music21's step adds them
87/// to `pitchPast`.
88///
89/// An ornament of a fixed size -- a half-step trill, a whole-step mordent
90/// -- carries no accidental of its own, so there is nowhere here to write
91/// the decision and the ornament is left as it stands. music21 keeps it on
92/// the pitch it resolved, which a value type does not hold.
93///
94/// # Errors
95///
96/// A general mordent that has not said which way it goes, whose notes
97/// cannot be worked out at all.
98pub 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
120/// The accidentals decided for an ornament's notes written onto the
121/// ornament itself, in the order [`Ornament::ornamental_pitches`] answers
122/// them: a turn's upper note and then its lower, and the one note of
123/// anything else.
124fn 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        // A half-step or whole-step ornament refuses one, its interval
138        // being fixed, and is left as it stands.
139        let _ = ornament.set_accidental(Some(accidental));
140    }
141}
142
143/// Every ornament the stream carries played out, in a stream of its own:
144/// music21's `stream.makeNotation.realizeOrnaments`.
145///
146/// The answer is this stream's [`Stream::clone_empty`] with each element
147/// appended after the one before and every nested stream realized the same
148/// way, so a gap between two elements closes -- which is what music21 does
149/// and what the comment in its own source calls a thing to fix. A note
150/// carrying ornaments is replaced by the notes each of them plays, read in
151/// the key signature in force where the note stands, and nothing else by
152/// nothing: an ornament is handed the note *as it stands* rather than what
153/// the ornament before it left, so a note carrying two is heard twice,
154/// once for each.
155///
156/// That is not [`crate::expressions::realize_ornaments`], which is
157/// music21's function of the same name in its `expressions` module: there
158/// the ornaments of one note are chained, each playing what the one before
159/// left.
160///
161/// # Errors
162///
163/// An ornament on anything but a note -- a chord, a rest, an unpitched
164/// stroke -- which music21 cannot play either, since it asks whatever it
165/// is given for its one pitch. And any ornament that cannot play the note
166/// it is on.
167pub fn realize_ornaments(stream: &Stream) -> Result<Stream> {
168    let mut in_force = None;
169    realized_ornaments(stream, &mut in_force)
170}
171
172/// [`realize_ornaments`], carrying the key signature in force into the
173/// streams nested inside this one -- which is the key music21's ornaments
174/// find by asking the note they are on for its context.
175fn 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
198/// One element of a stream appended to `realized`: the notes its ornaments
199/// play, or the element as it stands where it carries none.
200fn 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    // A key the stream never stated is no sharps, as music21's ornaments
234    // take when the note has no key signature in its context.
235    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
252/// Beams the notes of every measure of a part by the meter in force, and
253/// points the stems of each beamed group one way: music21's `makeBeams`.
254///
255/// A stream that is a measure is beamed itself. The meter in force is the
256/// last one stated by a measure or standing in the part at or before the
257/// measure. A measure with none, or holding more than its bar's length, is
258/// left as it is; grace
259/// notes are passed over. A measure is beamed voice by voice where it has
260/// voices.
261///
262/// An error stops the beaming where it stands, leaving the measures before
263/// it beamed and no stems set, as an exception in music21's does.
264pub 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        // The meters standing in the part itself, outside any measure.
272        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        // The last meter a measure stated, and where that measure began.
281        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
308/// The meter a measure opens with: music21's `timeSignature`, which is the
309/// one standing at the very start and no other.
310fn 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
342/// Beams one line of notes: a measure with no voices, or one voice. The
343/// padding is the measure's, left and right.
344fn beam_line(
345    line: &mut Stream,
346    meter: &TimeSignature,
347    (padding_left, padding_right): (FloatType, FloatType),
348) -> Result<()> {
349    // music21's `notesAndRests`, which takes a chord symbol for a note.
350    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            // The written value, which a tuplet leaves standing.
389            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    // A hair of latitude for lengths no float spells exactly.
401    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    // A measure padded on the left starts that far into its bar, and one
409    // padded on the right at its start; a short measure saying neither is
410    // taken as ending with the bar, a pickup.
411    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    // music21 reads each note's written value to beam it, and a copy of a
421    // duration whose one value has been read keeps that value as said. Every
422    // step that asks whether a length may be written another way works on
423    // such a copy, so the reading is recorded here.
424    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(&notes, 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
452/// One note or chord as the stem walk sees it.
453struct Stemmed {
454    /// The indices down through the nested streams to the element.
455    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
510/// Points the stems of each beamed group the way its first and last pitches
511/// lie about the middle line of the clef in force: music21's
512/// `setStemDirectionForBeamGroups`.
513///
514/// A group runs from a note whose first beam starts to the one whose first
515/// beam stops. Stems a score already points all one way are left alone, and
516/// a group with no clef before it is not touched.
517pub 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| &notes[*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 = &notes[*index];
575            if !settable(note.direction) {
576                continue;
577            }
578            if note.direction != StemDirection::Unspecified && consistent {
579                continue;
580            }
581            set_direction(stream, &note.path, direction);
582        }
583    }
584}
585
586/// One element waiting for its measure.
587struct Placed {
588    offset: FloatType,
589    end: FloatType,
590    voice: Option<usize>,
591    element: StreamElement,
592}
593
594/// A measure while it is being filled.
595struct Bar {
596    start: FloatType,
597    end: FloatType,
598    own: Vec<StreamEvent>,
599    voices: Vec<Vec<StreamEvent>>,
600}
601
602/// Snaps an offset as music21's `opFrac` does, to the nearest fraction with
603/// a denominator up to 65535, so that three triplets end on the beat. A
604/// negative offset is snapped as its size is.
605pub 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
622/// Sorts events as music21 sorts a stream: by offset, then by class, grace
623/// notes first, then in the order given.
624pub(crate) fn sorted_events(mut events: Vec<StreamEvent>) -> Vec<StreamEvent> {
625    events.sort_by(event_order);
626    events
627}
628
629/// Puts an element into a stream where music21's sort puts it: after
630/// everything that sorts no later.
631#[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
647/// The order music21 sorts two things standing in one stream in, leaving
648/// equals in the order they were put there.
649pub(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
675/// Cuts a stream into measures by the meters it holds: music21's
676/// `makeMeasures`.
677///
678/// A stream holding parts has each of them cut. Otherwise the stream is
679/// flattened, unless it holds voices, which are kept as the voices of each
680/// measure. A stream with no meter at its start is in `4/4` until it says
681/// otherwise. The first measure takes the clef standing at the start, or the
682/// one that fits the notes best; each measure where the meter changes states
683/// it; the last ends with a final barline. A note is put in the measure it
684/// starts in and is not cut where it runs past the barline.
685///
686/// Spanners are not carried across, as the places they name move.
687///
688/// ```
689/// use music21_rs::makenotation::make_measures;
690/// use music21_rs::{Duration, Note, Stream, TimeSignature};
691///
692/// let mut line = Stream::new();
693/// line.insert(0.0, TimeSignature::new(3, 4)?);
694/// for (place, name) in ["C4", "D4", "E4", "F4"].iter().enumerate() {
695///     let note = Note::from_name(name)?.with_duration(Duration::quarter());
696///     line.insert(place as f64, note);
697/// }
698/// let measured = make_measures(&line)?;
699/// assert_eq!(measured.measures().len(), 2);
700/// assert_eq!(measured.measures()[1].number(), 2);
701/// # Ok::<(), music21_rs::Error>(())
702/// ```
703pub fn make_measures(stream: &Stream) -> Result<Stream> {
704    make_measures_by(stream, &[])
705}
706
707/// [`make_measures`] by meters given rather than found: music21's
708/// `makeMeasures` with a `meterStream`. Each meter is given with the offset
709/// it takes over at; with none given the stream's own are used.
710pub 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    // Everything the stream holds, with where it starts and ends and which
731    // voice it is in.
732    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    // The meters, with 4/4 at the start where the stream says nothing there.
757    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    // The clef at the start, which the first measure takes and which is then
774    // not placed a second time.
775    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    // The measures, empty: where each starts and ends, and what it opens
810    // with.
811    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            // music21 copies the key in beside the one placed below.
827            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            // Something with no length standing at the very end is kept
860            // after the measures.
861            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
907/// Whether an element is a note, a chord, a rest or a stroke: music21's
908/// `GeneralNote`, which a chord symbol is one of.
909pub(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
921/// Whether an element sounds: music21's `NotRest`.
922pub(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
932/// Gives an element a new length, keeping whatever else it says.
933fn 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
946/// The tie a split leaves on the first piece, and the type of the one the
947/// second piece takes.
948fn 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
968/// The second piece of a split note does not show its accidental again.
969fn 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
983/// An element cut in two at a length into it, the pieces tied: music21's
984/// `splitAtQuarterLength`.
985///
986/// The second piece carries no lyrics, and each mark goes to the piece it is
987/// attached to. A rest and a chord of strokes are cut without ties.
988pub(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    // Marks stay with the piece they are attached to.
996    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            // A chord's lyrics are kept on its first note.
1053            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
1090/// music21's `nearestMultiple`: the multiple of a unit nearest a number, how
1091/// far off it is, and which way.
1092fn 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
1104/// The best place on the grids for a length or an offset: music21's
1105/// `bestMatch`. The answer is what is left of the gap, the error, the unit
1106/// and the match, in the order they are compared.
1107fn 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
1143/// The divisions of a quarter music21 quantizes to unless told otherwise:
1144/// sixteenths and triplet eighths.
1145pub const QUANTIZATION_DIVISORS: [u32; 2] = [4, 3];
1146
1147/// Moves every offset and length in a stream onto the nearest place a
1148/// quarter divides into: music21's `quantize`, for the stream's own elements.
1149///
1150/// `divisors` are the ways a quarter may be divided, `[4, 3]` for sixteenths
1151/// and triplets. Where two grids are as near, the one that leaves no gap
1152/// before the next element wins, then the nearer, then the finer. A note is
1153/// never quantized to no length at all, though a grace note stays one.
1154pub 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        // The next element that lands later than this one says how much
1171        // room there is to fill.
1172        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            // Marked for removal below by an offset no element can have.
1187            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
1195/// music21's `_findLayering` and `_consolidateLayering`, for how many of a
1196/// line's notes sound at once at the most.
1197fn 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    // Groups by the offset they were first gathered under.
1221    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
1257/// Puts a measure's notes into voices where they overlap: music21's
1258/// `makeVoices` with `fillGaps=False`.
1259///
1260/// There are as many voices as notes sounding at once at the most, and each
1261/// note goes to the first voice that has finished by the time it starts. A
1262/// note no voice is free for is lost, as it is there. A measure whose notes
1263/// never overlap is left alone.
1264pub 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            // Rests go, as `removeByClass('Rest')` takes them.
1280            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
1303/// Every meter a part states, at its offset from the part's start, with
1304/// `4/4` at the start where the part says nothing there.
1305fn 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    // A meter standing again is the object the earlier measure holds, and
1316    // music21's list of meters keeps one place for one object: the last it
1317    // stands at. Each such meter and the one it restates are moved there.
1318    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
1345/// Takes the voices with nothing in them out of a measure, and where one
1346/// voice is left puts its notes in the measure itself: music21's
1347/// `flattenUnnecessaryVoices`.
1348fn 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
1386/// Cuts every note that runs past its barline and ties the pieces, the
1387/// second going to the start of the next measure: music21's `makeTies`.
1388///
1389/// A stream holding parts has each of them done. The stream must already be
1390/// in measures. A piece cut from a voice goes to the voice of the same name
1391/// in the next measure, or to the measure itself where there is none; one
1392/// cut from a measure with no voices goes to the next measure's first voice
1393/// where it has any.
1394pub 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        // What is cut off, with the name of the voice it was cut from.
1454        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                // The notes of the next measure are gathered into a voice of
1519                // their own, and the piece joins its first voice.
1520                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
1558/// Fills one line out with rests from `low` to `high`: before its first
1559/// element, after its last, and in every gap between. `hidden` rests are
1560/// left unprinted.
1561pub(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
1599/// Fills every measure of a part with rests up to its bar's length, its
1600/// voices too: music21's `makeRests` with `fillGaps=True` and
1601/// `timeRangeFromBarDuration=True`.
1602///
1603/// A stream holding parts has each of them filled. A measure padded as a
1604/// pickup, or cut short, is filled only as far as its padding leaves. The
1605/// measures are then put one after another by what each holds.
1606pub fn make_rests(stream: &mut Stream) -> Result<()> {
1607    fill_rests(stream, None, false)
1608}
1609
1610/// music21's `makeRests` with `fillGaps=True` and
1611/// `timeRangeFromBarDuration=True`, rests `hidden` or not. A stream with no
1612/// measures is filled over `range`, or from its start to its end where none
1613/// is given.
1614pub(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    // The meters standing in the part itself, outside any measure.
1682    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        // A measure no meter has been stated for takes the one standing in
1702        // the part before it, and failing that is as long as the meter that
1703        // fits what it holds: music21's `barDuration`.
1704        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
1744/// The key signature a measure opens with: a key or a signature standing at
1745/// its very start.
1746fn 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
1759/// The names of the notes a key signature leaves unaltered or alters: the
1760/// major scale it is the signature of.
1761fn 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
1769/// Every pitch a stream holds, element by element and each nested stream
1770/// where it stands, the notes a chord symbol stands for among them:
1771/// music21's `Stream.pitches`.
1772fn 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
1786/// Decides which accidentals are written, measure by measure: music21's
1787/// `makeAccidentals` on a part.
1788///
1789/// A stream holding parts has each of them done. An accidental is written
1790/// where the key signature in force does not already say it, where the same
1791/// note has just been written otherwise in this measure or the one before,
1792/// and not where the note is tied from the one before. A key signature is in
1793/// force from the measure that opens with it.
1794///
1795/// The accidentals an ornament implies are not considered.
1796pub fn make_accidentals(stream: &mut Stream) {
1797    make_accidentals_by(stream, true);
1798}
1799
1800/// [`make_accidentals`] with music21's `cautionaryNotImmediateRepeat` said:
1801/// whether an altered note written again later in its measure, not straight
1802/// after, shows its accidental again.
1803pub(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    // What the measure before held: its pitches, and the ties its last
1829    // sounding element left open.
1830    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                // A tie does not reach across a new key signature: music21
1851                // asks whether the tied note, octave and all, is a name of
1852                // the new key, which it never is.
1853                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        // What the ornaments of this measure play, which counts among the
1873        // pitches the measure after it is decided against, as music21's
1874        // `makeAccidentalsInMeasureStream` counts them.
1875        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                // The accidentals this note's ornaments imply, decided
1899                // against what has been heard including the note itself.
1900                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                // A chord symbol is a chord to music21: each note it stands
1955                // for is decided like a chord's, and counts among those
1956                // already heard.
1957                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                // The root and the bass are notes of that chord, so a
1976                // natural one of them is given is the root's or the bass's.
1977                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        // music21: 2/4 with C5 D5 E4 F4 beams in pairs, the high pair down
2055        // and the low pair up.
2056        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        // music21's own docstring: the measure holding a whole C with a
2133        // mordent comes out holding C, B and C, and the measure after it
2134        // is untouched.
2135        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        // music21 hands each ornament the note as it stands, so the note
2160        // is played once for each: C B C, then C D C.
2161        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        // A trill on A in three flats plays the B flat above it, as
2177        // music21's does once it has asked the note for the key in its
2178        // context (where the note is spelled `B-`).
2179        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        // music21 asks whatever it is given for its one pitch, so a chord
2192        // raises there too.
2193        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        // music21 writes an `<accidental-mark>natural</accidental-mark>`
2232        // for this trill, the B flat before it having been heard.
2233        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(&note).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        // The ornament is left carrying nothing, so the writer writes no
2265        // mark for it.
2266        assert_eq!(shown(&note), None);
2267    }
2268
2269    #[test]
2270    fn an_ornament_of_a_fixed_size_is_left_as_it_stands() {
2271        // A half-step trill holds no accidental of its own, so there is
2272        // nowhere to write the decision; music21 keeps it on the pitch it
2273        // resolved.
2274        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(&note), None);
2291    }
2292}