Skip to main content

music21/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
31pub(crate) use score::{
32    Kept, beams_made, element_at_durations, keeping_spanners, make_measure_notation,
33    make_part_notation_by, make_part_notation_keeping_spanners,
34};
35pub use score::{
36    accidentals_made, consolidate_completed_tuplets, make_notation, make_tuplet_brackets,
37    split_at_durations, split_elements_to_complete_tuplets,
38};
39#[cfg(feature = "musicxml")]
40pub(crate) use score::{for_each_measure, make_part_notation, tuplet_brackets_made};
41
42/// [`make_ornamental_accidentals`] for one note of a measure being
43/// decided, with what it answered where it could.
44///
45/// An ornament whose notes cannot be worked out at all -- a general
46/// mordent that has not said which way it goes -- is left as it stands and
47/// counts for nothing, where music21 raises out of the whole step; nothing
48/// any reader here builds carries one.
49fn ornaments_decided(
50    note: &mut Note,
51    key: &KeySignature,
52    past: &[Pitch],
53    past_measure: &[Pitch],
54    altered: &[Pitch],
55    cautionary_not_immediate_repeat: bool,
56) -> Vec<Pitch> {
57    if note.expressions().is_empty() {
58        return Vec::new();
59    }
60    make_ornamental_accidentals(
61        note,
62        key,
63        &AccidentalDisplayOptions {
64            pitch_past: past,
65            pitch_past_measure: past_measure,
66            altered_pitches: altered,
67            cautionary_not_immediate_repeat,
68            ..AccidentalDisplayOptions::default()
69        },
70    )
71    .unwrap_or_default()
72}
73
74/// Decides whether each accidental this note's ornaments imply is shown,
75/// and writes it onto the ornament: music21's
76/// `makeOrnamentalAccidentals`.
77///
78/// The notes an ornament plays are read in `key`, decided as
79/// [`Ornament::update_accidental_display`] decides them -- never
80/// simultaneous with anything and never tied, an ornamental note being
81/// neither -- and what is decided is written back onto the ornament's own
82/// accidental, which is where the MusicXML writer reads the mark from.
83/// The pitches decided are answered in music21's order, so a caller can
84/// count them among the pitches already heard, as music21's step adds them
85/// to `pitchPast`.
86///
87/// An ornament of a fixed size -- a half-step trill, a whole-step mordent
88/// -- carries no accidental of its own, so there is nowhere here to write
89/// the decision and the ornament is left as it stands. music21 keeps it on
90/// the pitch it resolved, which a value type does not hold.
91///
92/// # Errors
93///
94/// A general mordent that has not said which way it goes, whose notes
95/// cannot be worked out at all.
96pub fn make_ornamental_accidentals(
97    note: &mut Note,
98    key: &KeySignature,
99    options: &AccidentalDisplayOptions<'_>,
100) -> Result<Vec<Pitch>> {
101    let source = note.pitch().clone();
102    let mut decided = Vec::new();
103    for expression in note.expressions_mut() {
104        let Expression::Ornament(ornament) = expression else {
105            continue;
106        };
107        let mut played = ornament.ornamental_pitches(&source, key)?;
108        if played.is_empty() {
109            continue;
110        }
111        ornament.update_accidental_display(&mut played, options);
112        write_back(ornament, &played);
113        decided.extend(played);
114    }
115    Ok(decided)
116}
117
118/// The accidentals decided for an ornament's notes written onto the
119/// ornament itself, in the order [`Ornament::ornamental_pitches`] answers
120/// them: a turn's upper note and then its lower, and the one note of
121/// anything else.
122fn write_back(ornament: &mut Ornament, played: &[Pitch]) {
123    let shown = |pitch: &Pitch| -> Option<Accidental> {
124        let accidental = pitch.accidental();
125        accidental.display_status().map(|_| accidental.clone())
126    };
127    if ornament.is_a("Turn") {
128        if let Some(upper) = played.first().and_then(shown) {
129            ornament.set_upper_accidental(Some(upper));
130        }
131        if let Some(lower) = played.get(1).and_then(shown) {
132            ornament.set_lower_accidental(Some(lower));
133        }
134    } else if let Some(accidental) = played.first().and_then(shown) {
135        // A half-step or whole-step ornament refuses one, its interval
136        // being fixed, and is left as it stands.
137        let _ = ornament.set_accidental(Some(accidental));
138    }
139}
140
141/// Every ornament the stream carries played out, in a stream of its own:
142/// music21's `stream.makeNotation.realizeOrnaments`.
143///
144/// The answer is this stream's [`Stream::clone_empty`] with each element
145/// appended after the one before and every nested stream realized the same
146/// way, so a gap between two elements closes -- which is what music21 does
147/// and what the comment in its own source calls a thing to fix. A note
148/// carrying ornaments is replaced by the notes each of them plays, read in
149/// the key signature in force where the note stands, and nothing else by
150/// nothing: an ornament is handed the note *as it stands* rather than what
151/// the ornament before it left, so a note carrying two is heard twice,
152/// once for each.
153///
154/// That is not [`crate::expressions::realize_ornaments`], which is
155/// music21's function of the same name in its `expressions` module: there
156/// the ornaments of one note are chained, each playing what the one before
157/// left.
158///
159/// # Errors
160///
161/// An ornament on anything but a note -- a chord, a rest, an unpitched
162/// stroke -- which music21 cannot play either, since it asks whatever it
163/// is given for its one pitch. And any ornament that cannot play the note
164/// it is on.
165pub fn realize_ornaments(stream: &Stream) -> Result<Stream> {
166    let mut in_force = None;
167    realized_ornaments(stream, &mut in_force)
168}
169
170/// [`realize_ornaments`], carrying the key signature in force into the
171/// streams nested inside this one -- which is the key music21's ornaments
172/// find by asking the note they are on for its context.
173fn realized_ornaments(stream: &Stream, in_force: &mut Option<KeySignature>) -> Result<Stream> {
174    let mut realized = stream.clone_empty();
175    for event in stream.events() {
176        let element = event.element();
177        match element {
178            StreamElement::Stream(inner) => {
179                let inner = realized_ornaments(inner, in_force)?;
180                realized.push(StreamElement::Stream(Box::new(inner)));
181            }
182            StreamElement::KeySignature(signature) => {
183                *in_force = Some(signature.clone());
184                realized.push(element.clone());
185            }
186            StreamElement::Key(key) => {
187                *in_force = Some(key.key_signature());
188                realized.push(element.clone());
189            }
190            _ => played_into(element, in_force.as_ref(), &mut realized)?,
191        }
192    }
193    Ok(realized)
194}
195
196/// One element of a stream appended to `realized`: the notes its ornaments
197/// play, or the element as it stands where it carries none.
198fn played_into(
199    element: &StreamElement,
200    in_force: Option<&KeySignature>,
201    realized: &mut Stream,
202) -> Result<()> {
203    let expressions = match element {
204        StreamElement::Note(note) => note.expressions(),
205        StreamElement::Chord(chord) => chord.expressions(),
206        StreamElement::Rest(rest) => rest.expressions(),
207        StreamElement::Unpitched(unpitched) => unpitched.written().expressions(),
208        _ => &[],
209    };
210    let ornaments: Vec<&Ornament> = expressions
211        .iter()
212        .filter_map(|expression| match expression {
213            Expression::Ornament(ornament) => Some(&**ornament),
214            _ => None,
215        })
216        .collect();
217    if ornaments.is_empty() {
218        realized.push(element.clone());
219        return Ok(());
220    }
221    let StreamElement::Note(note) = element else {
222        return Err(Error::Expression(format!(
223            "Cannot realize an ornament on {}",
224            element
225                .music21_classes()
226                .first()
227                .copied()
228                .unwrap_or("that element")
229        )));
230    };
231    // A key the stream never stated is no sharps, as music21's ornaments
232    // take when the note has no key signature in its context.
233    let default = KeySignature::new(0);
234    let key = in_force.unwrap_or(&default);
235    for ornament in ornaments {
236        let played = ornament.realize(note, key)?;
237        for before in played.before {
238            realized.push(before);
239        }
240        if let Some(main) = played.main {
241            realized.push(main);
242        }
243        for after in played.after {
244            realized.push(after);
245        }
246    }
247    Ok(())
248}
249
250/// The notes a note or chord ties forward, by name: music21's
251/// `getTiePitchSet`.
252///
253/// Nothing at all where the element is no note -- a rest or a barline
254/// ties nothing, and music21 answers `None` for either -- and an empty
255/// list where it ties nothing on. A stroke with no pitch is left out, as
256/// music21 leaves it out, so a percussion chord of strokes alone ties
257/// nothing.
258pub fn tie_pitch_set(element: &StreamElement) -> Option<Vec<String>> {
259    let tied = |note: &Note| -> Option<String> {
260        note.tie()
261            .filter(|tie| tie.tie_type() != TieType::Stop)
262            .map(|_| note.pitch().name_with_octave())
263    };
264    match element {
265        StreamElement::Note(note) => Some(tied(note).into_iter().collect()),
266        StreamElement::Chord(chord) => Some(chord.notes().iter().filter_map(tied).collect()),
267        // A chord symbol is one of music21's `NotRest`s, so it answers a
268        // list; it realizes its notes from its figure and carries no tie
269        // on any of them.
270        StreamElement::ChordSymbol(_) | StreamElement::Unpitched(_) => Some(Vec::new()),
271        StreamElement::PercussionChord(chord) => Some(
272            chord
273                .members()
274                .iter()
275                .filter_map(|member| match member {
276                    crate::percussion::PercussionNote::Note(note) => tied(note),
277                    crate::percussion::PercussionNote::Unpitched(_) => None,
278                })
279                .collect(),
280        ),
281        _ => None,
282    }
283}
284
285/// Beams the notes of every measure of a part by the meter in force, and
286/// points the stems of each beamed group one way: music21's `makeBeams`.
287///
288/// A stream that is a measure is beamed itself. The meter in force is the
289/// last one stated by a measure or standing in the part at or before the
290/// measure. A measure with none, or holding more than its bar's length, is
291/// left as it is; grace
292/// notes are passed over. A measure is beamed voice by voice where it has
293/// voices.
294///
295/// An error stops the beaming where it stands, leaving the measures before
296/// it beamed and no stems set, as an exception in music21's does.
297pub fn make_beams(stream: &mut Stream) -> Result<()> {
298    if stream.kind() == StreamKind::Measure {
299        let meter = meter_in(stream);
300        if let Some(meter) = meter {
301            beam_measure(stream, &meter)?;
302        }
303    } else {
304        // The meters standing in the part itself, outside any measure.
305        let loose: Vec<(FloatType, TimeSignature)> = stream
306            .events()
307            .iter()
308            .filter_map(|event| match event.element() {
309                StreamElement::TimeSignature(meter) => Some((event.offset(), meter.clone())),
310                _ => None,
311            })
312            .collect();
313        // The last meter a measure stated, and where that measure began.
314        let mut stated: Option<(FloatType, TimeSignature)> = None;
315        for event in stream.events_mut() {
316            let offset = event.offset();
317            let StreamElement::Stream(measure) = event.element_mut() else {
318                continue;
319            };
320            if measure.kind() != StreamKind::Measure {
321                continue;
322            }
323            if let Some(own) = meter_in(measure) {
324                stated = Some((offset, own));
325            }
326            let outside = loose.iter().rev().find(|(at, _)| *at <= offset + 1e-9);
327            let meter = match (&stated, outside) {
328                (Some((at, _)), Some((loose_at, meter))) if loose_at > at => Some(meter),
329                (Some((_, meter)), _) => Some(meter),
330                (None, outside) => outside.map(|(_, meter)| meter),
331            };
332            if let Some(meter) = meter {
333                beam_measure(measure, meter)?;
334            }
335        }
336    }
337    set_stem_direction_for_beam_groups(stream);
338    Ok(())
339}
340
341/// The meter a measure opens with: music21's `timeSignature`, which is the
342/// one standing at the very start and no other.
343fn meter_in(measure: &Stream) -> Option<TimeSignature> {
344    measure
345        .events()
346        .iter()
347        .find_map(|event| match event.element() {
348            StreamElement::TimeSignature(meter) if event.offset() == 0.0 => Some(meter.clone()),
349            _ => None,
350        })
351}
352
353fn beam_measure(measure: &mut Stream, meter: &TimeSignature) -> Result<()> {
354    let padding = (measure.padding_left(), measure.padding_right());
355    let has_voices = measure.events().iter().any(|event| {
356        event
357            .element()
358            .as_stream()
359            .is_some_and(|inner| inner.kind() == StreamKind::Voice)
360    });
361    if has_voices {
362        for event in measure.events_mut() {
363            if let StreamElement::Stream(voice) = event.element_mut()
364                && voice.kind() == StreamKind::Voice
365            {
366                beam_line(voice, meter, padding)?;
367            }
368        }
369        Ok(())
370    } else {
371        beam_line(measure, meter, padding)
372    }
373}
374
375/// Beams one line of notes: a measure with no voices, or one voice. The
376/// padding is the measure's, left and right.
377fn beam_line(
378    line: &mut Stream,
379    meter: &TimeSignature,
380    (padding_left, padding_right): (FloatType, FloatType),
381) -> Result<()> {
382    // music21's `notesAndRests`, which takes a chord symbol for a note.
383    let is_general_note = |element: &StreamElement| {
384        matches!(
385            element,
386            StreamElement::Note(_)
387                | StreamElement::Chord(_)
388                | StreamElement::Rest(_)
389                | StreamElement::Unpitched(_)
390                | StreamElement::PercussionChord(_)
391                | StreamElement::ChordSymbol(_)
392        )
393    };
394    let count = line
395        .events()
396        .iter()
397        .filter(|event| is_general_note(event.element()))
398        .count();
399    if count <= 1 {
400        return Ok(());
401    }
402    let mut places: Vec<usize> = Vec::new();
403    let mut notes: Vec<BeamedNote> = Vec::new();
404    for (place, event) in line.events().iter().enumerate() {
405        let element = event.element();
406        if !is_general_note(element) {
407            continue;
408        }
409        let duration = element.duration();
410        if duration.is_some_and(|duration| duration.is_grace()) {
411            continue;
412        }
413        let sounds = !matches!(
414            element,
415            StreamElement::Rest(_) | StreamElement::ChordSymbol(_)
416        );
417        places.push(place);
418        notes.push(BeamedNote {
419            offset: event.offset(),
420            quarter_length: element.quarter_length(),
421            // The written value, which a tuplet leaves standing.
422            duration_type: duration
423                .and_then(|duration| match duration.components().as_slice() {
424                    [(duration_type, _)] => Some(*duration_type),
425                    _ => None,
426                })
427                .unwrap_or(crate::duration::DurationType::Quarter),
428            sounds,
429        });
430    }
431    let summed: FloatType = notes.iter().map(|note| note.quarter_length).sum();
432    let bar = meter.bar_quarter_length();
433    // A hair of latitude for lengths no float spells exactly.
434    if summed > bar + 1e-9 {
435        return Ok(());
436    }
437    let highest = notes
438        .iter()
439        .map(|note| note.offset + note.quarter_length)
440        .fold(0.0, FloatType::max);
441    // A measure padded on the left starts that far into its bar, and one
442    // padded on the right at its start; a short measure saying neither is
443    // taken as ending with the bar, a pickup.
444    let start = if padding_left != 0.0 {
445        op_frac(padding_left)
446    } else if padding_right != 0.0 {
447        0.0
448    } else if highest < bar - 1e-9 {
449        bar - highest
450    } else {
451        0.0
452    };
453    // music21 reads each note's written value to beam it, and a copy of a
454    // duration whose one value has been read keeps that value as said. Every
455    // step that asks whether a length may be written another way works on
456    // such a copy, so the reading is recorded here.
457    for place in &places {
458        let element = line.events_mut()[*place].element_mut();
459        let Some(mut duration) = element.duration().cloned() else {
460            continue;
461        };
462        if duration.expression_is_inferred()
463            && duration.linked()
464            && duration.tuplets().is_empty()
465            && duration.components().len() <= 1
466        {
467            duration.set_expression_is_inferred(false);
468            score::set_duration(element, duration);
469        }
470    }
471    let beams = meter.beams_for(&notes, start, None)?;
472    for (place, beams) in places.into_iter().zip(beams) {
473        let beams = beams.unwrap_or_default();
474        match line.events_mut()[place].element_mut() {
475            StreamElement::Note(note) => note.set_beams(beams),
476            StreamElement::Chord(chord) => chord.set_beams(beams),
477            // music21 hands a rest its beams too, which are empty.
478            StreamElement::Rest(rest) => rest.set_beams(Some(beams)),
479            StreamElement::Unpitched(stroke) => stroke.written_mut().set_beams(beams),
480            StreamElement::PercussionChord(chord) => chord.written_mut().set_beams(beams),
481            _ => {}
482        }
483    }
484    Ok(())
485}
486
487/// One note or chord as the stem walk sees it.
488struct Stemmed {
489    /// The indices down through the nested streams to the element.
490    path: Vec<usize>,
491    offset: FloatType,
492    first_beam: Option<BeamType>,
493    direction: StemDirection,
494    pitches: Vec<Pitch>,
495}
496
497fn gather(
498    stream: &Stream,
499    base: FloatType,
500    path: &mut Vec<usize>,
501    out: &mut Vec<Stemmed>,
502    clefs: &mut Vec<(FloatType, Clef)>,
503) {
504    for (index, event) in stream.events().iter().enumerate() {
505        path.push(index);
506        let offset = base + event.offset();
507        match event.element() {
508            StreamElement::Stream(inner) => gather(inner, offset, path, out, clefs),
509            StreamElement::Clef(clef) => clefs.push((offset, clef.clone())),
510            StreamElement::Note(note) => out.push(Stemmed {
511                path: path.clone(),
512                offset,
513                first_beam: note.beams().by_number(1).and_then(|beam| beam.beam_type()),
514                direction: note.stem_direction(),
515                pitches: vec![note.pitch().clone()],
516            }),
517            StreamElement::Chord(chord) => out.push(Stemmed {
518                path: path.clone(),
519                offset,
520                first_beam: chord.beams().by_number(1).and_then(|beam| beam.beam_type()),
521                direction: chord.stem_direction(),
522                pitches: chord.pitches(),
523            }),
524            _ => {}
525        }
526        path.pop();
527    }
528}
529
530fn set_direction(stream: &mut Stream, path: &[usize], direction: StemDirection) {
531    let Some((first, rest)) = path.split_first() else {
532        return;
533    };
534    let Some(event) = stream.events_mut().get_mut(*first) else {
535        return;
536    };
537    match event.element_mut() {
538        StreamElement::Stream(inner) => set_direction(inner, rest, direction),
539        StreamElement::Note(note) => note.set_stem_direction(direction),
540        StreamElement::Chord(chord) => chord.set_stem_direction(direction),
541        _ => {}
542    }
543}
544
545/// Points the stems of each beamed group the way its first and last pitches
546/// lie about the middle line of the clef in force: music21's
547/// `setStemDirectionForBeamGroups`.
548///
549/// A group runs from a note whose first beam starts to the one whose first
550/// beam stops. Stems a score already points all one way are left alone, and
551/// a group with no clef before it is not touched.
552pub fn set_stem_direction_for_beam_groups(stream: &mut Stream) {
553    let mut notes = Vec::new();
554    let mut clefs = Vec::new();
555    gather(stream, 0.0, &mut Vec::new(), &mut notes, &mut clefs);
556
557    let mut groups: Vec<Vec<usize>> = Vec::new();
558    let mut current: Vec<usize> = Vec::new();
559    let mut inside = false;
560    for (index, note) in notes.iter().enumerate() {
561        if note.first_beam == Some(BeamType::Start) {
562            inside = true;
563        }
564        if inside {
565            current.push(index);
566        }
567        if note.first_beam == Some(BeamType::Stop) {
568            groups.push(std::mem::take(&mut current));
569            inside = false;
570        }
571    }
572    if !current.is_empty() {
573        groups.push(current);
574    }
575
576    let settable = |direction: StemDirection| {
577        matches!(
578            direction,
579            StemDirection::Up | StemDirection::Down | StemDirection::Unspecified
580        )
581    };
582    for group in groups {
583        let Some(first) = group.first().map(|index| &notes[*index]) else {
584            continue;
585        };
586        let mut said: Vec<StemDirection> = Vec::new();
587        for index in &group {
588            let direction = notes[*index].direction;
589            if settable(direction) && !said.contains(&direction) {
590                said.push(direction);
591            }
592        }
593        let consistent = !said.contains(&StemDirection::Unspecified) && said.len() < 2;
594        let Some((_, clef)) = clefs
595            .iter()
596            .rev()
597            .find(|(offset, _)| *offset <= first.offset)
598        else {
599            continue;
600        };
601        let pitches: Vec<Pitch> = group
602            .iter()
603            .flat_map(|index| notes[*index].pitches.iter().cloned())
604            .collect();
605        let Ok(direction) = clef.stem_direction_for_pitches(&pitches, true, false) else {
606            continue;
607        };
608        for index in &group {
609            let note = &notes[*index];
610            if !settable(note.direction) {
611                continue;
612            }
613            if note.direction != StemDirection::Unspecified && consistent {
614                continue;
615            }
616            set_direction(stream, &note.path, direction);
617        }
618    }
619}
620
621/// One element waiting for its measure.
622struct Placed {
623    offset: FloatType,
624    end: FloatType,
625    voice: Option<usize>,
626    element: StreamElement,
627}
628
629/// A measure while it is being filled.
630struct Bar {
631    start: FloatType,
632    end: FloatType,
633    own: Vec<StreamEvent>,
634    voices: Vec<Vec<StreamEvent>>,
635}
636
637/// Snaps an offset as music21's `opFrac` does, to the nearest fraction with
638/// a denominator up to 65535, so that three triplets end on the beat. A
639/// negative offset is snapped as its size is.
640pub fn op_frac(value: FloatType) -> FloatType {
641    if value < 0.0 {
642        return -op_frac(-value);
643    }
644    match crate::duration::limited_fraction(value, 65535) {
645        Some((numerator, denominator)) if denominator != 0 => {
646            let snapped = numerator as FloatType / denominator as FloatType;
647            if (snapped - value).abs() < 1e-9 {
648                snapped
649            } else {
650                value
651            }
652        }
653        _ => value,
654    }
655}
656
657/// Sorts events as music21 sorts a stream: by offset, then by class, grace
658/// notes first, then in the order given.
659pub(crate) fn sorted_events(mut events: Vec<StreamEvent>) -> Vec<StreamEvent> {
660    events.sort_by(event_order);
661    events
662}
663
664/// Puts an element into a stream where music21's sort puts it: after
665/// everything that sorts no later.
666pub(crate) fn insert_sorted(stream: &mut Stream, offset: FloatType, element: StreamElement) {
667    let event = StreamEvent::new(offset, element);
668    let mut events = stream.events().to_vec();
669    let place = events
670        .iter()
671        .position(|held| event_order(held, &event).is_gt())
672        .unwrap_or(events.len());
673    events.insert(place, event);
674    let spanners = stream.spanners().to_vec();
675    *stream = stream.with_events(events);
676    for spanner in spanners {
677        stream.add_spanner(spanner);
678    }
679}
680
681/// The order music21 sorts two things standing in one stream in, leaving
682/// equals in the order they were put there.
683pub(crate) fn event_order(left: &StreamEvent, right: &StreamEvent) -> std::cmp::Ordering {
684    let grace = |event: &StreamEvent| {
685        event
686            .element()
687            .duration()
688            .is_some_and(crate::duration::Duration::is_grace)
689    };
690    left.offset()
691        .total_cmp(&right.offset())
692        .then(
693            left.element()
694                .class_sort_order()
695                .cmp(&right.element().class_sort_order()),
696        )
697        .then(grace(right).cmp(&grace(left)))
698}
699
700fn placed(offset: FloatType, voice: Option<usize>, element: &StreamElement) -> Placed {
701    Placed {
702        offset,
703        end: op_frac(offset + element.quarter_length()),
704        voice,
705        element: element.clone(),
706    }
707}
708
709/// Cuts a stream into measures by the meters it holds: music21's
710/// `makeMeasures`.
711///
712/// A stream holding parts has each of them cut. Otherwise the stream is
713/// flattened, unless it holds voices, which are kept as the voices of each
714/// measure. A stream with no meter at its start is in `4/4` until it says
715/// otherwise. The first measure takes the clef standing at the start, or the
716/// one that fits the notes best; each measure where the meter changes states
717/// it; the last ends with a final barline. A note is put in the measure it
718/// starts in and is not cut where it runs past the barline.
719///
720/// Spanners are not carried across, as the places they name move.
721///
722/// A stream that would take more than [`MAX_MEASURES`] measures is refused
723/// with an error. A few bytes of a file can say a note lasts hundreds of
724/// millions of quarters, and that many measures do not fit in memory.
725///
726/// ```
727/// use music21::makenotation::make_measures;
728/// use music21::{Duration, Note, Stream, TimeSignature};
729///
730/// let mut line = Stream::new();
731/// line.insert(0.0, TimeSignature::new(3, 4)?);
732/// for (place, name) in ["C4", "D4", "E4", "F4"].iter().enumerate() {
733///     let note = Note::from_name(name)?.with_duration(Duration::quarter());
734///     line.insert(place as f64, note);
735/// }
736/// let measured = make_measures(&line)?;
737/// assert_eq!(measured.measures().len(), 2);
738/// assert_eq!(measured.measures()[1].number(), 2);
739/// # Ok::<(), music21::Error>(())
740/// ```
741pub fn make_measures(stream: &Stream) -> Result<Stream> {
742    make_measures_by(stream, &[])
743}
744
745/// The most measures [`make_measures`] cuts a stream into. Hours of music
746/// in the shortest meters fit in it.
747pub const MAX_MEASURES: usize = 100_000;
748
749/// [`make_measures`] by meters given rather than found: music21's
750/// `makeMeasures` with a `meterStream`. Each meter is given with the offset
751/// it takes over at; with none given the stream's own are used.
752pub fn make_measures_by(stream: &Stream, given: &[(FloatType, TimeSignature)]) -> Result<Stream> {
753    let is_part_like = |element: &StreamElement| {
754        element
755            .as_stream()
756            .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
757    };
758    if stream
759        .events()
760        .iter()
761        .any(|event| is_part_like(event.element()))
762    {
763        let mut made = stream.clone();
764        for event in made.events_mut() {
765            if let StreamElement::Stream(inner) = event.element_mut() {
766                **inner = make_measures_by(inner, given)?;
767            }
768        }
769        return Ok(made);
770    }
771
772    // Everything the stream holds, with where it starts and ends and which
773    // voice it is in.
774    let voices = stream.voices();
775    let voice_count = voices.len();
776    let mut waiting: Vec<Placed> = Vec::new();
777    if voice_count > 0 {
778        for event in stream.events() {
779            let is_voice = event
780                .element()
781                .as_stream()
782                .is_some_and(|inner| inner.kind() == StreamKind::Voice);
783            if !is_voice {
784                waiting.push(placed(event.offset(), None, event.element()));
785            }
786        }
787        for (index, voice) in voices.iter().enumerate() {
788            for event in sorted_events(voice.flatten().events().to_vec()) {
789                waiting.push(placed(event.offset(), Some(index), event.element()));
790            }
791        }
792    } else {
793        for event in sorted_events(stream.flatten().events().to_vec()) {
794            waiting.push(placed(event.offset(), None, event.element()));
795        }
796    }
797    // music21's `offsetMap` passes over barlines, so a loose one -- a
798    // flattened measure's, say -- goes into no measure.
799    waiting.retain(|item| !matches!(item.element, StreamElement::Barline(_)));
800
801    // The meters, with 4/4 at the start where the stream says nothing there.
802    let mut meters: Vec<(FloatType, TimeSignature)> = waiting
803        .iter()
804        .filter_map(|item| match &item.element {
805            StreamElement::TimeSignature(meter) => Some((item.offset, meter.clone())),
806            _ => None,
807        })
808        .collect();
809    meters.sort_by(|left, right| left.0.total_cmp(&right.0));
810    if meters.first().is_none_or(|(offset, _)| *offset > 0.0) {
811        meters.insert(0, (0.0, TimeSignature::new(4, 4)?));
812    }
813    if !given.is_empty() {
814        meters = given.to_vec();
815        meters.sort_by(|left, right| left.0.total_cmp(&right.0));
816    }
817
818    // The clef at the start, which the first measure takes and which is then
819    // not placed a second time.
820    let own_clef = waiting.iter().position(|item| {
821        item.voice.is_none() && item.offset == 0.0 && matches!(item.element, StreamElement::Clef(_))
822    });
823    let clef = match own_clef.map(|index| &waiting[index].element) {
824        Some(StreamElement::Clef(clef)) => clef.clone(),
825        _ => {
826            let mut pitches: Vec<Pitch> = Vec::new();
827            for item in &waiting {
828                match &item.element {
829                    StreamElement::Note(note) => pitches.push(note.pitch().clone()),
830                    StreamElement::Chord(chord) => pitches.extend(chord.pitches()),
831                    StreamElement::ChordSymbol(symbol) => {
832                        pitches.extend(symbol.pitches().unwrap_or_default());
833                    }
834                    _ => {}
835                }
836            }
837            Clef::best_for(&pitches, false)
838        }
839    };
840    let key = waiting.iter().find_map(|item| match &item.element {
841        element @ (StreamElement::KeySignature(_) | StreamElement::Key(_))
842            if item.voice.is_none() && item.offset == 0.0 =>
843        {
844            Some(element.clone())
845        }
846        _ => None,
847    });
848
849    let end = waiting
850        .iter()
851        .map(|item| item.end)
852        .fold(0.0, FloatType::max);
853
854    // The measures, empty: where each starts and ends, and what it opens
855    // with.
856    let mut bars: Vec<Bar> = Vec::new();
857    let mut offset = 0.0;
858    let mut last_meter: Option<usize> = None;
859    loop {
860        let here = meters
861            .iter()
862            .rposition(|(at, _)| *at <= offset)
863            .unwrap_or(0);
864        let mut own = Vec::new();
865        if last_meter != Some(here) {
866            last_meter = Some(here);
867            own.push(StreamEvent::new(0.0, meters[here].1.clone()));
868        }
869        if bars.is_empty() {
870            own.push(StreamEvent::new(0.0, clef.clone()));
871            // music21 copies the key in beside the one placed below.
872            if voice_count > 0
873                && let Some(key) = &key
874            {
875                own.push(StreamEvent::new(0.0, key.clone()));
876            }
877        }
878        let length = meters[here].1.bar_duration().quarter_length();
879        if length == 0.0 {
880            return Err(crate::error::Error::Meter(format!(
881                "time signature {} has no duration",
882                meters[here].1.ratio_string()
883            )));
884        }
885        if bars.len() == MAX_MEASURES {
886            return Err(crate::error::Error::Stream(format!(
887                "the stream would take more than {MAX_MEASURES} measures"
888            )));
889        }
890        let next = op_frac(offset + length);
891        bars.push(Bar {
892            start: offset,
893            end: next,
894            own,
895            voices: vec![Vec::new(); voice_count],
896        });
897        offset = next;
898        if offset >= end {
899            break;
900        }
901    }
902
903    let mut loose: Vec<StreamEvent> = Vec::new();
904    for (index, item) in waiting.into_iter().enumerate() {
905        let Some(bar) = bars
906            .iter_mut()
907            .find(|bar| bar.start <= item.offset && item.offset < bar.end)
908        else {
909            // Something with no length standing at the very end is kept
910            // after the measures.
911            if item.offset == item.end && item.offset == end {
912                loose.push(StreamEvent::new(item.offset, item.element));
913                continue;
914            }
915            return Err(crate::error::Error::Meter(format!(
916                "cannot place an element with start/end {}/{} within any measures",
917                item.offset, item.end
918            )));
919        };
920        let within = op_frac(item.offset - bar.start);
921        if own_clef == Some(index) {
922            continue;
923        }
924        if within == 0.0 && matches!(item.element, StreamElement::TimeSignature(_)) {
925            continue;
926        }
927        match item.voice {
928            None => bar.own.push(StreamEvent::new(within, item.element)),
929            Some(voice) => bar.voices[voice].push(StreamEvent::new(within, item.element)),
930        }
931    }
932
933    // music21 stores those at the end of the measures as they stand, where
934    // the music in them ends rather than where the last bar does.
935    let reached = bars
936        .iter()
937        .map(|bar| {
938            let held = bar
939                .own
940                .iter()
941                .chain(bar.voices.iter().flatten())
942                .map(StreamEvent::end_offset)
943                .fold(0.0, FloatType::max);
944            op_frac(bar.start + held)
945        })
946        .fold(0.0, FloatType::max);
947    for event in &mut loose {
948        *event = StreamEvent::new(reached, event.element().clone());
949    }
950
951    let count = bars.len();
952    let mut events: Vec<StreamEvent> = Vec::new();
953    for (index, bar) in bars.into_iter().enumerate() {
954        let mut own = bar.own;
955        for (id, voice) in bar.voices.into_iter().enumerate() {
956            let mut voice = Stream::new().with_events(sorted_events(voice));
957            voice.set_kind(StreamKind::Voice);
958            voice.set_id(Some(id.to_string()));
959            own.push(StreamEvent::new(0.0, voice));
960        }
961        let mut measure = Stream::new().with_events(sorted_events(own));
962        measure.set_kind(StreamKind::Measure);
963        measure.set_number(index as crate::defaults::IntegerType + 1);
964        if index + 1 == count {
965            measure.set_right_barline(Some(crate::bar::Barline::new(
966                crate::bar::BarlineType::Final,
967            )));
968        }
969        events.push(StreamEvent::new(bar.start, measure));
970    }
971    events.extend(loose);
972    Ok(stream.with_events(events))
973}
974
975/// Whether an element is a note, a chord, a rest or a stroke: music21's
976/// `GeneralNote`, which a chord symbol is one of.
977pub(crate) fn is_general_note(element: &StreamElement) -> bool {
978    matches!(
979        element,
980        StreamElement::Note(_)
981            | StreamElement::Chord(_)
982            | StreamElement::Rest(_)
983            | StreamElement::Unpitched(_)
984            | StreamElement::PercussionChord(_)
985            | StreamElement::ChordSymbol(_)
986    )
987}
988
989/// Whether an element sounds: music21's `NotRest`.
990pub(crate) fn is_not_rest(element: &StreamElement) -> bool {
991    is_general_note(element) && !matches!(element, StreamElement::Rest(_))
992}
993
994fn is_voice(element: &StreamElement) -> bool {
995    element
996        .as_stream()
997        .is_some_and(|inner| inner.kind() == StreamKind::Voice)
998}
999
1000/// Gives an element a new length, keeping whatever else it says.
1001fn set_quarter_length(element: &mut StreamElement, quarter_length: FloatType) -> Result<()> {
1002    let duration = Duration::new(quarter_length)?;
1003    match element {
1004        StreamElement::Note(note) => note.set_duration(duration),
1005        StreamElement::Chord(chord) => chord.set_duration(duration),
1006        StreamElement::Rest(rest) => rest.set_duration(duration),
1007        StreamElement::Unpitched(stroke) => stroke.written_mut().set_duration(duration),
1008        StreamElement::PercussionChord(chord) => chord.written_mut().set_duration(duration),
1009        _ => {}
1010    }
1011    Ok(())
1012}
1013
1014/// The tie a split leaves on the first piece, and the type of the one the
1015/// second piece takes.
1016fn split_tie(note: &mut Note) -> TieType {
1017    match note.tie().map(Tie::tie_type) {
1018        Some(TieType::Start) => TieType::Continue,
1019        Some(TieType::Stop) => {
1020            let mut tie = note
1021                .tie()
1022                .cloned()
1023                .unwrap_or_else(|| Tie::new(TieType::Stop));
1024            tie.set_tie_type(TieType::Continue);
1025            note.set_tie(Some(tie));
1026            TieType::Stop
1027        }
1028        Some(TieType::Continue) => TieType::Continue,
1029        _ => {
1030            note.set_tie(Some(Tie::new(TieType::Start)));
1031            TieType::Stop
1032        }
1033    }
1034}
1035
1036/// The second piece of a split note does not show its accidental again.
1037fn hide_tied_accidental(first: &Note, second: &mut Note) {
1038    let Some(accidental) = first.pitch().written_accidental() else {
1039        return;
1040    };
1041    if accidental.display_type() == "even-tied" {
1042        return;
1043    }
1044    let mut pitch = second.pitch().clone();
1045    if let Some(accidental) = pitch.written_accidental_mut() {
1046        accidental.set_display_status(Some(false));
1047        second.set_pitch(pitch);
1048    }
1049}
1050
1051/// An element cut in two at a length into it, the pieces tied: music21's
1052/// `splitAtQuarterLength`.
1053///
1054/// The second piece carries no lyrics, and each mark goes to the piece it is
1055/// attached to. A rest and a chord of strokes are cut without ties.
1056pub(crate) fn split_element(
1057    element: &StreamElement,
1058    at: FloatType,
1059) -> Result<(StreamElement, StreamElement)> {
1060    let whole = element.quarter_length();
1061    let first_length = Duration::new(at)?;
1062    let second_length = Duration::new(op_frac(whole - at))?;
1063    // Marks stay with the piece they are attached to.
1064    let share = |marks: &[Articulation]| -> (Vec<Articulation>, Vec<Articulation>) {
1065        let mut first = Vec::new();
1066        let mut second = Vec::new();
1067        for mark in marks {
1068            match mark.tie_attach() {
1069                "first" => first.push(mark.clone()),
1070                "last" => second.push(mark.clone()),
1071                _ => {
1072                    first.push(mark.clone());
1073                    second.push(mark.clone());
1074                }
1075            }
1076        }
1077        (first, second)
1078    };
1079    let split_note = |note: &Note| -> (Note, Note) {
1080        let mut first = note.clone();
1081        let mut second = note.clone();
1082        second.lyrics_mut().clear();
1083        let (kept, moved) = share(note.articulations());
1084        *first.articulations_mut() = kept;
1085        *second.articulations_mut() = moved;
1086        let (kept, moved) = split_expressions(note.expressions());
1087        *first.expressions_mut() = kept;
1088        *second.expressions_mut() = moved;
1089        first.set_duration(first_length.clone());
1090        second.set_duration(second_length.clone());
1091        let closing = split_tie(&mut first);
1092        second.set_tie(Some(Tie::new(closing)));
1093        hide_tied_accidental(&first, &mut second);
1094        (first, second)
1095    };
1096    match element {
1097        StreamElement::Note(note) => {
1098            let (first, second) = split_note(note);
1099            Ok((first.into(), second.into()))
1100        }
1101        StreamElement::Unpitched(stroke) => {
1102            let (first_note, second_note) = split_note(stroke.written());
1103            let mut first = stroke.clone();
1104            let mut second = stroke.clone();
1105            *first.written_mut() = first_note;
1106            *second.written_mut() = second_note;
1107            Ok((first.into(), second.into()))
1108        }
1109        StreamElement::Chord(chord) => {
1110            let mut first = chord.clone();
1111            let mut second = chord.clone();
1112            let (kept, moved) = share(chord.articulations());
1113            *first.articulations_mut() = kept;
1114            *second.articulations_mut() = moved;
1115            let (kept, moved) = split_expressions(chord.expressions());
1116            *first.expressions_mut() = kept;
1117            *second.expressions_mut() = moved;
1118            first.set_duration(first_length);
1119            second.set_duration(second_length);
1120            // A chord's lyrics are kept on its first note.
1121            if let Some(singer) = second.notes_mut().first_mut() {
1122                singer.lyrics_mut().clear();
1123            }
1124            for (one, other) in first.notes_mut().iter_mut().zip(second.notes_mut()) {
1125                let closing = split_tie(one);
1126                other.set_tie(Some(Tie::new(closing)));
1127                hide_tied_accidental(one, other);
1128            }
1129            Ok((first.into(), second.into()))
1130        }
1131        StreamElement::PercussionChord(chord) => {
1132            let mut first = chord.clone();
1133            let mut second = chord.clone();
1134            let (kept, moved) = split_expressions(chord.written().expressions());
1135            *first.written_mut().expressions_mut() = kept;
1136            *second.written_mut().expressions_mut() = moved;
1137            first.written_mut().set_duration(first_length);
1138            second.written_mut().set_duration(second_length);
1139            Ok((first.into(), second.into()))
1140        }
1141        StreamElement::Rest(rest) => {
1142            let mut first = rest.clone();
1143            let mut second = rest.clone();
1144            second.lyrics_mut().clear();
1145            let (kept, moved) = split_expressions(rest.expressions());
1146            *first.expressions_mut() = kept;
1147            *second.expressions_mut() = moved;
1148            first.set_duration(first_length);
1149            second.set_duration(second_length);
1150            Ok((first.into(), second.into()))
1151        }
1152        _ => Err(Error::Duration(
1153            "only a note, a chord or a rest is cut at a bar".to_string(),
1154        )),
1155    }
1156}
1157
1158/// music21's `nearestMultiple`: the multiple of a unit nearest a number, how
1159/// far off it is, and which way.
1160fn nearest_multiple(number: FloatType, unit: FloatType) -> (FloatType, FloatType, FloatType) {
1161    let round7 = |value: FloatType| (value * 1e7).round_ties_even() / 1e7;
1162    let multiple = (number / unit).floor();
1163    let low = unit * multiple;
1164    let high = unit * (multiple + 1.0);
1165    if low <= number && number <= low + unit / 2.0 {
1166        (low, round7(number - low), round7(number - low))
1167    } else {
1168        (high, round7(high - number), round7(number - high))
1169    }
1170}
1171
1172/// The best place on the grids for a length or an offset: music21's
1173/// `bestMatch`. The answer is what is left of the gap, the error, the unit
1174/// and the match, in the order they are compared.
1175fn best_match(
1176    target: FloatType,
1177    divisors: &[u32],
1178    zero_allowed: bool,
1179    gap: FloatType,
1180) -> (FloatType, FloatType, FloatType, FloatType) {
1181    let mut best: Option<(FloatType, FloatType, FloatType, FloatType)> = None;
1182    for divisor in divisors {
1183        let unit = 1.0 / FloatType::from(*divisor);
1184        let (mut found, mut error, _) = nearest_multiple(target, unit);
1185        if !zero_allowed && found == 0.0 {
1186            found = unit;
1187            error = ((target - found) * 1e7).round_ties_even().abs() / 1e7;
1188        }
1189        let remaining = if gap % unit == 0.0 {
1190            0.0
1191        } else {
1192            (gap - found).max(0.0)
1193        };
1194        let candidate = (remaining, error, unit, found);
1195        let better = best.is_none_or(|held| {
1196            candidate
1197                .0
1198                .total_cmp(&held.0)
1199                .then(candidate.1.total_cmp(&held.1))
1200                .then(candidate.2.total_cmp(&held.2))
1201                .then(candidate.3.total_cmp(&held.3))
1202                .is_lt()
1203        });
1204        if better {
1205            best = Some(candidate);
1206        }
1207    }
1208    best.unwrap_or((0.0, 0.0, 1.0, target))
1209}
1210
1211/// Which way and how far `target` was moved to the place `best_match`
1212/// found for it: music21's `signedError`.
1213fn signed_error(
1214    target: FloatType,
1215    found: (FloatType, FloatType, FloatType, FloatType),
1216    zero_allowed: bool,
1217) -> FloatType {
1218    let (nearest, _, signed) = nearest_multiple(target, found.2);
1219    if !zero_allowed && nearest == 0.0 {
1220        return ((target - found.3) * 1e7).round_ties_even() / 1e7;
1221    }
1222    signed
1223}
1224
1225/// The divisions of a quarter music21 quantizes to unless told otherwise:
1226/// sixteenths and triplet eighths.
1227pub const QUANTIZATION_DIVISORS: [u32; 2] = [4, 3];
1228
1229/// Moves every offset and length in a stream onto the nearest place a
1230/// quarter divides into: music21's `quantize`, for the stream's own elements.
1231///
1232/// `divisors` are the ways a quarter may be divided, `[4, 3]` for sixteenths
1233/// and triplets. Where two grids are as near, the one that leaves no gap
1234/// before the next element wins, then the nearer, then the finer. A note is
1235/// never quantized to no length at all, though a grace note stays one.
1236pub fn quantize(stream: &mut Stream, divisors: &[u32]) -> Result<()> {
1237    let divisors: &[u32] = if divisors.is_empty() {
1238        &QUANTIZATION_DIVISORS
1239    } else {
1240        divisors
1241    };
1242    let mut events = stream.events().to_vec();
1243    for index in 0..events.len() {
1244        let original = events[index].offset();
1245        let sign = if original < 0.0 { -1.0 } else { 1.0 };
1246        let landing = best_match(original.abs(), divisors, true, 0.0);
1247        let offset = op_frac(landing.3 * sign);
1248        let mut element = events[index].element().clone();
1249        let offset_error = signed_error(original.abs(), landing, true) * sign;
1250
1251        let is_grace = element.duration().is_some_and(Duration::is_grace);
1252        let length = element.quarter_length().max(0.0);
1253        let zero_allowed = !is_not_rest(&element) || is_grace;
1254        // The next element that lands later than this one says how much
1255        // room there is to fill.
1256        let ahead = events[index + 1..]
1257            .iter()
1258            .map(|event| best_match(event.offset(), divisors, true, 0.0).3)
1259            .find(|landing| *landing > offset);
1260        let gap = ahead.map_or(0.0, |landing| op_frac(landing - offset));
1261        let fitted = best_match(length, divisors, zero_allowed, gap);
1262        let matched = fitted.3;
1263        let is_stream = matches!(element, StreamElement::Stream(_));
1264        let mut length_error = None;
1265        if !is_grace && !is_stream && !(matched == 0.0 && matches!(element, StreamElement::Rest(_)))
1266        {
1267            set_quarter_length(&mut element, op_frac(matched))?;
1268            length_error = Some(signed_error(length, fitted, zero_allowed));
1269        }
1270        // How far each moved, which music21 writes into the editorial of
1271        // what has one where it is not nought.
1272        let errors = (
1273            Some(offset_error).filter(|error| *error != 0.0),
1274            length_error.filter(|error| *error != 0.0),
1275        );
1276        match &mut element {
1277            StreamElement::Note(note) => note.set_quantization_errors(errors),
1278            StreamElement::Chord(chord) => chord.set_quantization_errors(errors),
1279            _ => {}
1280        }
1281        let dropped = matched == 0.0 && matches!(element, StreamElement::Rest(_));
1282        events[index] = StreamEvent::new(offset, element);
1283        if dropped {
1284            // Marked for removal below by an offset no element can have.
1285            events[index] = StreamEvent::new(FloatType::NAN, events[index].element().clone());
1286        }
1287    }
1288    events.retain(|event| !event.offset().is_nan());
1289    *stream = stream.with_events(sorted_events(events));
1290    Ok(())
1291}
1292
1293/// music21's `_findLayering` and `_consolidateLayering`, for how many of a
1294/// line's notes sound at once at the most.
1295fn most_at_once(spans: &[(FloatType, FloatType)]) -> usize {
1296    let overlaps = |left: (FloatType, FloatType), right: (FloatType, FloatType)| {
1297        let (first, second) = if right.0 < left.0 || (right.0 == left.0 && right.1 < left.1) {
1298            (right, left)
1299        } else {
1300            (left, right)
1301        };
1302        second.0 < first.1
1303    };
1304    let mut layering: Vec<Vec<usize>> = vec![Vec::new(); spans.len()];
1305    for source in 0..spans.len() {
1306        for target in source + 1..spans.len() {
1307            if overlaps(spans[source], spans[target]) {
1308                layering[source].push(target);
1309                layering[target].push(source);
1310            } else {
1311                break;
1312            }
1313        }
1314    }
1315    for list in &mut layering {
1316        list.sort_unstable();
1317    }
1318    // Groups by the offset they were first gathered under.
1319    let mut groups: Vec<(FloatType, Vec<usize>)> = Vec::new();
1320    for (source, others) in layering.iter().enumerate() {
1321        if others.is_empty() {
1322            continue;
1323        }
1324        let mut destination: Option<FloatType> = None;
1325        for other in others {
1326            let mut store = true;
1327            if let Some((key, _)) = groups.iter().find(|(_, held)| held.contains(other)) {
1328                store = false;
1329                destination = Some(*key);
1330            }
1331            let key = *destination.get_or_insert(spans[source].0);
1332            if store {
1333                match groups.iter_mut().find(|(held, _)| *held == key) {
1334                    Some((_, held)) => held.push(*other),
1335                    None => groups.push((key, vec![*other])),
1336                }
1337            }
1338        }
1339        if !groups.iter().any(|(_, held)| held.contains(&source)) {
1340            let key = destination.unwrap_or(spans[source].0);
1341            match groups.iter_mut().find(|(held, _)| *held == key) {
1342                Some((_, held)) => held.push(source),
1343                None => groups.push((key, vec![source])),
1344            }
1345        }
1346    }
1347    groups
1348        .iter()
1349        .map(|(_, held)| held.len())
1350        .max()
1351        .unwrap_or(1)
1352        .max(1)
1353}
1354
1355/// Puts a measure's notes into voices where they overlap: music21's
1356/// `makeVoices` with `fillGaps=False`.
1357///
1358/// There are as many voices as notes sounding at once at the most, and each
1359/// note goes to the first voice that has finished by the time it starts. A
1360/// note no voice is free for is lost, as it is there. A measure whose notes
1361/// never overlap is left alone.
1362pub fn make_voices(measure: &mut Stream) {
1363    let events = measure.events().to_vec();
1364    let spans: Vec<(FloatType, FloatType)> = events
1365        .iter()
1366        .filter(|event| is_not_rest(event.element()))
1367        .map(|event| (event.offset(), op_frac(event.end_offset())))
1368        .collect();
1369    let count = most_at_once(&spans);
1370    if count == 1 {
1371        return;
1372    }
1373    let mut voices: Vec<(FloatType, Vec<StreamEvent>)> = vec![(0.0, Vec::new()); count];
1374    let mut kept: Vec<StreamEvent> = Vec::new();
1375    for event in events {
1376        if !is_not_rest(event.element()) {
1377            // Rests go, as `removeByClass('Rest')` takes them.
1378            if !matches!(event.element(), StreamElement::Rest(_)) {
1379                kept.push(event);
1380            }
1381            continue;
1382        }
1383        let offset = event.offset();
1384        let end = op_frac(event.end_offset());
1385        if let Some((highest, held)) = voices.iter_mut().find(|(highest, _)| *highest <= offset) {
1386            *highest = highest.max(end);
1387            held.push(event);
1388        }
1389    }
1390    for (_, held) in voices {
1391        if held.is_empty() {
1392            continue;
1393        }
1394        let mut voice = Stream::new().with_events(held);
1395        voice.set_kind(StreamKind::Voice);
1396        kept.push(StreamEvent::new(0.0, voice));
1397    }
1398    *measure = measure.with_events(sorted_events(kept));
1399}
1400
1401/// Every meter a part states, at its offset from the part's start, with
1402/// `4/4` at the start where the part says nothing there.
1403fn meters_of(part: &Stream) -> Result<Vec<(FloatType, TimeSignature)>> {
1404    let mut meters: Vec<(FloatType, TimeSignature)> = part
1405        .recurse()
1406        .into_iter()
1407        .filter_map(|(offset, element)| match element {
1408            StreamElement::TimeSignature(meter) => Some((offset, meter.clone())),
1409            _ => None,
1410        })
1411        .collect();
1412    meters.sort_by(|left, right| left.0.total_cmp(&right.0));
1413    // A meter standing again is the object the earlier measure holds, and
1414    // music21's list of meters keeps one place for one object: the last it
1415    // stands at. Each such meter and the one it restates are moved there.
1416    let mut group: Vec<usize> = (0..meters.len()).collect();
1417    for index in 0..meters.len() {
1418        if !meters[index].1.is_restated() {
1419            continue;
1420        }
1421        let ratio = meters[index].1.ratio_string();
1422        if let Some(earlier) = (0..index)
1423            .rev()
1424            .find(|earlier| meters[*earlier].1.ratio_string() == ratio)
1425        {
1426            group[index] = group[earlier];
1427        }
1428    }
1429    for index in (0..meters.len()).rev() {
1430        let last = (0..meters.len())
1431            .rev()
1432            .find(|other| group[*other] == group[index])
1433            .unwrap_or(index);
1434        meters[index].0 = meters[last].0;
1435    }
1436    meters.sort_by(|left, right| left.0.total_cmp(&right.0));
1437    if meters.first().is_none_or(|(offset, _)| *offset > 0.0) {
1438        meters.insert(0, (0.0, TimeSignature::new(4, 4)?));
1439    }
1440    Ok(meters)
1441}
1442
1443/// Takes the voices with nothing in them out of a measure, and where one
1444/// voice is left puts its notes in the measure itself: music21's
1445/// `flattenUnnecessaryVoices`.
1446fn flatten_unnecessary_voices(measure: &mut Stream) {
1447    let events = measure.events().to_vec();
1448    if !events.iter().any(|event| is_voice(event.element())) {
1449        return;
1450    }
1451    let full = events
1452        .iter()
1453        .filter(|event| {
1454            event
1455                .element()
1456                .as_stream()
1457                .is_some_and(|inner| inner.kind() == StreamKind::Voice && !inner.is_empty())
1458        })
1459        .count();
1460    let mut kept: Vec<StreamEvent> = Vec::new();
1461    let mut freed: Vec<StreamEvent> = Vec::new();
1462    for event in events {
1463        match event.element() {
1464            StreamElement::Stream(inner) if inner.kind() == StreamKind::Voice => {
1465                if inner.is_empty() {
1466                    continue;
1467                }
1468                if full == 1 {
1469                    let shift = event.offset();
1470                    freed.extend(inner.events().iter().map(|held| {
1471                        StreamEvent::new(shift + held.offset(), held.element().clone())
1472                    }));
1473                } else {
1474                    kept.push(event);
1475                }
1476            }
1477            _ => kept.push(event),
1478        }
1479    }
1480    kept.extend(freed);
1481    *measure = measure.with_events(sorted_events(kept));
1482}
1483
1484/// Cuts every note that runs past its barline and ties the pieces, the
1485/// second going to the start of the next measure: music21's `makeTies`.
1486///
1487/// A stream holding parts has each of them done. The stream must already be
1488/// in measures. A piece cut from a voice goes to the voice of the same name
1489/// in the next measure, or to the measure itself where there is none; when
1490/// the next measure has no voices, its notes are gathered into a voice and
1491/// the piece goes to a voice of its own name, made there. One cut from a
1492/// measure with no voices goes to the next measure's first voice where it
1493/// has any.
1494pub fn make_ties(stream: &mut Stream) -> Result<()> {
1495    make_ties_of(stream, is_general_note)
1496}
1497
1498fn make_ties_of(stream: &mut Stream, wanted: fn(&StreamElement) -> bool) -> Result<()> {
1499    let part_like = |element: &StreamElement| {
1500        element
1501            .as_stream()
1502            .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
1503    };
1504    if stream
1505        .events()
1506        .iter()
1507        .any(|event| part_like(event.element()))
1508    {
1509        let mut events = stream.events().to_vec();
1510        for event in &mut events {
1511            if let StreamElement::Stream(inner) = event.element_mut() {
1512                make_ties_of(inner, wanted)?;
1513            }
1514        }
1515        let spanners = stream.spanners().to_vec();
1516        *stream = stream.with_events(events);
1517        for spanner in spanners {
1518            stream.add_spanner(spanner);
1519        }
1520        return Ok(());
1521    }
1522    let meters = meters_of(stream)?;
1523    let mut others: Vec<StreamEvent> = Vec::new();
1524    let mut measures: Vec<(FloatType, Stream)> = Vec::new();
1525    for event in stream.events() {
1526        match event.element() {
1527            StreamElement::Stream(inner) if inner.kind() == StreamKind::Measure => {
1528                measures.push((event.offset(), (**inner).clone()));
1529            }
1530            _ => others.push(event.clone()),
1531        }
1532    }
1533    if measures.is_empty() {
1534        return Err(Error::Meter(
1535            "cannot process a stream without measures".to_string(),
1536        ));
1537    }
1538
1539    let mut index = 0;
1540    while index < measures.len() {
1541        let start = measures[index].0;
1542        let meter = meters
1543            .iter()
1544            .rfind(|(at, _)| *at <= start)
1545            .map_or(&meters[0].1, |(_, meter)| meter);
1546        let bar = meter.bar_duration().quarter_length();
1547        let has_voices = measures[index]
1548            .1
1549            .events()
1550            .iter()
1551            .any(|event| is_voice(event.element()));
1552
1553        // What is cut off, with the name of the voice it was cut from.
1554        let mut remains: Vec<(Option<String>, StreamElement)> = Vec::new();
1555        let mut cut = |line: &mut Stream, id: Option<String>| -> Result<()> {
1556            let mut events = line.events().to_vec();
1557            for event in &mut events {
1558                if !wanted(event.element()) {
1559                    continue;
1560                }
1561                let offset = event.offset();
1562                let end = op_frac(event.end_offset());
1563                if end - bar <= 1e-9 || offset >= bar - 1e-9 {
1564                    continue;
1565                }
1566                // music21 refuses before tying a note over more bars than
1567                // it would make measures for.
1568                if index as FloatType + (end - bar) / bar > MAX_MEASURES as FloatType {
1569                    return Err(Error::Stream(format!(
1570                        "cannot make more than {MAX_MEASURES} measures"
1571                    )));
1572                }
1573                let (first, remain) = split_element(event.element(), op_frac(bar - offset))?;
1574                *event = StreamEvent::new(offset, first);
1575                remains.push((id.clone(), remain));
1576            }
1577            *line = line.with_events(events);
1578            Ok(())
1579        };
1580        {
1581            let measure = &mut measures[index].1;
1582            if has_voices {
1583                let mut events = measure.events().to_vec();
1584                for event in &mut events {
1585                    if let StreamElement::Stream(voice) = event.element_mut()
1586                        && voice.kind() == StreamKind::Voice
1587                    {
1588                        let id = voice.id().map(str::to_string);
1589                        cut(voice, id)?;
1590                    }
1591                }
1592                *measure = measure.with_events(events);
1593            } else {
1594                cut(measure, None)?;
1595            }
1596        }
1597        if remains.is_empty() {
1598            index += 1;
1599            continue;
1600        }
1601        if index + 1 == measures.len() {
1602            let mut next = Stream::with_kind(StreamKind::Measure);
1603            next.set_number(measures[index].1.number() + 1);
1604            measures.push((op_frac(start + bar), next));
1605        }
1606        let next = &mut measures[index + 1].1;
1607        let next_had_voices = next.events().iter().any(|event| is_voice(event.element()));
1608        for (id, remain) in remains {
1609            let mut events = next.events().to_vec();
1610            let voice_at = |events: &[StreamEvent], wanted: Option<&str>| -> Option<usize> {
1611                events.iter().position(|event| {
1612                    event.element().as_stream().is_some_and(|inner| {
1613                        inner.kind() == StreamKind::Voice
1614                            && wanted.is_none_or(|wanted| inner.id() == Some(wanted))
1615                    })
1616                })
1617            };
1618            let destination = if next_had_voices {
1619                if has_voices {
1620                    id.as_deref().and_then(|id| voice_at(&events, Some(id)))
1621                } else {
1622                    voice_at(&events, None)
1623                }
1624            } else if has_voices {
1625                // The notes of the next measure are gathered into a voice of
1626                // their own once, and the piece joins the voice of its own
1627                // name, made where there is none.
1628                if voice_at(&events, None).is_none() {
1629                    let (moved, kept): (Vec<StreamEvent>, Vec<StreamEvent>) = events
1630                        .into_iter()
1631                        .partition(|event| is_general_note(event.element()));
1632                    events = kept;
1633                    let mut voice = Stream::new().with_events(moved);
1634                    voice.set_kind(StreamKind::Voice);
1635                    events.push(StreamEvent::new(0.0, voice));
1636                    events = sorted_events(events);
1637                }
1638                let named = id.as_deref().and_then(|id| voice_at(&events, Some(id)));
1639                if named.is_none() {
1640                    let mut voice = Stream::new().with_events(vec![StreamEvent::new(0.0, remain)]);
1641                    voice.set_kind(StreamKind::Voice);
1642                    voice.set_id(id.clone());
1643                    events.push(StreamEvent::new(0.0, voice));
1644                    *next = next.with_events(sorted_events(events));
1645                    continue;
1646                }
1647                named
1648            } else {
1649                None
1650            };
1651            match destination {
1652                Some(place) => {
1653                    if let StreamElement::Stream(voice) = events[place].element_mut() {
1654                        let mut held = voice.events().to_vec();
1655                        held.push(StreamEvent::new(0.0, remain));
1656                        **voice = voice.with_events(sorted_events(held));
1657                    }
1658                }
1659                None => {
1660                    events.push(StreamEvent::new(0.0, remain));
1661                    events = sorted_events(events);
1662                }
1663            }
1664            *next = next.with_events(events);
1665        }
1666        index += 1;
1667    }
1668
1669    for (offset, mut measure) in measures {
1670        flatten_unnecessary_voices(&mut measure);
1671        others.push(StreamEvent::new(offset, measure));
1672    }
1673    *stream = stream.with_events(sorted_events(others));
1674    Ok(())
1675}
1676
1677/// Fills one line out with rests from `low` to `high`: before its first
1678/// element, after its last, and in every gap between. `hidden` rests are
1679/// left unprinted.
1680pub(crate) fn fill_line(
1681    line: &mut Stream,
1682    low: FloatType,
1683    high: FloatType,
1684    hidden: bool,
1685) -> Result<()> {
1686    let mut events = line.events().to_vec();
1687    let lowest = events
1688        .iter()
1689        .map(StreamEvent::offset)
1690        .fold(FloatType::INFINITY, FloatType::min);
1691    let lowest = if lowest.is_finite() { lowest } else { 0.0 };
1692    let highest = op_frac(line.end_offset());
1693    let rest = |at: FloatType, length: FloatType| -> Result<StreamEvent> {
1694        let mut rest = Rest::new(Duration::new(op_frac(length))?);
1695        rest.set_hidden(hidden);
1696        Ok(StreamEvent::new(at, rest))
1697    };
1698    if lowest - low > 1e-9 {
1699        events.push(rest(low, lowest - low)?);
1700    }
1701    if high - highest > 1e-9 {
1702        events.push(rest(highest, high - highest)?);
1703    }
1704    events = sorted_events(events);
1705    let mut gaps: Vec<StreamEvent> = Vec::new();
1706    let mut reached = 0.0;
1707    for event in &events {
1708        if event.offset() - reached > 1e-9 {
1709            gaps.push(rest(reached, event.offset() - reached)?);
1710        }
1711        reached = op_frac(FloatType::max(reached, event.end_offset()));
1712    }
1713    events.extend(gaps);
1714    *line = line.with_events(sorted_events(events));
1715    Ok(())
1716}
1717
1718/// Fills every measure of a part with rests up to its bar's length, its
1719/// voices too: music21's `makeRests` with `fillGaps=True` and
1720/// `timeRangeFromBarDuration=True`.
1721///
1722/// A stream holding parts has each of them filled. A measure padded as a
1723/// pickup, or cut short, is filled only as far as its padding leaves. The
1724/// measures are then put one after another by what each holds.
1725pub fn make_rests(stream: &mut Stream) -> Result<()> {
1726    fill_rests(stream, None, false)
1727}
1728
1729/// music21's `makeRests` with `fillGaps=True` and
1730/// `timeRangeFromBarDuration=True`, rests `hidden` or not. A stream with no
1731/// measures is filled over `range`, or from its start to its end where none
1732/// is given.
1733pub(crate) fn fill_rests(
1734    stream: &mut Stream,
1735    range: Option<(FloatType, FloatType)>,
1736    hidden: bool,
1737) -> Result<()> {
1738    let is_part = |element: &StreamElement| {
1739        element
1740            .as_stream()
1741            .is_some_and(|inner| matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff))
1742    };
1743    if stream.events().iter().any(|event| is_part(event.element())) {
1744        let mut events = stream.events().to_vec();
1745        for event in &mut events {
1746            if let StreamElement::Stream(inner) = event.element_mut()
1747                && matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff)
1748            {
1749                let spanners = inner.spanners().to_vec();
1750                fill_rests(inner, range, hidden)?;
1751                inner.clear_spanners();
1752                for spanner in spanners {
1753                    inner.add_spanner(spanner);
1754                }
1755            }
1756        }
1757        let spanners = stream.spanners().to_vec();
1758        *stream = stream.with_events(events);
1759        for spanner in spanners {
1760            stream.add_spanner(spanner);
1761        }
1762        return Ok(());
1763    }
1764    let has_measures = stream.events().iter().any(|event| {
1765        event
1766            .element()
1767            .as_stream()
1768            .is_some_and(|inner| inner.kind() == StreamKind::Measure)
1769    });
1770    if !has_measures {
1771        let (low, high) = range.unwrap_or((0.0, stream.end_offset()));
1772        let has_voices = stream
1773            .events()
1774            .iter()
1775            .any(|event| is_voice(event.element()));
1776        if has_voices {
1777            let mut events = stream.events().to_vec();
1778            for event in &mut events {
1779                if let StreamElement::Stream(voice) = event.element_mut()
1780                    && voice.kind() == StreamKind::Voice
1781                {
1782                    fill_line(voice, low, high, hidden)?;
1783                }
1784            }
1785            let spanners = stream.spanners().to_vec();
1786            *stream = stream.with_events(events);
1787            for spanner in spanners {
1788                stream.add_spanner(spanner);
1789            }
1790        } else {
1791            let spanners = stream.spanners().to_vec();
1792            fill_line(stream, low, high, hidden)?;
1793            for spanner in spanners {
1794                stream.add_spanner(spanner);
1795            }
1796        }
1797        return Ok(());
1798    }
1799    let mut events = stream.events().to_vec();
1800    // The meters standing in the part itself, outside any measure.
1801    let loose: Vec<(FloatType, TimeSignature)> = events
1802        .iter()
1803        .filter_map(|event| match event.element() {
1804            StreamElement::TimeSignature(meter) => Some((event.offset(), meter.clone())),
1805            _ => None,
1806        })
1807        .collect();
1808    let mut meter: Option<TimeSignature> = None;
1809    for event in &mut events {
1810        let offset = event.offset();
1811        let StreamElement::Stream(measure) = event.element_mut() else {
1812            continue;
1813        };
1814        if measure.kind() != StreamKind::Measure {
1815            continue;
1816        }
1817        if let Some(own) = meter_in(measure) {
1818            meter = Some(own);
1819        }
1820        // A measure no meter has been stated for takes the one standing in
1821        // the part before it, and failing that is as long as the meter that
1822        // fits what it holds: music21's `barDuration`.
1823        let bar = match &meter {
1824            Some(meter) => meter.bar_duration().quarter_length(),
1825            None => match loose.iter().rev().find(|(at, _)| *at < offset) {
1826                Some((_, meter)) => meter.bar_duration().quarter_length(),
1827                None => crate::meter::best_time_signature(measure)
1828                    .map_or_else(|_| measure.end_offset(), |meter| meter.bar_quarter_length()),
1829            },
1830        };
1831        let target = FloatType::max(
1832            op_frac(bar - measure.padding_left() - measure.padding_right()),
1833            0.0,
1834        );
1835        let mut held = measure.events().to_vec();
1836        for inner in &mut held {
1837            if let StreamElement::Stream(voice) = inner.element_mut()
1838                && voice.kind() == StreamKind::Voice
1839            {
1840                fill_line(voice, 0.0, target, hidden)?;
1841            }
1842        }
1843        **measure = measure.with_events(held);
1844        fill_line(measure, 0.0, target.min(bar), hidden)?;
1845    }
1846    *stream = stream.with_events(events);
1847    make_ties_of(stream, |element| matches!(element, StreamElement::Rest(_)))?;
1848    let mut events = stream.events().to_vec();
1849    let mut reached = 0.0;
1850    for event in &mut events {
1851        if let StreamElement::Stream(measure) = event.element()
1852            && measure.kind() == StreamKind::Measure
1853        {
1854            let length = measure.end_offset();
1855            *event = StreamEvent::new(reached, event.element().clone());
1856            reached = op_frac(reached + length);
1857        }
1858    }
1859    *stream = stream.with_events(sorted_events(events));
1860    Ok(())
1861}
1862
1863/// The key signature a measure opens with: a key or a signature standing at
1864/// its very start.
1865fn key_signature_in(measure: &Stream) -> Option<crate::key::KeySignature> {
1866    measure
1867        .events()
1868        .iter()
1869        .find_map(|event| match event.element() {
1870            StreamElement::KeySignature(signature) if event.offset() == 0.0 => {
1871                Some(signature.clone())
1872            }
1873            StreamElement::Key(key) if event.offset() == 0.0 => Some(key.key_signature()),
1874            _ => None,
1875        })
1876}
1877
1878/// The names of the notes a key signature leaves unaltered or alters: the
1879/// major scale it is the signature of.
1880fn diatonic_names(signature: &crate::key::KeySignature) -> Vec<String> {
1881    signature
1882        .scale("major")
1883        .and_then(|scale| scale.pitches())
1884        .map(|pitches| pitches.iter().map(Pitch::name).collect())
1885        .unwrap_or_default()
1886}
1887
1888/// Every pitch a stream holds, element by element and each nested stream
1889/// where it stands, the notes a chord symbol stands for among them:
1890/// music21's `Stream.pitches`.
1891fn pitches_in_order(stream: &Stream) -> Vec<Pitch> {
1892    let mut out = Vec::new();
1893    for event in stream.events() {
1894        match event.element() {
1895            StreamElement::Stream(inner) => out.extend(pitches_in_order(inner)),
1896            StreamElement::ChordSymbol(symbol) => {
1897                out.extend(symbol.pitches().unwrap_or_default());
1898            }
1899            element => out.extend(element.pitches()),
1900        }
1901    }
1902    out
1903}
1904
1905/// Decides which accidentals are written, measure by measure: music21's
1906/// `makeAccidentals` on a part.
1907///
1908/// A stream holding parts has each of them done. An accidental is written
1909/// where the key signature in force does not already say it, where the same
1910/// note has just been written otherwise in this measure or the one before,
1911/// and not where the note is tied from the one before. A key signature is in
1912/// force from the measure that opens with it.
1913///
1914/// The accidentals an ornament implies are not considered.
1915pub fn make_accidentals(stream: &mut Stream) {
1916    make_accidentals_by(stream, true);
1917}
1918
1919/// [`make_accidentals`] with music21's `cautionaryNotImmediateRepeat` said:
1920/// whether an altered note written again later in its measure, not straight
1921/// after, shows its accidental again.
1922pub(crate) fn make_accidentals_by(stream: &mut Stream, cautionary_not_immediate_repeat: bool) {
1923    let part_like = |element: &StreamElement| {
1924        element
1925            .as_stream()
1926            .is_some_and(|inner| !matches!(inner.kind(), StreamKind::Measure | StreamKind::Voice))
1927    };
1928    let mut events = stream.events().to_vec();
1929    if events.iter().any(|event| part_like(event.element())) {
1930        for event in &mut events {
1931            if let StreamElement::Stream(inner) = event.element_mut() {
1932                make_accidentals_by(inner, cautionary_not_immediate_repeat);
1933            }
1934        }
1935        let spanners = stream.spanners().to_vec();
1936        *stream = stream.with_events(events);
1937        for spanner in spanners {
1938            stream.add_spanner(spanner);
1939        }
1940        return;
1941    }
1942
1943    let mut signature: Option<crate::key::KeySignature> = None;
1944    let mut diatonic: Vec<String> = Vec::new();
1945    let mut past_measure: Vec<Pitch> = Vec::new();
1946    let mut tied: Option<Vec<String>> = None;
1947    // What the measure before held: its pitches, and the ties its last
1948    // sounding element left open.
1949    let mut previous: Option<(Vec<Pitch>, Option<Vec<String>>)> = None;
1950    for event in &mut events {
1951        let StreamElement::Stream(measure) = event.element_mut() else {
1952            continue;
1953        };
1954        if measure.kind() != StreamKind::Measure {
1955            continue;
1956        }
1957        let own = key_signature_in(measure);
1958        if let Some((pitches, open)) = &previous {
1959            if own.is_none() {
1960                past_measure = pitches.clone();
1961            } else if signature.is_some() {
1962                past_measure = pitches
1963                    .iter()
1964                    .filter(|pitch| !diatonic.contains(&pitch.name()))
1965                    .cloned()
1966                    .collect();
1967            }
1968            if let Some(open) = open {
1969                // A tie does not reach across a new key signature: music21
1970                // asks whether the tied note, octave and all, is a name of
1971                // the new key, which it never is.
1972                tied = Some(if own.is_some() {
1973                    Vec::new()
1974                } else {
1975                    open.clone()
1976                });
1977            }
1978        }
1979        if let Some(own) = own {
1980            diatonic = diatonic_names(&own);
1981            signature = Some(own);
1982        }
1983        let altered = signature
1984            .as_ref()
1985            .and_then(|signature| signature.altered_pitches().ok())
1986            .unwrap_or_default();
1987
1988        let mut past: Vec<Pitch> = Vec::new();
1989        let mut open: Vec<String> = tied.clone().unwrap_or_default();
1990        let mut last_sounding: Option<Vec<String>> = None;
1991        // What the ornaments of this measure play, which counts among the
1992        // pitches the measure after it is decided against, as music21's
1993        // `makeAccidentalsInMeasureStream` counts them.
1994        let mut ornamental: Vec<Pitch> = Vec::new();
1995        let in_force = signature.clone().unwrap_or_else(|| KeySignature::new(0));
1996        measure.for_each_mut(&mut |_, element| match element {
1997            StreamElement::Note(note) => {
1998                let mut pitch = note.pitch().clone();
1999                pitch.update_accidental_display(&AccidentalDisplayOptions {
2000                    pitch_past: &past,
2001                    pitch_past_measure: &past_measure,
2002                    altered_pitches: &altered,
2003                    last_note_was_tied: open.contains(&pitch.name_with_octave()),
2004                    cautionary_not_immediate_repeat,
2005                    ..AccidentalDisplayOptions::default()
2006                });
2007                note.set_pitch(pitch.clone());
2008                open = tie_pitch_set(&StreamElement::Note(note.clone())).unwrap_or_default();
2009                last_sounding = Some(open.clone());
2010                past.push(pitch);
2011                // The accidentals this note's ornaments imply, decided
2012                // against what has been heard including the note itself.
2013                let played = ornaments_decided(
2014                    note,
2015                    &in_force,
2016                    &past,
2017                    &past_measure,
2018                    &altered,
2019                    cautionary_not_immediate_repeat,
2020                );
2021                past.extend(played.iter().cloned());
2022                ornamental.extend(played);
2023            }
2024            StreamElement::Chord(chord) => {
2025                let mut seen: Vec<String> = Vec::new();
2026                for index in 0..chord.notes().len() {
2027                    let others: Vec<Pitch> = chord
2028                        .notes()
2029                        .iter()
2030                        .enumerate()
2031                        .filter(|(other, _)| *other != index)
2032                        .map(|(_, note)| note.pitch().clone())
2033                        .collect();
2034                    let note = &mut chord.notes_mut()[index];
2035                    let mut pitch = note.pitch().clone();
2036                    pitch.update_accidental_display(&AccidentalDisplayOptions {
2037                        pitch_past: &past,
2038                        pitch_past_measure: &past_measure,
2039                        other_simultaneous_pitches: &others,
2040                        altered_pitches: &altered,
2041                        last_note_was_tied: open.contains(&pitch.name_with_octave()),
2042                        cautionary_not_immediate_repeat,
2043                        ..AccidentalDisplayOptions::default()
2044                    });
2045                    note.set_pitch(pitch.clone());
2046                    if let Some(tied) = tie_pitch_set(&StreamElement::Note(note.clone())) {
2047                        seen.extend(tied);
2048                    }
2049                    let played = ornaments_decided(
2050                        note,
2051                        &in_force,
2052                        &past,
2053                        &past_measure,
2054                        &altered,
2055                        cautionary_not_immediate_repeat,
2056                    );
2057                    ornamental.extend(played);
2058                }
2059                open = seen;
2060                last_sounding = Some(open.clone());
2061                past.extend(chord.notes().iter().map(|note| note.pitch().clone()));
2062            }
2063            StreamElement::ChordSymbol(symbol) => {
2064                // A chord symbol is a chord to music21: each note it stands
2065                // for is decided like a chord's, and counts among those
2066                // already heard.
2067                let mut sounded = symbol.pitches().unwrap_or_default();
2068                for index in 0..sounded.len() {
2069                    let others: Vec<Pitch> = sounded
2070                        .iter()
2071                        .enumerate()
2072                        .filter(|(other, _)| *other != index)
2073                        .map(|(_, pitch)| pitch.clone())
2074                        .collect();
2075                    let tied = open.contains(&sounded[index].name_with_octave());
2076                    sounded[index].update_accidental_display(&AccidentalDisplayOptions {
2077                        pitch_past: &past,
2078                        pitch_past_measure: &past_measure,
2079                        other_simultaneous_pitches: &others,
2080                        altered_pitches: &altered,
2081                        last_note_was_tied: tied,
2082                        ..AccidentalDisplayOptions::default()
2083                    });
2084                }
2085                // The root and the bass are notes of that chord, so a
2086                // natural one of them is given is the root's or the bass's.
2087                let given = |named: &Pitch| {
2088                    sounded
2089                        .iter()
2090                        .find(|pitch| {
2091                            pitch.step() == named.step() && pitch.alter() == named.alter()
2092                        })
2093                        .and_then(Pitch::written_accidental)
2094                        .cloned()
2095                };
2096                if symbol.root().written_accidental().is_none()
2097                    && let Some(accidental) = given(symbol.root())
2098                {
2099                    let mut root = symbol.root().clone();
2100                    root.set_written_accidental(Some(accidental));
2101                    symbol.set_root(root);
2102                }
2103                if let Some(bass) = symbol.bass().cloned()
2104                    && bass.written_accidental().is_none()
2105                    && let Some(accidental) = given(&bass)
2106                {
2107                    let mut bass = bass;
2108                    bass.set_written_accidental(Some(accidental));
2109                    symbol.set_bass(Some(bass));
2110                }
2111                open.clear();
2112                last_sounding = Some(Vec::new());
2113                past.extend(sounded);
2114            }
2115            StreamElement::Rest(_) => open.clear(),
2116            StreamElement::Unpitched(_) | StreamElement::PercussionChord(_) => {
2117                open.clear();
2118                last_sounding = Some(Vec::new());
2119            }
2120            _ => {}
2121        });
2122        tied = Some(open);
2123        let mut held = pitches_in_order(measure);
2124        held.extend(ornamental);
2125        previous = Some((held, last_sounding));
2126    }
2127    *stream = stream.with_events(events);
2128}
2129
2130#[cfg(test)]
2131mod tests {
2132    use super::*;
2133    use crate::{Duration, Note};
2134
2135    /// A note longer than `MAX_MEASURES` bars is refused before any
2136    /// measure is made for it, as music21 refuses it.
2137    #[test]
2138    fn ties_past_the_most_measures_are_refused() -> Result<()> {
2139        let mut measure = Stream::with_kind(StreamKind::Measure);
2140        measure.set_number(1);
2141        measure.insert(0.0, TimeSignature::new(4, 4)?);
2142        measure.insert(
2143            0.0,
2144            Note::from_name("C4")?.with_duration(Duration::new(FloatType::from(1u32 << 28))?),
2145        );
2146        let mut part = Stream::with_kind(StreamKind::Part);
2147        part.insert(0.0, measure);
2148        let refused = make_ties(&mut part).unwrap_err();
2149        assert!(matches!(refused, Error::Stream(_)), "{refused}");
2150        assert!(refused.to_string().contains("more than 100000 measures"));
2151        Ok(())
2152    }
2153
2154    /// Notes in two voices tied into a measure with none continue there in
2155    /// voices of the same names, beside the notes the measure already held.
2156    #[test]
2157    fn ties_into_a_measure_without_voices_keep_their_voices() -> Result<()> {
2158        let tied_into = |held: &[&str]| -> Result<Vec<(Option<String>, Vec<String>)>> {
2159            let mut first = Stream::with_kind(StreamKind::Measure);
2160            first.set_number(1);
2161            first.insert(0.0, TimeSignature::new(2, 4)?);
2162            for (id, name) in [("1", "C5"), ("2", "C4")] {
2163                let mut voice = Stream::with_kind(StreamKind::Voice);
2164                voice.set_id(Some(id.to_string()));
2165                voice.insert(
2166                    0.0,
2167                    Note::from_name(name)?.with_duration(Duration::new(4.0)?),
2168                );
2169                first.insert(0.0, voice);
2170            }
2171            let mut second = Stream::with_kind(StreamKind::Measure);
2172            second.set_number(2);
2173            for name in held {
2174                second.insert(
2175                    0.0,
2176                    Note::from_name(name)?.with_duration(Duration::new(2.0)?),
2177                );
2178            }
2179            let mut part = Stream::with_kind(StreamKind::Part);
2180            part.insert(0.0, first);
2181            part.insert(2.0, second);
2182            make_ties(&mut part)?;
2183            let measures = part.measures();
2184            Ok(measures[1]
2185                .voices()
2186                .iter()
2187                .map(|voice| {
2188                    let names = voice
2189                        .notes()
2190                        .iter()
2191                        .filter_map(|(_, element)| match element {
2192                            StreamElement::Note(note) => Some(note.pitch().name_with_octave()),
2193                            _ => None,
2194                        })
2195                        .collect();
2196                    (voice.id().map(str::to_string), names)
2197                })
2198                .collect())
2199        };
2200        let voices = tied_into(&[])?;
2201        assert_eq!(
2202            voices,
2203            [
2204                (Some("1".to_string()), vec!["C5".to_string()]),
2205                (Some("2".to_string()), vec!["C4".to_string()]),
2206            ]
2207        );
2208        let voices = tied_into(&["G4"])?;
2209        assert_eq!(voices.len(), 3);
2210        assert!(voices.contains(&(Some("1".to_string()), vec!["C5".to_string()])));
2211        assert!(voices.contains(&(Some("2".to_string()), vec!["C4".to_string()])));
2212        assert!(voices.iter().any(|(_, names)| names == &["G4".to_string()]));
2213        Ok(())
2214    }
2215
2216    /// A barline standing loose in what is cut into measures stands
2217    /// nowhere: music21's `offsetMap` passes over barlines, so
2218    /// `makeMeasures` puts none of them into a measure.
2219    #[test]
2220    fn loose_barlines_go_into_no_measure() -> Result<()> {
2221        let mut line = Stream::new();
2222        line.insert(
2223            0.0,
2224            crate::bar::Barline::new(crate::bar::BarlineType::Heavy),
2225        );
2226        line.insert(
2227            0.0,
2228            Note::from_name("C4")?.with_duration(Duration::new(4.0)?),
2229        );
2230        line.insert(
2231            4.0,
2232            crate::bar::Barline::new(crate::bar::BarlineType::Double),
2233        );
2234        line.insert(
2235            4.0,
2236            Note::from_name("D4")?.with_duration(Duration::new(4.0)?),
2237        );
2238        let measures = make_measures(&line)?;
2239        let held: usize = measures
2240            .measures()
2241            .iter()
2242            .map(|measure| {
2243                measure
2244                    .events()
2245                    .iter()
2246                    .filter(|event| matches!(event.element(), StreamElement::Barline(_)))
2247                    .count()
2248            })
2249            .sum();
2250        assert_eq!(held, 0);
2251        Ok(())
2252    }
2253
2254    fn eighths(names: &[&str]) -> Stream {
2255        let mut measure = Stream::with_kind(StreamKind::Measure);
2256        measure.insert(0.0, Clef::treble());
2257        measure.insert(0.0, TimeSignature::new(2, 4).unwrap());
2258        for (index, name) in names.iter().enumerate() {
2259            let note = Note::from_name(name)
2260                .unwrap()
2261                .with_duration(Duration::eighth());
2262            measure.insert(index as FloatType * 0.5, note);
2263        }
2264        measure
2265    }
2266
2267    fn beams_and_stems(measure: &Stream) -> Vec<(Option<BeamType>, StemDirection)> {
2268        measure
2269            .events()
2270            .iter()
2271            .filter_map(|event| match event.element() {
2272                StreamElement::Note(note) => Some((
2273                    note.beams().by_number(1).and_then(|beam| beam.beam_type()),
2274                    note.stem_direction(),
2275                )),
2276                _ => None,
2277            })
2278            .collect()
2279    }
2280
2281    #[test]
2282    fn eighths_are_beamed_by_the_beat_and_stemmed_together() {
2283        // music21: 2/4 with C5 D5 E4 F4 beams in pairs, the high pair down
2284        // and the low pair up.
2285        let mut part = Stream::with_kind(StreamKind::Part);
2286        part.insert(0.0, eighths(&["C5", "D5", "E4", "F4"]));
2287        make_beams(&mut part).unwrap();
2288        let measure = part.measures()[0];
2289        assert_eq!(
2290            beams_and_stems(measure),
2291            [
2292                (Some(BeamType::Start), StemDirection::Down),
2293                (Some(BeamType::Stop), StemDirection::Down),
2294                (Some(BeamType::Start), StemDirection::Up),
2295                (Some(BeamType::Stop), StemDirection::Up),
2296            ]
2297        );
2298    }
2299
2300    /// music21's `makeMeasures` stores what stands with no length at the
2301    /// very end with `storeAtEnd`, which puts it where the measures' music
2302    /// then ends -- the end of the last note, not of the last bar.
2303    #[test]
2304    fn what_stands_at_the_very_end_follows_the_last_note() {
2305        let mut part = Stream::with_kind(StreamKind::Part);
2306        part.insert(0.0, TimeSignature::new(2, 4).unwrap());
2307        part.insert(
2308            0.0,
2309            Note::from_name("C4")
2310                .unwrap()
2311                .with_duration(Duration::new(1.5).unwrap()),
2312        );
2313        part.insert(2.0, crate::tempo::MetronomeMark::new(60.0));
2314        let made = make_measures(&part).unwrap();
2315        let marks: Vec<FloatType> = made
2316            .events()
2317            .iter()
2318            .filter(|event| matches!(event.element(), StreamElement::MetronomeMark(_)))
2319            .map(StreamEvent::offset)
2320            .collect();
2321        assert_eq!(marks, [1.5]);
2322    }
2323
2324    /// music21's makeBeams hands every rest of a line it beams the beams it
2325    /// worked out for it, an empty `Beams`; a rest it passes over has none.
2326    #[test]
2327    fn a_beamed_line_gives_its_rests_empty_beams() {
2328        let mut measure = eighths(&["C5", "D5", "E4"]);
2329        measure.insert(1.5, crate::rest::Rest::new(Duration::eighth()));
2330        let mut lone = Stream::with_kind(StreamKind::Measure);
2331        lone.insert(0.0, crate::rest::Rest::new(Duration::new(2.0).unwrap()));
2332        let mut part = Stream::with_kind(StreamKind::Part);
2333        part.insert(0.0, measure);
2334        part.insert(1.0, lone);
2335        make_beams(&mut part).unwrap();
2336        let beamed: Vec<bool> = part
2337            .measures()
2338            .iter()
2339            .flat_map(|measure| measure.events())
2340            .filter_map(|event| match event.element() {
2341                StreamElement::Rest(rest) => {
2342                    Some(rest.beams().is_some_and(crate::notation::Beams::is_empty))
2343                }
2344                _ => None,
2345            })
2346            .collect();
2347        assert_eq!(beamed, [true, false]);
2348    }
2349
2350    /// A bar length written over the meter's own is the length music21's
2351    /// `makeMeasures` and `makeTies` cut at.
2352    #[test]
2353    fn a_written_bar_length_is_the_measure() {
2354        let mut meter = TimeSignature::new(2, 16).unwrap();
2355        meter.set_bar_duration(Some(Duration::new(3.0).unwrap()));
2356        let mut part = Stream::with_kind(StreamKind::Part);
2357        part.insert(0.0, meter);
2358        part.insert(0.0, Note::from_name("C4").unwrap());
2359
2360        let mut measured = make_measures(&part).unwrap();
2361        make_ties(&mut measured).unwrap();
2362        assert_eq!(measured.measures().len(), 1);
2363    }
2364
2365    #[test]
2366    fn a_measure_with_no_meter_is_left_alone() {
2367        let mut measure = Stream::with_kind(StreamKind::Measure);
2368        for (index, name) in ["C4", "D4"].iter().enumerate() {
2369            let note = Note::from_name(name)
2370                .unwrap()
2371                .with_duration(Duration::eighth());
2372            measure.insert(index as FloatType * 0.5, note);
2373        }
2374        let mut part = Stream::with_kind(StreamKind::Part);
2375        part.insert(0.0, measure);
2376        make_beams(&mut part).unwrap();
2377        assert!(
2378            beams_and_stems(part.measures()[0])
2379                .iter()
2380                .all(|(beam, stem)| beam.is_none() && *stem == StemDirection::Unspecified)
2381        );
2382    }
2383}
2384
2385#[cfg(test)]
2386mod realize_tests {
2387    use super::*;
2388    use crate::expressions::{Ornament, OrnamentKind};
2389    use crate::{Chord, Duration, Note};
2390
2391    fn described(stream: &Stream) -> Vec<String> {
2392        stream
2393            .events()
2394            .iter()
2395            .map(|event| match event.element() {
2396                StreamElement::Stream(inner) => {
2397                    format!("[{}]", described(inner).join(" "))
2398                }
2399                StreamElement::Note(note) => format!(
2400                    "{}@{}",
2401                    note.pitch().name_with_octave(),
2402                    note.duration().map_or(0.0, Duration::quarter_length)
2403                ),
2404                element => element
2405                    .music21_classes()
2406                    .first()
2407                    .copied()
2408                    .unwrap_or("other")
2409                    .to_string(),
2410            })
2411            .collect()
2412    }
2413
2414    fn ornamented(name: &str, length: FloatType, kinds: &[OrnamentKind]) -> Note {
2415        let mut note = Note::from_name(name)
2416            .unwrap()
2417            .with_duration(Duration::new(length).unwrap());
2418        for kind in kinds {
2419            note.expressions_mut().push(Ornament::of_kind(*kind).into());
2420        }
2421        note
2422    }
2423
2424    #[test]
2425    fn a_mordent_is_played_where_the_note_stood() {
2426        // music21's own docstring: the measure holding a whole C with a
2427        // mordent comes out holding C, B and C, and the measure after it
2428        // is untouched.
2429        let mut first = Stream::with_kind(StreamKind::Measure);
2430        first.insert(0.0, TimeSignature::new(4, 4).unwrap());
2431        first.push(ornamented("C4", 4.0, &[OrnamentKind::Mordent]));
2432        let mut second = Stream::with_kind(StreamKind::Measure);
2433        second.push(
2434            Note::from_name("D4")
2435                .unwrap()
2436                .with_duration(Duration::new(4.0).unwrap()),
2437        );
2438        let mut score = Stream::new();
2439        score.push(first);
2440        score.push(second);
2441        let realized = realize_ornaments(&score).unwrap();
2442        assert_eq!(
2443            described(&realized),
2444            [
2445                "[TimeSignature C4@0.125 B3@0.125 C4@3.75]".to_string(),
2446                "[D4@4]".to_string()
2447            ]
2448        );
2449    }
2450
2451    #[test]
2452    fn a_note_carrying_two_ornaments_is_heard_twice() {
2453        // music21 hands each ornament the note as it stands, so the note
2454        // is played once for each: C B C, then C D C.
2455        let mut measure = Stream::with_kind(StreamKind::Measure);
2456        measure.push(ornamented(
2457            "C4",
2458            2.0,
2459            &[OrnamentKind::Mordent, OrnamentKind::InvertedMordent],
2460        ));
2461        let realized = realize_ornaments(&measure).unwrap();
2462        assert_eq!(
2463            described(&realized).join(" "),
2464            "C4@0.125 B3@0.125 C4@1.75 C4@0.125 D4@0.125 C4@1.75"
2465        );
2466    }
2467
2468    #[test]
2469    fn the_key_in_force_says_what_the_neighbour_is() {
2470        // A trill on A in three flats plays the B flat above it, as
2471        // music21's does once it has asked the note for the key in its
2472        // context (where the note is spelled `B-`).
2473        let mut measure = Stream::with_kind(StreamKind::Measure);
2474        measure.insert(0.0, KeySignature::new(-3));
2475        measure.push(ornamented("A4", 0.5, &[OrnamentKind::Trill]));
2476        let realized = realize_ornaments(&measure).unwrap();
2477        assert_eq!(
2478            described(&realized).join(" "),
2479            "KeySignature A4@0.125 Bb4@0.125 A4@0.125 Bb4@0.125"
2480        );
2481    }
2482
2483    #[test]
2484    fn an_ornament_on_a_chord_is_refused() {
2485        // music21 asks whatever it is given for its one pitch, so a chord
2486        // raises there too.
2487        let mut measure = Stream::with_kind(StreamKind::Measure);
2488        let mut chord = Chord::new("C4 E4 G4").unwrap();
2489        chord.set_duration(Duration::new(1.0).unwrap());
2490        chord
2491            .expressions_mut()
2492            .push(Ornament::of_kind(OrnamentKind::Mordent).into());
2493        measure.push(chord);
2494        assert!(realize_ornaments(&measure).is_err());
2495    }
2496}
2497
2498#[cfg(test)]
2499mod ornamental_tests {
2500    use super::*;
2501    use crate::expressions::{Ornament, OrnamentKind};
2502    use crate::{Duration, Note};
2503
2504    fn trilled(name: &str) -> Note {
2505        let mut note = Note::from_name(name)
2506            .unwrap()
2507            .with_duration(Duration::new(1.0).unwrap());
2508        note.expressions_mut()
2509            .push(Ornament::of_kind(OrnamentKind::Trill).into());
2510        note
2511    }
2512
2513    fn shown(note: &Note) -> Option<String> {
2514        let Some(crate::expressions::Expression::Ornament(ornament)) = note.expressions().first()
2515        else {
2516            return None;
2517        };
2518        ornament
2519            .accidental()
2520            .map(|accidental| format!("{} {:?}", accidental.name(), accidental.display_status()))
2521    }
2522
2523    #[test]
2524    fn a_trill_above_a_flat_already_heard_shows_a_natural() {
2525        // music21 writes an `<accidental-mark>natural</accidental-mark>`
2526        // for this trill, the B flat before it having been heard.
2527        let mut note = trilled("A4");
2528        let past = [crate::Pitch::from_name("Bb4").unwrap()];
2529        let played = make_ornamental_accidentals(
2530            &mut note,
2531            &KeySignature::new(0),
2532            &AccidentalDisplayOptions {
2533                pitch_past: &past,
2534                ..AccidentalDisplayOptions::default()
2535            },
2536        )
2537        .expect("the trill plays its neighbour");
2538        assert_eq!(
2539            played
2540                .iter()
2541                .map(crate::Pitch::name_with_octave)
2542                .collect::<Vec<_>>(),
2543            ["B4".to_string()]
2544        );
2545        assert_eq!(shown(&note).as_deref(), Some("natural Some(true)"));
2546    }
2547
2548    #[test]
2549    fn a_trill_whose_neighbour_needs_nothing_says_nothing() {
2550        let mut note = trilled("A4");
2551        let played = make_ornamental_accidentals(
2552            &mut note,
2553            &KeySignature::new(0),
2554            &AccidentalDisplayOptions::default(),
2555        )
2556        .expect("the trill plays its neighbour");
2557        assert_eq!(played.len(), 1);
2558        // The ornament is left carrying nothing, so the writer writes no
2559        // mark for it.
2560        assert_eq!(shown(&note), None);
2561    }
2562
2563    #[test]
2564    fn an_ornament_of_a_fixed_size_is_left_as_it_stands() {
2565        // A half-step trill holds no accidental of its own, so there is
2566        // nowhere to write the decision; music21 keeps it on the pitch it
2567        // resolved.
2568        let mut note = Note::from_name("A4")
2569            .unwrap()
2570            .with_duration(Duration::new(1.0).unwrap());
2571        note.expressions_mut()
2572            .push(Ornament::of_kind(OrnamentKind::HalfStepTrill).into());
2573        let past = [crate::Pitch::from_name("Bb4").unwrap()];
2574        let played = make_ornamental_accidentals(
2575            &mut note,
2576            &KeySignature::new(0),
2577            &AccidentalDisplayOptions {
2578                pitch_past: &past,
2579                ..AccidentalDisplayOptions::default()
2580            },
2581        )
2582        .expect("the trill plays its neighbour");
2583        assert_eq!(played.len(), 1);
2584        assert_eq!(shown(&note), None);
2585    }
2586}