music21_rs/stream/
splitting.rs1use super::{Stream, StreamElement, StreamEvent, StreamKind};
5use crate::clef::Clef;
6use crate::defaults::FloatType;
7use crate::error::Result;
8use crate::key::KeySignature;
9use crate::makenotation::{op_frac, split_element};
10use crate::meter::TimeSignature;
11
12#[derive(Clone, Debug, Default)]
18pub struct InForce {
19 pub clef: Option<Clef>,
21 pub key: Option<KeySignature>,
23 pub meter: Option<TimeSignature>,
25}
26
27impl Stream {
28 pub fn in_force_before(&self, offset: FloatType) -> InForce {
31 let mut found = InForce::default();
32 for event in self.flatten().events() {
33 if event.offset() >= offset {
34 break;
35 }
36 match event.element() {
37 StreamElement::Clef(clef) => found.clef = Some(clef.clone()),
38 StreamElement::KeySignature(key) => found.key = Some(key.clone()),
39 StreamElement::Key(key) => found.key = Some(key.key_signature()),
40 StreamElement::TimeSignature(meter) => found.meter = Some(meter.clone()),
41 _ => {}
42 }
43 }
44 found
45 }
46
47 pub fn split_at_quarter_length(
75 &self,
76 quarter_length: FloatType,
77 in_force: &InForce,
78 ) -> Result<(Stream, Stream)> {
79 let quarter_length = op_frac(quarter_length);
80 let mut right = Stream::with_kind(self.kind());
81 let mut settings: Vec<StreamEvent> = Vec::new();
82 if self.kind() == StreamKind::Measure {
83 let own = |find: &dyn Fn(&StreamElement) -> bool| -> Option<StreamElement> {
84 self.events()
85 .iter()
86 .filter(|event| event.offset() < quarter_length && find(event.element()))
87 .map(|event| event.element().clone())
88 .last()
89 };
90 let meter = self
91 .flatten()
92 .events()
93 .iter()
94 .find_map(|event| match event.element() {
95 StreamElement::TimeSignature(meter) => Some(meter.clone()),
96 _ => None,
97 })
98 .or_else(|| in_force.meter.clone());
99 if let Some(meter) = meter {
100 settings.push(StreamEvent::new(0.0, meter));
101 }
102 let key = own(&|element| {
103 matches!(
104 element,
105 StreamElement::KeySignature(_) | StreamElement::Key(_)
106 )
107 })
108 .or_else(|| in_force.key.clone().map(StreamElement::KeySignature));
109 if let Some(key) = key {
110 settings.push(StreamEvent::new(0.0, key));
111 }
112 let clef = own(&|element| matches!(element, StreamElement::Clef(_)))
113 .or_else(|| in_force.clef.clone().map(StreamElement::Clef));
114 if let Some(clef) = clef {
115 settings.push(StreamEvent::new(0.0, clef));
116 }
117 }
118 right.insert_sorted(settings);
119
120 let mut left = self.clone();
121 let highest = op_frac(self.end_offset());
122 if quarter_length > highest {
123 return Ok((left, right));
124 }
125 let span = super::span::OffsetSpan {
126 include_end_boundary: true,
127 must_finish_in_span: false,
128 include_elements_that_end_at_start: false,
129 must_begin_in_span: false,
130 ..super::span::OffsetSpan::between(quarter_length, highest)
131 };
132 let mut kept: Vec<(StreamEvent, Option<usize>)> = Vec::new();
133 let mut moved: Vec<StreamEvent> = Vec::new();
134 for (index, event) in self.events().iter().enumerate() {
135 let length = event.element().quarter_length();
136 if !span.takes_at(event.offset(), length) {
137 kept.push((event.clone(), Some(index)));
138 continue;
139 }
140 if event.offset() < quarter_length {
141 let cut = op_frac(quarter_length - event.offset());
142 let (first, second) = match event.element() {
143 StreamElement::Stream(inner) => {
144 let (first, second) =
145 inner.split_at_quarter_length(cut, &InForce::default())?;
146 (first.into(), second.into())
147 }
148 element => split_element(element, cut)?,
149 };
150 kept.push((StreamEvent::new(event.offset(), first), Some(index)));
151 moved.push(StreamEvent::new(0.0, second));
152 } else {
153 moved.push(StreamEvent::new(
154 op_frac(event.offset() - quarter_length),
155 event.element().clone(),
156 ));
157 }
158 }
159 left.replace_events(kept);
160 if left.right_barline().is_some() && span.takes_at(highest, 0.0) {
161 right.set_right_barline(left.right_barline().cloned());
162 left.set_right_barline(None);
163 }
164 right.insert_sorted(moved);
165 Ok((left, right))
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172 use crate::bar::{Barline, BarlineType};
173 use crate::duration::Duration;
174 use crate::note::Note;
175
176 #[test]
177 fn the_second_half_gets_the_settings_and_the_right_barline() -> Result<()> {
178 let mut measure = Stream::with_kind(StreamKind::Measure);
179 measure.insert(0.0, Note::from_name("C4")?.with_duration(Duration::whole()));
180 measure.set_right_barline(Some(Barline::new(BarlineType::Final)));
181 let in_force = InForce {
182 clef: Some(Clef::best_for(&[], false)),
183 key: Some(KeySignature::new(2)),
184 meter: Some(TimeSignature::new(4, 4)?),
185 };
186 let (left, right) = measure.split_at_quarter_length(1.0, &in_force)?;
187 assert!(left.right_barline().is_none());
188 assert_eq!(
189 right.right_barline().map(Barline::bar_type),
190 Some(BarlineType::Final)
191 );
192 assert!(right.left_barline().is_none());
193 let kinds: Vec<&str> = right
194 .events()
195 .iter()
196 .map(|event| match event.element() {
197 StreamElement::Clef(_) => "clef",
198 StreamElement::KeySignature(_) => "key",
199 StreamElement::TimeSignature(_) => "meter",
200 StreamElement::Note(_) => "note",
201 _ => "other",
202 })
203 .collect();
204 assert_eq!(kinds, ["clef", "key", "meter", "note"]);
205 assert_eq!(left.end_offset(), 1.0);
206 assert_eq!(right.end_offset(), 3.0);
207
208 let (whole, empty) = measure.split_at_quarter_length(5.0, &InForce::default())?;
210 assert_eq!(whole.end_offset(), 4.0);
211 assert!(empty.is_empty());
212 Ok(())
213 }
214}