1use crate::defaults::{FloatType, IntegerType};
12use crate::duration::Duration;
13use crate::error::{Error, Result};
14use crate::interval::{GenericInterval, Interval, IntervalDirection};
15use crate::key::keysignature::KeySignature;
16use crate::notation::{Tie, TieType};
17use crate::note::Note;
18use crate::pitch::{Accidental, AccidentalDisplayOptions, Pitch};
19use crate::spanner::{Spanner, SpannerKind};
20use crate::stream::{Stream, StreamElement};
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24enum Family {
25 Plain,
27 Mordent,
28 Trill,
29 Turn,
30 Appoggiatura,
31 Tremolo,
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37pub enum OrnamentKind {
38 Ornament,
40 GeneralAppoggiatura,
42 GeneralMordent,
44 Schleifer,
46 Tremolo,
48 Trill,
50 Turn,
52 Appoggiatura,
54 HalfStepTrill,
56 InvertedAppoggiatura,
58 InvertedMordent,
60 InvertedTrill,
62 InvertedTurn,
64 Mordent,
66 Shake,
68 WholeStepTrill,
70 HalfStepAppoggiatura,
72 HalfStepInvertedAppoggiatura,
74 HalfStepInvertedMordent,
76 HalfStepMordent,
78 WholeStepAppoggiatura,
80 WholeStepInvertedAppoggiatura,
82 WholeStepInvertedMordent,
84 WholeStepMordent,
86}
87
88struct KindRow {
90 kind: OrnamentKind,
91 class: &'static str,
92 parents: &'static [&'static str],
94 family: Family,
95 up: Option<bool>,
98 fixed_size: Option<&'static str>,
101 quarter_length: FloatType,
102 placement: Option<&'static str>,
103 tie_attach: &'static str,
104}
105
106const KINDS: [KindRow; 24] = [
107 row(
108 OrnamentKind::Ornament,
109 "Ornament",
110 &[],
111 Family::Plain,
112 None,
113 None,
114 0.0,
115 None,
116 "first",
117 ),
118 row(
119 OrnamentKind::GeneralAppoggiatura,
120 "GeneralAppoggiatura",
121 &["Ornament"],
122 Family::Appoggiatura,
123 None,
124 Some("M2"),
125 0.0,
126 None,
127 "first",
128 ),
129 row(
130 OrnamentKind::GeneralMordent,
131 "GeneralMordent",
132 &["Ornament"],
133 Family::Mordent,
134 None,
135 None,
136 0.125,
137 Some("above"),
138 "first",
139 ),
140 row(
141 OrnamentKind::Schleifer,
142 "Schleifer",
143 &["Ornament"],
144 Family::Plain,
145 None,
146 None,
147 0.25,
148 None,
149 "first",
150 ),
151 row(
152 OrnamentKind::Tremolo,
153 "Tremolo",
154 &["Ornament"],
155 Family::Tremolo,
156 None,
157 None,
158 0.0,
159 None,
160 "first",
161 ),
162 row(
163 OrnamentKind::Trill,
164 "Trill",
165 &["Ornament"],
166 Family::Trill,
167 Some(true),
168 None,
169 0.125,
170 Some("above"),
171 "all",
172 ),
173 row(
174 OrnamentKind::Turn,
175 "Turn",
176 &["Ornament"],
177 Family::Turn,
178 None,
179 None,
180 0.25,
181 Some("above"),
182 "all",
183 ),
184 row(
185 OrnamentKind::Appoggiatura,
186 "Appoggiatura",
187 &["GeneralAppoggiatura", "Ornament"],
188 Family::Appoggiatura,
189 Some(false),
190 Some("M2"),
191 0.0,
192 None,
193 "first",
194 ),
195 row(
196 OrnamentKind::HalfStepTrill,
197 "HalfStepTrill",
198 &["Trill", "Ornament"],
199 Family::Trill,
200 Some(true),
201 Some("m2"),
202 0.125,
203 Some("above"),
204 "all",
205 ),
206 row(
207 OrnamentKind::InvertedAppoggiatura,
208 "InvertedAppoggiatura",
209 &["GeneralAppoggiatura", "Ornament"],
210 Family::Appoggiatura,
211 Some(true),
212 Some("M2"),
213 0.0,
214 None,
215 "first",
216 ),
217 row(
218 OrnamentKind::InvertedMordent,
219 "InvertedMordent",
220 &["GeneralMordent", "Ornament"],
221 Family::Mordent,
222 Some(true),
223 None,
224 0.125,
225 Some("above"),
226 "first",
227 ),
228 row(
229 OrnamentKind::InvertedTrill,
230 "InvertedTrill",
231 &["Trill", "Ornament"],
232 Family::Trill,
233 Some(false),
234 None,
235 0.125,
236 Some("above"),
237 "all",
238 ),
239 row(
240 OrnamentKind::InvertedTurn,
241 "InvertedTurn",
242 &["Turn", "Ornament"],
243 Family::Turn,
244 None,
245 None,
246 0.25,
247 Some("above"),
248 "all",
249 ),
250 row(
251 OrnamentKind::Mordent,
252 "Mordent",
253 &["GeneralMordent", "Ornament"],
254 Family::Mordent,
255 Some(false),
256 None,
257 0.125,
258 Some("above"),
259 "first",
260 ),
261 row(
262 OrnamentKind::Shake,
263 "Shake",
264 &["Trill", "Ornament"],
265 Family::Trill,
266 Some(true),
267 None,
268 0.25,
269 Some("above"),
270 "all",
271 ),
272 row(
273 OrnamentKind::WholeStepTrill,
274 "WholeStepTrill",
275 &["Trill", "Ornament"],
276 Family::Trill,
277 Some(true),
278 Some("M2"),
279 0.125,
280 Some("above"),
281 "all",
282 ),
283 row(
284 OrnamentKind::HalfStepAppoggiatura,
285 "HalfStepAppoggiatura",
286 &["Appoggiatura", "GeneralAppoggiatura", "Ornament"],
287 Family::Appoggiatura,
288 Some(false),
289 Some("m2"),
290 0.0,
291 None,
292 "first",
293 ),
294 row(
295 OrnamentKind::HalfStepInvertedAppoggiatura,
296 "HalfStepInvertedAppoggiatura",
297 &["InvertedAppoggiatura", "GeneralAppoggiatura", "Ornament"],
298 Family::Appoggiatura,
299 Some(true),
300 Some("m2"),
301 0.0,
302 None,
303 "first",
304 ),
305 row(
306 OrnamentKind::HalfStepInvertedMordent,
307 "HalfStepInvertedMordent",
308 &["InvertedMordent", "GeneralMordent", "Ornament"],
309 Family::Mordent,
310 Some(true),
311 Some("m2"),
312 0.125,
313 Some("above"),
314 "first",
315 ),
316 row(
317 OrnamentKind::HalfStepMordent,
318 "HalfStepMordent",
319 &["Mordent", "GeneralMordent", "Ornament"],
320 Family::Mordent,
321 Some(false),
322 Some("m-2"),
323 0.125,
324 Some("above"),
325 "first",
326 ),
327 row(
328 OrnamentKind::WholeStepAppoggiatura,
329 "WholeStepAppoggiatura",
330 &["Appoggiatura", "GeneralAppoggiatura", "Ornament"],
331 Family::Appoggiatura,
332 Some(false),
333 Some("M2"),
334 0.0,
335 None,
336 "first",
337 ),
338 row(
339 OrnamentKind::WholeStepInvertedAppoggiatura,
340 "WholeStepInvertedAppoggiatura",
341 &["InvertedAppoggiatura", "GeneralAppoggiatura", "Ornament"],
342 Family::Appoggiatura,
343 Some(true),
344 Some("M2"),
345 0.0,
346 None,
347 "first",
348 ),
349 row(
350 OrnamentKind::WholeStepInvertedMordent,
351 "WholeStepInvertedMordent",
352 &["InvertedMordent", "GeneralMordent", "Ornament"],
353 Family::Mordent,
354 Some(true),
355 Some("M2"),
356 0.125,
357 Some("above"),
358 "first",
359 ),
360 row(
361 OrnamentKind::WholeStepMordent,
362 "WholeStepMordent",
363 &["Mordent", "GeneralMordent", "Ornament"],
364 Family::Mordent,
365 Some(false),
366 Some("M-2"),
367 0.125,
368 Some("above"),
369 "first",
370 ),
371];
372
373#[allow(clippy::too_many_arguments)]
374const fn row(
375 kind: OrnamentKind,
376 class: &'static str,
377 parents: &'static [&'static str],
378 family: Family,
379 up: Option<bool>,
380 fixed_size: Option<&'static str>,
381 quarter_length: FloatType,
382 placement: Option<&'static str>,
383 tie_attach: &'static str,
384) -> KindRow {
385 KindRow {
386 kind,
387 class,
388 parents,
389 family,
390 up,
391 fixed_size,
392 quarter_length,
393 placement,
394 tie_attach,
395 }
396}
397
398impl OrnamentKind {
399 pub const ALL: [OrnamentKind; 24] = [
401 OrnamentKind::Ornament,
402 OrnamentKind::GeneralAppoggiatura,
403 OrnamentKind::GeneralMordent,
404 OrnamentKind::Schleifer,
405 OrnamentKind::Tremolo,
406 OrnamentKind::Trill,
407 OrnamentKind::Turn,
408 OrnamentKind::Appoggiatura,
409 OrnamentKind::HalfStepTrill,
410 OrnamentKind::InvertedAppoggiatura,
411 OrnamentKind::InvertedMordent,
412 OrnamentKind::InvertedTrill,
413 OrnamentKind::InvertedTurn,
414 OrnamentKind::Mordent,
415 OrnamentKind::Shake,
416 OrnamentKind::WholeStepTrill,
417 OrnamentKind::HalfStepAppoggiatura,
418 OrnamentKind::HalfStepInvertedAppoggiatura,
419 OrnamentKind::HalfStepInvertedMordent,
420 OrnamentKind::HalfStepMordent,
421 OrnamentKind::WholeStepAppoggiatura,
422 OrnamentKind::WholeStepInvertedAppoggiatura,
423 OrnamentKind::WholeStepInvertedMordent,
424 OrnamentKind::WholeStepMordent,
425 ];
426
427 fn row(self) -> &'static KindRow {
428 KINDS
429 .iter()
430 .find(|row| row.kind == self)
431 .expect("every kind has a row")
432 }
433
434 pub fn class_name(self) -> &'static str {
436 self.row().class
437 }
438
439 pub fn from_class_name(class: &str) -> Option<Self> {
441 KINDS
442 .iter()
443 .find(|row| row.class == class)
444 .map(|row| row.kind)
445 }
446
447 pub fn parents(self) -> &'static [&'static str] {
449 self.row().parents
450 }
451
452 pub fn has_fixed_size(self) -> bool {
455 self.row().fixed_size.is_some()
456 && matches!(self.row().family, Family::Mordent | Family::Trill)
457 }
458}
459
460#[derive(Clone, Copy, Debug, PartialEq)]
462#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
463pub enum OrnamentDelay {
464 NoDelay,
466 Default,
468 Timed(FloatType),
470}
471
472#[derive(Clone, Copy, Debug, PartialEq, Eq)]
474pub enum TurnNote {
475 Upper,
477 Lower,
479}
480
481#[derive(Clone, Debug)]
485pub struct Realization {
486 pub before: Vec<Note>,
488 pub main: Option<Note>,
490 pub after: Vec<Note>,
492}
493
494impl Realization {
495 pub fn into_notes(self) -> Vec<Note> {
497 let mut notes = self.before;
498 notes.extend(self.main);
499 notes.extend(self.after);
500 notes
501 }
502}
503
504#[derive(Clone, Debug, PartialEq)]
524#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
525#[must_use]
526pub struct Ornament {
527 kind: OrnamentKind,
528 quarter_length: FloatType,
529 auto_scale: bool,
530 placement: Option<String>,
531 tie_attach: String,
532 accidental: Option<Accidental>,
533 upper_accidental: Option<Accidental>,
534 lower_accidental: Option<Accidental>,
535 delay: OrnamentDelay,
536 nachschlag: bool,
537 number_of_marks: u8,
538 measured: bool,
539 size: Option<Interval>,
540}
541
542impl Default for Ornament {
543 fn default() -> Self {
545 Self::of_kind(OrnamentKind::Ornament)
546 }
547}
548
549impl Ornament {
550 pub fn of_kind(kind: OrnamentKind) -> Self {
552 let row = kind.row();
553 let size = match row.family {
554 Family::Appoggiatura => row
555 .fixed_size
556 .map(|name| Interval::from_name(name).expect("a fixed interval name")),
557 _ => None,
558 };
559 Self {
560 kind,
561 quarter_length: row.quarter_length,
562 auto_scale: true,
563 placement: row.placement.map(str::to_string),
564 tie_attach: row.tie_attach.to_string(),
565 accidental: None,
566 upper_accidental: None,
567 lower_accidental: None,
568 delay: OrnamentDelay::NoDelay,
569 nachschlag: false,
570 number_of_marks: 3,
571 measured: true,
572 size,
573 }
574 }
575
576 pub fn kind(&self) -> OrnamentKind {
578 self.kind
579 }
580
581 pub fn is_a(&self, class: &str) -> bool {
583 self.kind.class_name() == class || self.kind.parents().contains(&class)
584 }
585
586 fn family(&self) -> Family {
587 self.kind.row().family
588 }
589
590 pub fn direction(&self) -> Option<IntervalDirection> {
594 match self.family() {
595 Family::Mordent | Family::Trill | Family::Appoggiatura => {
596 self.kind.row().up.map(|up| {
597 if up {
598 IntervalDirection::Ascending
599 } else {
600 IntervalDirection::Descending
601 }
602 })
603 }
604 _ => None,
605 }
606 }
607
608 pub fn name(&self) -> String {
611 let mut name =
612 crate::common::stringtools::camel_case_to_hyphen(self.kind.class_name(), ' ');
613 match self.family() {
614 Family::Mordent | Family::Trill => {
615 if let Some(accidental) = &self.accidental {
616 name = format!("{name} ({})", accidental.name());
617 }
618 }
619 Family::Turn => {
620 match self.delay {
621 OrnamentDelay::Default => name = format!("delayed {name}"),
622 OrnamentDelay::Timed(delay) => {
623 name = format!("delayed(delayQL={}) {name}", python_float(delay));
624 }
625 OrnamentDelay::NoDelay => {}
626 }
627 let parts: Vec<String> = [
628 self.upper_accidental
629 .as_ref()
630 .map(|accidental| format!("upper={}", accidental.name())),
631 self.lower_accidental
632 .as_ref()
633 .map(|accidental| format!("lower={}", accidental.name())),
634 ]
635 .into_iter()
636 .flatten()
637 .collect();
638 if !parts.is_empty() {
639 name = format!("{name} ({})", parts.join(", "));
640 }
641 }
642 _ => {}
643 }
644 name
645 }
646
647 pub fn quarter_length(&self) -> FloatType {
650 self.quarter_length
651 }
652
653 pub fn set_quarter_length(&mut self, quarter_length: FloatType) {
655 self.quarter_length = quarter_length;
656 }
657
658 pub fn auto_scale(&self) -> bool {
661 self.auto_scale
662 }
663
664 pub fn set_auto_scale(&mut self, auto_scale: bool) {
666 self.auto_scale = auto_scale;
667 }
668
669 pub fn placement(&self) -> Option<&str> {
671 self.placement.as_deref()
672 }
673
674 pub fn set_placement(&mut self, placement: Option<String>) {
676 self.placement = placement;
677 }
678
679 pub fn tie_attach(&self) -> &str {
681 &self.tie_attach
682 }
683
684 pub fn set_tie_attach(&mut self, attach: impl Into<String>) {
686 self.tie_attach = attach.into();
687 }
688
689 pub fn split_client(
719 &self,
720 stream: &mut Stream,
721 positions: &[usize],
722 ) -> Result<Option<Spanner>> {
723 if !self.is_a("Trill") {
724 return Err(Error::Expression(format!(
725 "a {} is not split with the note it is on; only a trill is",
726 self.kind.class_name()
727 )));
728 }
729 let Some(&first) = positions.first() else {
730 return Ok(None);
731 };
732 let mut position = 0;
733 let mut placed = false;
734 stream.for_each_mut(&mut |_, element| {
735 if position == first {
736 let expressions = match element {
737 StreamElement::Note(note) => Some(note.expressions_mut()),
738 StreamElement::Chord(chord) => Some(chord.expressions_mut()),
739 StreamElement::Rest(rest) => Some(rest.expressions_mut()),
740 StreamElement::Unpitched(stroke) => {
741 Some(stroke.written_mut().expressions_mut())
742 }
743 _ => None,
744 };
745 if let Some(expressions) = expressions {
746 expressions.push(Expression::from(self.clone()));
747 placed = true;
748 }
749 }
750 position += 1;
751 });
752 if !placed {
753 return Err(Error::Expression(format!(
754 "there is no note at position {first} to carry the trill"
755 )));
756 }
757 let extended = stream.spanners().iter().any(|spanner| {
758 spanner.kind() == SpannerKind::TrillExtension
759 && spanner.spanned().contains(&Some(first))
760 });
761 if positions.len() > 1 && !extended {
762 return Ok(Some(Spanner::new(
763 SpannerKind::TrillExtension,
764 positions.to_vec(),
765 )));
766 }
767 Ok(None)
768 }
769
770 pub fn accidental(&self) -> Option<&Accidental> {
773 self.accidental.as_ref()
774 }
775
776 pub fn set_accidental(&mut self, accidental: Option<Accidental>) -> Result<()> {
782 if self.kind.has_fixed_size() {
783 return Err(Error::Expression(format!(
784 "Cannot set accidental of {}",
785 self.kind.class_name()
786 )));
787 }
788 self.accidental = accidental;
789 Ok(())
790 }
791
792 pub fn upper_accidental(&self) -> Option<&Accidental> {
794 self.upper_accidental.as_ref()
795 }
796
797 pub fn set_upper_accidental(&mut self, accidental: Option<Accidental>) {
799 self.upper_accidental = accidental;
800 }
801
802 pub fn lower_accidental(&self) -> Option<&Accidental> {
804 self.lower_accidental.as_ref()
805 }
806
807 pub fn set_lower_accidental(&mut self, accidental: Option<Accidental>) {
809 self.lower_accidental = accidental;
810 }
811
812 pub fn delay(&self) -> OrnamentDelay {
814 self.delay
815 }
816
817 pub fn set_delay(&mut self, delay: OrnamentDelay) {
819 self.delay = match delay {
820 OrnamentDelay::Timed(length) if length <= 0.0 => OrnamentDelay::NoDelay,
821 other => other,
822 };
823 }
824
825 pub fn is_delayed(&self) -> bool {
827 self.delay != OrnamentDelay::NoDelay
828 }
829
830 pub fn nachschlag(&self) -> bool {
833 self.nachschlag
834 }
835
836 pub fn set_nachschlag(&mut self, nachschlag: bool) {
838 self.nachschlag = nachschlag;
839 }
840
841 pub fn number_of_marks(&self) -> u8 {
843 self.number_of_marks
844 }
845
846 pub fn set_number_of_marks(&mut self, marks: u8) -> Result<()> {
852 if marks > 8 {
853 return Err(Error::Expression(
854 "Number of marks must be a number from 0 to 8".to_string(),
855 ));
856 }
857 self.number_of_marks = marks;
858 Ok(())
859 }
860
861 pub fn measured(&self) -> bool {
863 self.measured
864 }
865
866 pub fn set_measured(&mut self, measured: bool) {
868 self.measured = measured;
869 }
870
871 pub fn appoggiatura_size(&self) -> Option<&Interval> {
873 self.size.as_ref()
874 }
875
876 pub fn set_appoggiatura_size(&mut self, size: Option<Interval>) {
878 self.size = size;
879 }
880
881 pub fn size(&self, source: &Pitch, key: &KeySignature) -> Result<Interval> {
900 let row = self.kind.row();
901 let what = match row.family {
902 Family::Mordent => "mordent",
903 Family::Trill => "trill",
904 _ => {
905 return Err(Error::Expression(format!(
906 "a {} has no single size",
907 self.name()
908 )));
909 }
910 };
911 if let Some(name) = row.fixed_size {
912 return Interval::from_name(name);
913 }
914 let Some(up) = row.up else {
915 return Err(Error::Expression(format!(
916 "Cannot compute {what} size if I do not know its direction"
917 )));
918 };
919 neighbour(source, up, self.accidental.as_ref(), key)
920 }
921
922 pub fn turn_size(
929 &self,
930 source: &Pitch,
931 which: TurnNote,
932 key: &KeySignature,
933 ) -> Result<Interval> {
934 if self.family() != Family::Turn {
935 return Err(Error::Expression(format!(
936 "a {} is not a turn",
937 self.name()
938 )));
939 }
940 match which {
941 TurnNote::Upper => neighbour(source, true, self.upper_accidental.as_ref(), key),
942 TurnNote::Lower => neighbour(source, false, self.lower_accidental.as_ref(), key),
943 }
944 }
945
946 pub fn ornamental_pitches(&self, source: &Pitch, key: &KeySignature) -> Result<Vec<Pitch>> {
956 let resolved = |interval: &Interval, accidental: Option<&Accidental>| -> Result<Pitch> {
957 let mut from = source.clone();
958 from.set_octave_is_implicit(false);
959 let mut ornamental = from.transpose(interval)?;
960 if ornamental
961 .microtone()
962 .is_some_and(|microtone| microtone.cents() != 0.0)
963 {
964 ornamental = ornamental.convert_microtones_to_quarter_tones()?;
965 }
966 if let Some(accidental) = accidental {
967 let status = accidental.display_status();
968 let mut written = ornamental.accidental().clone();
969 written.set_display_status(status);
970 ornamental.set_accidental(written);
971 }
972 Ok(ornamental)
973 };
974 match self.family() {
975 Family::Mordent | Family::Trill => {
976 let interval = self.size(source, key)?;
977 Ok(vec![resolved(&interval, self.accidental.as_ref())?])
978 }
979 Family::Turn => {
980 let upper = self.turn_size(source, TurnNote::Upper, key)?;
981 let lower = self.turn_size(source, TurnNote::Lower, key)?;
982 Ok(vec![
983 resolved(&upper, self.upper_accidental.as_ref())?,
984 resolved(&lower, self.lower_accidental.as_ref())?,
985 ])
986 }
987 _ => Ok(Vec::new()),
988 }
989 }
990
991 pub fn update_accidental_display(
1003 &self,
1004 ornamental: &mut [Pitch],
1005 options: &AccidentalDisplayOptions<'_>,
1006 ) {
1007 let governing = match self.family() {
1008 Family::Mordent | Family::Trill => vec![self.accidental.as_ref()],
1009 Family::Turn => vec![
1010 self.upper_accidental.as_ref(),
1011 self.lower_accidental.as_ref(),
1012 ],
1013 _ => return,
1014 };
1015 let untied = AccidentalDisplayOptions {
1016 other_simultaneous_pitches: &[],
1017 last_note_was_tied: false,
1018 ..*options
1019 };
1020 for (pitch, accidental) in ornamental.iter_mut().zip(governing) {
1021 let says = accidental.filter(|accidental| accidental.display_status().is_some());
1022 match says {
1023 Some(accidental) => {
1024 let mut shown = pitch.accidental().clone();
1025 shown.set_display_status(accidental.display_status());
1026 pitch.set_accidental(shown);
1027 }
1028 None => pitch.update_accidental_display(&untied),
1029 }
1030 }
1031 }
1032
1033 pub fn realize(&self, note: &Note, key: &KeySignature) -> Result<Realization> {
1042 let length = note.duration().map_or(1.0, Duration::quarter_length);
1044 match self.family() {
1045 Family::Plain => Ok(Realization {
1046 before: Vec::new(),
1047 main: Some(note.clone()),
1048 after: Vec::new(),
1049 }),
1050 Family::Mordent => self.realize_mordent(note, key, length),
1051 Family::Trill => self.realize_trill(note, key, length),
1052 Family::Turn => self.realize_turn(note, key, length),
1053 Family::Appoggiatura => self.realize_appoggiatura(note, length),
1054 Family::Tremolo => self.realize_tremolo(note, length),
1055 }
1056 }
1057
1058 fn realize_mordent(
1059 &self,
1060 note: &Note,
1061 key: &KeySignature,
1062 length: FloatType,
1063 ) -> Result<Realization> {
1064 if self.kind.row().up.is_none() {
1065 return Err(Error::Expression(
1066 "Cannot realize a mordent if I do not know its direction".to_string(),
1067 ));
1068 }
1069 no_time_to_steal(length)?;
1070 let mut each = self.quarter_length;
1071 if length <= self.quarter_length * 2.0 {
1072 if !self.auto_scale {
1073 return Err(Error::Expression(
1074 "The note is not long enough to realize a mordent".to_string(),
1075 ));
1076 }
1077 each = length / 4.0;
1078 }
1079 let interval = self.size(note.pitch(), key)?;
1080 let mut second = lasting(note, each)?;
1081 let mut moved = second.pitch().transpose(&interval)?;
1082 if moved.written_accidental().is_none() {
1083 moved.set_written_accidental(key.accidental_by_step(moved.step().as_char())?);
1084 }
1085 second.set_pitch(moved);
1086 Ok(Realization {
1087 before: vec![lasting(note, each)?, second],
1088 main: Some(lasting(&self.taken_off(note), length - 2.0 * each)?),
1089 after: Vec::new(),
1090 })
1091 }
1092
1093 fn realize_trill(
1094 &self,
1095 note: &Note,
1096 key: &KeySignature,
1097 length: FloatType,
1098 ) -> Result<Realization> {
1099 no_time_to_steal(length)?;
1100 let mut each = self.quarter_length;
1101 if length < 2.0 * each {
1102 if !self.auto_scale {
1103 return Err(Error::Expression(
1104 "The note is not long enough to realize a trill".to_string(),
1105 ));
1106 }
1107 each = length / 2.0;
1108 }
1109 if length < 4.0 * self.quarter_length && self.nachschlag {
1110 if !self.auto_scale {
1111 return Err(Error::Expression(
1112 "The note is not long enough for a nachschlag".to_string(),
1113 ));
1114 }
1115 each = length / 4.0;
1116 }
1117 let interval = self.size(note.pitch(), key)?;
1118 let from_key = !self.kind.has_fixed_size();
1119 let mut count = (length / each) as IntegerType;
1120 if self.nachschlag {
1121 count -= 2;
1122 }
1123 let written = note.pitch().name_with_octave();
1124 let mut trilled = Vec::new();
1125 for _ in 0..(count / 2) {
1126 trilled.push(lasting(note, each)?);
1127 let mut upper = lasting(note, each)?;
1128 upper.set_pitch(upper.pitch().transpose(&interval)?);
1129 trilled.push(upper);
1130 }
1131 if from_key {
1132 for played in &mut trilled {
1133 if played.pitch().name_with_octave() != written
1134 && played.pitch().written_accidental().is_none()
1135 {
1136 let mut pitch = played.pitch().clone();
1137 pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1138 played.set_pitch(pitch);
1139 }
1140 }
1141 }
1142 if !self.nachschlag {
1143 return Ok(Realization {
1144 before: trilled,
1145 main: None,
1146 after: Vec::new(),
1147 });
1148 }
1149 let mut first = lasting(&unmarked(note), each)?;
1151 let mut second = lasting(&unmarked(note), each)?;
1152 second.set_pitch(second.pitch().transpose(&interval.reversed()?)?);
1153 if from_key {
1154 for played in [&mut first, &mut second] {
1155 let mut pitch = played.pitch().clone();
1156 pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1157 played.set_pitch(pitch);
1158 }
1159 }
1160 Ok(Realization {
1161 before: trilled,
1162 main: None,
1163 after: vec![first, second],
1164 })
1165 }
1166
1167 fn realize_turn(
1168 &self,
1169 note: &Note,
1170 key: &KeySignature,
1171 length: FloatType,
1172 ) -> Result<Realization> {
1173 no_time_to_steal(length)?;
1174 let remainder = match self.delay {
1175 OrnamentDelay::NoDelay => 0.0,
1176 OrnamentDelay::Default => length / 2.0,
1177 OrnamentDelay::Timed(delay) => delay,
1178 };
1179 let turn_length = length - remainder;
1180 let mut each = self.quarter_length;
1181 let mut last = None;
1182 if turn_length < 4.0 * self.quarter_length {
1183 if !self.auto_scale {
1184 return Err(Error::Expression(
1185 "The note is not long enough to realize a turn".to_string(),
1186 ));
1187 }
1188 each = turn_length / 4.0;
1189 } else if turn_length > 4.0 * self.quarter_length {
1190 last = Some(turn_length - 3.0 * each);
1191 }
1192 let inverted = self.kind == OrnamentKind::InvertedTurn;
1193 let (first_side, third_side) = if inverted {
1194 (TurnNote::Lower, TurnNote::Upper)
1195 } else {
1196 (TurnNote::Upper, TurnNote::Lower)
1197 };
1198 let first_interval = self.turn_size(note.pitch(), first_side, key)?;
1199 let third_interval = self.turn_size(note.pitch(), third_side, key)?;
1200 let plain = unmarked(note);
1202 let mut first = lasting(&plain, each)?;
1203 first.set_pitch(first.pitch().transpose(&first_interval)?);
1204 let second = lasting(&plain, each)?;
1205 let mut third = lasting(&plain, each)?;
1206 third.set_pitch(third.pitch().transpose(&third_interval)?);
1207 let fourth = lasting(&plain, last.unwrap_or(each))?;
1208 let mut turned = vec![first, second, third, fourth];
1209 for index in [0, 2] {
1210 if turned[index].pitch().written_accidental().is_none() {
1211 let mut pitch = turned[index].pitch().clone();
1212 pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1213 turned[index].set_pitch(pitch);
1214 }
1215 }
1216 if remainder == 0.0 {
1217 return Ok(Realization {
1218 before: Vec::new(),
1219 main: None,
1220 after: turned,
1221 });
1222 }
1223 Ok(Realization {
1224 before: Vec::new(),
1225 main: Some(lasting(&self.taken_off(note), remainder)?),
1226 after: turned,
1227 })
1228 }
1229
1230 fn realize_appoggiatura(&self, note: &Note, length: FloatType) -> Result<Realization> {
1231 let Some(up) = self.kind.row().up else {
1232 return Err(Error::Expression(
1233 "Cannot realize an Appoggiatura if I do not know its direction".to_string(),
1234 ));
1235 };
1236 let Some(size) = &self.size else {
1237 return Err(Error::Expression(
1238 "Cannot realize an Appoggiatura if there is no size given".to_string(),
1239 ));
1240 };
1241 no_time_to_steal(length)?;
1242 let half = length / 2.0;
1243 let interval = if up { size.reversed()? } else { size.clone() };
1244 let mut leaning = lasting(note, half)?;
1245 leaning.set_pitch(leaning.pitch().transpose(&interval)?);
1246 Ok(Realization {
1247 before: vec![leaning],
1248 main: Some(lasting(&self.taken_off(note), half)?),
1249 after: Vec::new(),
1250 })
1251 }
1252
1253 fn realize_tremolo(&self, note: &Note, length: FloatType) -> Result<Realization> {
1254 let each = (0.5 as FloatType).powi(IntegerType::from(self.number_of_marks));
1255 let mut repeated = Vec::new();
1256 let mut remaining = self.taken_off(note);
1257 let mut left = length;
1258 while left > each {
1259 let mut played = lasting(&remaining, each)?;
1260 left -= each;
1261 remaining = lasting(&remaining, left)?;
1262 tie_split(&mut played, &mut remaining);
1263 repeated.push(played);
1264 }
1265 repeated.push(remaining);
1266 Ok(Realization {
1267 before: repeated,
1268 main: None,
1269 after: Vec::new(),
1270 })
1271 }
1272}
1273
1274impl Ornament {
1275 fn taken_off(&self, note: &Note) -> Note {
1278 let mut left = note.clone();
1279 let expressions = left.expressions_mut();
1280 if let Some(at) = expressions.iter().position(
1281 |expression| matches!(expression, Expression::Ornament(ornament) if **ornament == *self),
1282 ) {
1283 expressions.remove(at);
1284 }
1285 left
1286 }
1287}
1288
1289fn unmarked(note: &Note) -> Note {
1291 let mut plain = note.clone();
1292 plain.expressions_mut().clear();
1293 plain
1294}
1295
1296fn tie_split(first: &mut Note, rest: &mut Note) {
1300 let rest_type = match first.tie().map(Tie::tie_type) {
1301 None => {
1302 first.set_tie(Some(Tie::new(TieType::Start)));
1303 TieType::Stop
1304 }
1305 Some(TieType::Stop) => {
1306 first.set_tie(Some(Tie::new(TieType::Continue)));
1307 TieType::Stop
1308 }
1309 Some(TieType::Start | TieType::Continue) => TieType::Continue,
1310 Some(_) => TieType::Stop,
1311 };
1312 rest.set_tie(Some(Tie::new(rest_type)));
1313}
1314
1315fn no_time_to_steal(length: FloatType) -> Result<()> {
1317 if length == 0.0 {
1318 return Err(Error::Expression(
1319 "Cannot steal time from an object with no duration".to_string(),
1320 ));
1321 }
1322 Ok(())
1323}
1324
1325fn lasting(note: &Note, quarter_length: FloatType) -> Result<Note> {
1327 let mut copy = note.clone();
1328 copy.set_duration(Duration::new(quarter_length)?);
1329 Ok(copy)
1330}
1331
1332fn neighbour(
1336 source: &Pitch,
1337 up: bool,
1338 accidental: Option<&Accidental>,
1339 key: &KeySignature,
1340) -> Result<Interval> {
1341 let mut ornamental = source.clone();
1342 ornamental.set_written_accidental(None);
1343 ornamental.set_octave_is_implicit(false);
1344 let mut ornamental =
1345 GenericInterval::new(if up { 2 } else { -2 })?.transpose_pitch(&ornamental)?;
1346 let spelled = match accidental {
1347 Some(accidental) => Some(accidental.clone()),
1348 None => key.accidental_by_step(ornamental.step().as_char())?,
1349 };
1350 ornamental.set_written_accidental(spelled);
1351 Interval::between_pitches(source, &ornamental)
1352}
1353
1354pub(crate) fn python_float(value: FloatType) -> String {
1356 if value.fract() == 0.0 {
1357 format!("{value:.1}")
1358 } else {
1359 value.to_string()
1360 }
1361}
1362
1363#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1365#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1366pub enum FermataType {
1367 Upright,
1369 #[default]
1371 Inverted,
1372}
1373
1374impl FermataType {
1375 pub fn as_str(self) -> &'static str {
1377 match self {
1378 Self::Upright => "upright",
1379 Self::Inverted => "inverted",
1380 }
1381 }
1382}
1383
1384#[derive(Clone, Debug, Default, PartialEq, Eq)]
1386#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1387#[must_use]
1388pub struct Fermata {
1389 fermata_type: FermataType,
1390 shape: Option<String>,
1391}
1392
1393impl Fermata {
1394 pub fn new() -> Self {
1396 Self::default()
1397 }
1398
1399 pub fn fermata_type(&self) -> FermataType {
1401 self.fermata_type
1402 }
1403
1404 pub fn set_fermata_type(&mut self, fermata_type: FermataType) {
1406 self.fermata_type = fermata_type;
1407 }
1408
1409 pub fn shape(&self) -> Option<&str> {
1412 self.shape.as_deref()
1413 }
1414
1415 pub fn set_shape(&mut self, shape: Option<String>) {
1417 self.shape = shape.filter(|shape| shape != "normal");
1418 }
1419}
1420
1421#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1423#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1424pub enum ArpeggioType {
1425 #[default]
1427 Normal,
1428 Up,
1430 Down,
1432 NonArpeggio,
1434}
1435
1436impl ArpeggioType {
1437 pub fn as_str(self) -> &'static str {
1439 match self {
1440 Self::Normal => "normal",
1441 Self::Up => "up",
1442 Self::Down => "down",
1443 Self::NonArpeggio => "non-arpeggio",
1444 }
1445 }
1446
1447 pub fn from_name(name: &str) -> Result<Self> {
1449 match name {
1450 "normal" => Ok(Self::Normal),
1451 "up" => Ok(Self::Up),
1452 "down" => Ok(Self::Down),
1453 "non-arpeggio" => Ok(Self::NonArpeggio),
1454 other => Err(Error::Value(format!(
1455 "Arpeggio type must be \"normal\", \"up\", \"down\", or \"non-arpeggio\", not '{other}'."
1456 ))),
1457 }
1458 }
1459}
1460
1461#[derive(Clone, Debug, Default, PartialEq, Eq)]
1465#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1466#[must_use]
1467pub struct TextExpression {
1468 content: String,
1469 #[cfg_attr(feature = "serde", serde(default))]
1470 placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1471}
1472
1473impl TextExpression {
1474 pub fn new(content: impl Into<String>) -> Self {
1476 Self {
1477 content: content.into(),
1478 placement: crate::display::Drawn(None),
1479 }
1480 }
1481
1482 pub fn content(&self) -> &str {
1484 &self.content
1485 }
1486
1487 pub fn set_content(&mut self, content: impl Into<String>) {
1489 self.content = content.into();
1490 }
1491
1492 pub fn placement(&self) -> Option<crate::notation::Placement> {
1495 self.placement.0
1496 }
1497
1498 pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1500 self.placement.0 = placement;
1501 }
1502}
1503
1504#[derive(Clone, Debug, Default, PartialEq, Eq)]
1507#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1508#[must_use]
1509pub struct RehearsalMark {
1510 content: String,
1511 #[cfg_attr(feature = "serde", serde(default))]
1512 placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1513 #[cfg_attr(feature = "serde", serde(default))]
1514 enclosure: crate::display::Drawn<Option<String>>,
1515}
1516
1517impl RehearsalMark {
1518 pub fn new(content: impl Into<String>) -> Self {
1520 Self {
1521 content: content.into(),
1522 placement: crate::display::Drawn(None),
1523 enclosure: crate::display::Drawn(None),
1524 }
1525 }
1526
1527 pub fn content(&self) -> &str {
1529 &self.content
1530 }
1531
1532 pub fn set_content(&mut self, content: impl Into<String>) {
1534 self.content = content.into();
1535 }
1536
1537 pub fn placement(&self) -> Option<crate::notation::Placement> {
1540 self.placement.0
1541 }
1542
1543 pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1545 self.placement.0 = placement;
1546 }
1547
1548 pub fn enclosure(&self) -> Option<&str> {
1551 self.enclosure.0.as_deref()
1552 }
1553
1554 pub fn set_enclosure(&mut self, enclosure: Option<String>) {
1556 self.enclosure.0 = enclosure;
1557 }
1558}
1559
1560#[derive(Clone, Debug, PartialEq)]
1563#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1564#[non_exhaustive]
1565pub enum Expression {
1566 Ornament(Box<Ornament>),
1569 Fermata(Fermata),
1571 Arpeggio(ArpeggioType),
1573}
1574
1575impl From<Ornament> for Expression {
1576 fn from(value: Ornament) -> Self {
1577 Self::Ornament(Box::new(value))
1578 }
1579}
1580
1581impl From<Fermata> for Expression {
1582 fn from(value: Fermata) -> Self {
1583 Self::Fermata(value)
1584 }
1585}
1586
1587impl Expression {
1588 pub fn tie_attach(&self) -> &str {
1593 match self {
1594 Self::Ornament(ornament) => ornament.tie_attach(),
1595 Self::Fermata(_) => "last",
1596 Self::Arpeggio(_) => "first",
1597 }
1598 }
1599
1600 fn is_trill(&self) -> bool {
1603 matches!(self, Self::Ornament(ornament) if ornament.is_a("Trill"))
1604 }
1605}
1606
1607pub(crate) fn split_expressions(expressions: &[Expression]) -> (Vec<Expression>, Vec<Expression>) {
1613 let mut first = Vec::new();
1614 let mut second = Vec::new();
1615 for expression in expressions {
1616 if expression.is_trill() {
1617 first.push(expression.clone());
1618 continue;
1619 }
1620 match expression.tie_attach() {
1621 "first" => first.push(expression.clone()),
1622 "last" => second.push(expression.clone()),
1623 _ => {
1624 first.push(expression.clone());
1625 second.push(expression.clone());
1626 }
1627 }
1628 }
1629 (first, second)
1630}
1631
1632pub fn realize_ornaments(
1645 note: &Note,
1646 ornaments: &[Ornament],
1647 key: &KeySignature,
1648) -> Result<Vec<Note>> {
1649 let mut before = Vec::new();
1650 let mut after: Vec<Note> = Vec::new();
1651 let mut current = Some(note.clone());
1652 for ornament in ornaments {
1653 let Some(main) = current.take() else {
1654 break;
1655 };
1656 let played = ornament.realize(&main, key)?;
1657 before.extend(played.before);
1658 after.extend(played.after);
1659 current = played.main;
1660 }
1661 before.extend(current);
1662 before.extend(after);
1663 Ok(before)
1664}
1665
1666#[cfg(test)]
1667mod tests {
1668 use super::*;
1669
1670 fn written(notes: Vec<Note>) -> Vec<String> {
1671 notes
1672 .iter()
1673 .map(|note| {
1674 let length = note.duration().map_or(1.0, Duration::quarter_length);
1675 match note.tie() {
1676 Some(tie) => format!(
1677 "{} {length} {}",
1678 note.pitch().name_with_octave(),
1679 tie.tie_type().as_str()
1680 ),
1681 None => format!("{} {length}", note.pitch().name_with_octave()),
1682 }
1683 })
1684 .collect()
1685 }
1686
1687 #[test]
1689 fn an_ornament_answers_what_music21_s_answers() {
1690 let directions = [
1691 (OrnamentKind::GeneralMordent, None),
1692 (OrnamentKind::Mordent, Some(IntervalDirection::Descending)),
1693 (
1694 OrnamentKind::InvertedMordent,
1695 Some(IntervalDirection::Ascending),
1696 ),
1697 (OrnamentKind::Trill, Some(IntervalDirection::Ascending)),
1698 (
1699 OrnamentKind::InvertedTrill,
1700 Some(IntervalDirection::Descending),
1701 ),
1702 (OrnamentKind::Shake, Some(IntervalDirection::Ascending)),
1703 (OrnamentKind::GeneralAppoggiatura, None),
1704 (
1705 OrnamentKind::Appoggiatura,
1706 Some(IntervalDirection::Descending),
1707 ),
1708 (
1709 OrnamentKind::InvertedAppoggiatura,
1710 Some(IntervalDirection::Ascending),
1711 ),
1712 (OrnamentKind::Turn, None),
1713 ];
1714 for (kind, direction) in directions {
1715 assert_eq!(Ornament::of_kind(kind).direction(), direction, "{kind:?}");
1716 }
1717
1718 let key = KeySignature::new(0);
1719 let mut quarter = Note::from_name("C4").unwrap();
1720 quarter.set_duration(Duration::new(1.0).unwrap());
1721 let tremolo = Ornament::of_kind(OrnamentKind::Tremolo);
1722 let played = tremolo.realize(&quarter, &key).unwrap().into_notes();
1723 assert_eq!(played.len(), 8);
1724 assert_eq!(
1725 written(played)[..2],
1726 ["C4 0.125 start", "C4 0.125 continue"]
1727 );
1728
1729 let mut half_step = Ornament::of_kind(OrnamentKind::HalfStepMordent);
1730 assert!(
1731 half_step
1732 .set_accidental(Accidental::new("sharp").ok())
1733 .is_err()
1734 );
1735
1736 let mut trill = Ornament::of_kind(OrnamentKind::Trill);
1737 trill.set_nachschlag(true);
1738 let played = written(trill.realize(&quarter, &key).unwrap().into_notes());
1739 assert_eq!(
1740 played,
1741 [
1742 "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125",
1743 "B3 0.125"
1744 ]
1745 );
1746 }
1747}