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(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(note, each)?;
1150 let mut second = lasting(note, each)?;
1151 second.set_pitch(second.pitch().transpose(&interval.reversed()?)?);
1152 if from_key {
1153 for played in [&mut first, &mut second] {
1154 let mut pitch = played.pitch().clone();
1155 pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1156 played.set_pitch(pitch);
1157 }
1158 }
1159 Ok(Realization {
1160 before: trilled,
1161 main: None,
1162 after: vec![first, second],
1163 })
1164 }
1165
1166 fn realize_turn(
1167 &self,
1168 note: &Note,
1169 key: &KeySignature,
1170 length: FloatType,
1171 ) -> Result<Realization> {
1172 no_time_to_steal(length)?;
1173 let remainder = match self.delay {
1174 OrnamentDelay::NoDelay => 0.0,
1175 OrnamentDelay::Default => length / 2.0,
1176 OrnamentDelay::Timed(delay) => delay,
1177 };
1178 let turn_length = length - remainder;
1179 let mut each = self.quarter_length;
1180 let mut last = None;
1181 if turn_length < 4.0 * self.quarter_length {
1182 if !self.auto_scale {
1183 return Err(Error::Expression(
1184 "The note is not long enough to realize a turn".to_string(),
1185 ));
1186 }
1187 each = turn_length / 4.0;
1188 } else if turn_length > 4.0 * self.quarter_length {
1189 last = Some(turn_length - 3.0 * each);
1190 }
1191 let inverted = self.kind == OrnamentKind::InvertedTurn;
1192 let (first_side, third_side) = if inverted {
1193 (TurnNote::Lower, TurnNote::Upper)
1194 } else {
1195 (TurnNote::Upper, TurnNote::Lower)
1196 };
1197 let first_interval = self.turn_size(note.pitch(), first_side, key)?;
1198 let third_interval = self.turn_size(note.pitch(), third_side, key)?;
1199 let mut first = lasting(note, each)?;
1200 first.set_pitch(first.pitch().transpose(&first_interval)?);
1201 let second = lasting(note, each)?;
1202 let mut third = lasting(note, each)?;
1203 third.set_pitch(third.pitch().transpose(&third_interval)?);
1204 let fourth = lasting(note, last.unwrap_or(each))?;
1205 let mut turned = vec![first, second, third, fourth];
1206 for index in [0, 2] {
1207 if turned[index].pitch().written_accidental().is_none() {
1208 let mut pitch = turned[index].pitch().clone();
1209 pitch.set_written_accidental(key.accidental_by_step(pitch.step().as_char())?);
1210 turned[index].set_pitch(pitch);
1211 }
1212 }
1213 if remainder == 0.0 {
1214 return Ok(Realization {
1215 before: Vec::new(),
1216 main: None,
1217 after: turned,
1218 });
1219 }
1220 Ok(Realization {
1221 before: Vec::new(),
1222 main: Some(lasting(note, remainder)?),
1223 after: turned,
1224 })
1225 }
1226
1227 fn realize_appoggiatura(&self, note: &Note, length: FloatType) -> Result<Realization> {
1228 let Some(up) = self.kind.row().up else {
1229 return Err(Error::Expression(
1230 "Cannot realize an Appoggiatura if I do not know its direction".to_string(),
1231 ));
1232 };
1233 let Some(size) = &self.size else {
1234 return Err(Error::Expression(
1235 "Cannot realize an Appoggiatura if there is no size given".to_string(),
1236 ));
1237 };
1238 no_time_to_steal(length)?;
1239 let half = length / 2.0;
1240 let interval = if up { size.reversed()? } else { size.clone() };
1241 let mut leaning = lasting(note, half)?;
1242 leaning.set_pitch(leaning.pitch().transpose(&interval)?);
1243 Ok(Realization {
1244 before: vec![leaning],
1245 main: Some(lasting(note, half)?),
1246 after: Vec::new(),
1247 })
1248 }
1249
1250 fn realize_tremolo(&self, note: &Note, length: FloatType) -> Result<Realization> {
1251 let each = (0.5 as FloatType).powi(IntegerType::from(self.number_of_marks));
1252 let mut repeated = Vec::new();
1253 let mut remaining = note.clone();
1254 let mut left = length;
1255 while left > each {
1256 let mut played = lasting(&remaining, each)?;
1257 left -= each;
1258 remaining = lasting(&remaining, left)?;
1259 tie_split(&mut played, &mut remaining);
1260 repeated.push(played);
1261 }
1262 repeated.push(remaining);
1263 Ok(Realization {
1264 before: repeated,
1265 main: None,
1266 after: Vec::new(),
1267 })
1268 }
1269}
1270
1271fn tie_split(first: &mut Note, rest: &mut Note) {
1275 let rest_type = match first.tie().map(Tie::tie_type) {
1276 None => {
1277 first.set_tie(Some(Tie::new(TieType::Start)));
1278 TieType::Stop
1279 }
1280 Some(TieType::Stop) => {
1281 first.set_tie(Some(Tie::new(TieType::Continue)));
1282 TieType::Stop
1283 }
1284 Some(TieType::Start | TieType::Continue) => TieType::Continue,
1285 Some(_) => TieType::Stop,
1286 };
1287 rest.set_tie(Some(Tie::new(rest_type)));
1288}
1289
1290fn no_time_to_steal(length: FloatType) -> Result<()> {
1292 if length == 0.0 {
1293 return Err(Error::Expression(
1294 "Cannot steal time from an object with no duration".to_string(),
1295 ));
1296 }
1297 Ok(())
1298}
1299
1300fn lasting(note: &Note, quarter_length: FloatType) -> Result<Note> {
1302 let mut copy = note.clone();
1303 copy.set_duration(Duration::new(quarter_length)?);
1304 Ok(copy)
1305}
1306
1307fn neighbour(
1311 source: &Pitch,
1312 up: bool,
1313 accidental: Option<&Accidental>,
1314 key: &KeySignature,
1315) -> Result<Interval> {
1316 let mut ornamental = source.clone();
1317 ornamental.set_written_accidental(None);
1318 ornamental.set_octave_is_implicit(false);
1319 let mut ornamental =
1320 GenericInterval::new(if up { 2 } else { -2 })?.transpose_pitch(&ornamental)?;
1321 let spelled = match accidental {
1322 Some(accidental) => Some(accidental.clone()),
1323 None => key.accidental_by_step(ornamental.step().as_char())?,
1324 };
1325 ornamental.set_written_accidental(spelled);
1326 Interval::between_pitches(source, &ornamental)
1327}
1328
1329pub(crate) fn python_float(value: FloatType) -> String {
1331 if value.fract() == 0.0 {
1332 format!("{value:.1}")
1333 } else {
1334 value.to_string()
1335 }
1336}
1337
1338#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1340#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1341pub enum FermataType {
1342 Upright,
1344 #[default]
1346 Inverted,
1347}
1348
1349impl FermataType {
1350 pub fn as_str(self) -> &'static str {
1352 match self {
1353 Self::Upright => "upright",
1354 Self::Inverted => "inverted",
1355 }
1356 }
1357}
1358
1359#[derive(Clone, Debug, Default, PartialEq, Eq)]
1361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1362#[must_use]
1363pub struct Fermata {
1364 fermata_type: FermataType,
1365 shape: Option<String>,
1366}
1367
1368impl Fermata {
1369 pub fn new() -> Self {
1371 Self::default()
1372 }
1373
1374 pub fn fermata_type(&self) -> FermataType {
1376 self.fermata_type
1377 }
1378
1379 pub fn set_fermata_type(&mut self, fermata_type: FermataType) {
1381 self.fermata_type = fermata_type;
1382 }
1383
1384 pub fn shape(&self) -> Option<&str> {
1387 self.shape.as_deref()
1388 }
1389
1390 pub fn set_shape(&mut self, shape: Option<String>) {
1392 self.shape = shape.filter(|shape| shape != "normal");
1393 }
1394}
1395
1396#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1398#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1399pub enum ArpeggioType {
1400 #[default]
1402 Normal,
1403 Up,
1405 Down,
1407 NonArpeggio,
1409}
1410
1411impl ArpeggioType {
1412 pub fn as_str(self) -> &'static str {
1414 match self {
1415 Self::Normal => "normal",
1416 Self::Up => "up",
1417 Self::Down => "down",
1418 Self::NonArpeggio => "non-arpeggio",
1419 }
1420 }
1421
1422 pub fn from_name(name: &str) -> Result<Self> {
1424 match name {
1425 "normal" => Ok(Self::Normal),
1426 "up" => Ok(Self::Up),
1427 "down" => Ok(Self::Down),
1428 "non-arpeggio" => Ok(Self::NonArpeggio),
1429 other => Err(Error::Value(format!(
1430 "Arpeggio type must be \"normal\", \"up\", \"down\", or \"non-arpeggio\", not '{other}'."
1431 ))),
1432 }
1433 }
1434}
1435
1436#[derive(Clone, Debug, Default, PartialEq, Eq)]
1440#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1441#[must_use]
1442pub struct TextExpression {
1443 content: String,
1444 #[cfg_attr(feature = "serde", serde(default))]
1445 placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1446}
1447
1448impl TextExpression {
1449 pub fn new(content: impl Into<String>) -> Self {
1451 Self {
1452 content: content.into(),
1453 placement: crate::display::Drawn(None),
1454 }
1455 }
1456
1457 pub fn content(&self) -> &str {
1459 &self.content
1460 }
1461
1462 pub fn set_content(&mut self, content: impl Into<String>) {
1464 self.content = content.into();
1465 }
1466
1467 pub fn placement(&self) -> Option<crate::notation::Placement> {
1470 self.placement.0
1471 }
1472
1473 pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1475 self.placement.0 = placement;
1476 }
1477}
1478
1479#[derive(Clone, Debug, Default, PartialEq, Eq)]
1482#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1483#[must_use]
1484pub struct RehearsalMark {
1485 content: String,
1486 #[cfg_attr(feature = "serde", serde(default))]
1487 placement: crate::display::Drawn<Option<crate::notation::Placement>>,
1488 #[cfg_attr(feature = "serde", serde(default))]
1489 enclosure: crate::display::Drawn<Option<String>>,
1490}
1491
1492impl RehearsalMark {
1493 pub fn new(content: impl Into<String>) -> Self {
1495 Self {
1496 content: content.into(),
1497 placement: crate::display::Drawn(None),
1498 enclosure: crate::display::Drawn(None),
1499 }
1500 }
1501
1502 pub fn content(&self) -> &str {
1504 &self.content
1505 }
1506
1507 pub fn set_content(&mut self, content: impl Into<String>) {
1509 self.content = content.into();
1510 }
1511
1512 pub fn placement(&self) -> Option<crate::notation::Placement> {
1515 self.placement.0
1516 }
1517
1518 pub fn set_placement(&mut self, placement: Option<crate::notation::Placement>) {
1520 self.placement.0 = placement;
1521 }
1522
1523 pub fn enclosure(&self) -> Option<&str> {
1526 self.enclosure.0.as_deref()
1527 }
1528
1529 pub fn set_enclosure(&mut self, enclosure: Option<String>) {
1531 self.enclosure.0 = enclosure;
1532 }
1533}
1534
1535#[derive(Clone, Debug, PartialEq)]
1538#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1539pub enum Expression {
1540 Ornament(Box<Ornament>),
1543 Fermata(Fermata),
1545 Arpeggio(ArpeggioType),
1547}
1548
1549impl From<Ornament> for Expression {
1550 fn from(value: Ornament) -> Self {
1551 Self::Ornament(Box::new(value))
1552 }
1553}
1554
1555impl From<Fermata> for Expression {
1556 fn from(value: Fermata) -> Self {
1557 Self::Fermata(value)
1558 }
1559}
1560
1561impl Expression {
1562 pub fn tie_attach(&self) -> &str {
1567 match self {
1568 Self::Ornament(ornament) => ornament.tie_attach(),
1569 Self::Fermata(_) => "last",
1570 Self::Arpeggio(_) => "first",
1571 }
1572 }
1573
1574 fn is_trill(&self) -> bool {
1577 matches!(self, Self::Ornament(ornament) if ornament.is_a("Trill"))
1578 }
1579}
1580
1581pub(crate) fn split_expressions(expressions: &[Expression]) -> (Vec<Expression>, Vec<Expression>) {
1587 let mut first = Vec::new();
1588 let mut second = Vec::new();
1589 for expression in expressions {
1590 if expression.is_trill() {
1591 first.push(expression.clone());
1592 continue;
1593 }
1594 match expression.tie_attach() {
1595 "first" => first.push(expression.clone()),
1596 "last" => second.push(expression.clone()),
1597 _ => {
1598 first.push(expression.clone());
1599 second.push(expression.clone());
1600 }
1601 }
1602 }
1603 (first, second)
1604}
1605
1606pub fn realize_ornaments(
1619 note: &Note,
1620 ornaments: &[Ornament],
1621 key: &KeySignature,
1622) -> Result<Vec<Note>> {
1623 let mut before = Vec::new();
1624 let mut after: Vec<Note> = Vec::new();
1625 let mut current = Some(note.clone());
1626 for ornament in ornaments {
1627 let Some(main) = current.take() else {
1628 break;
1629 };
1630 let played = ornament.realize(&main, key)?;
1631 before.extend(played.before);
1632 after.extend(played.after);
1633 current = played.main;
1634 }
1635 before.extend(current);
1636 before.extend(after);
1637 Ok(before)
1638}
1639
1640#[cfg(test)]
1641mod tests {
1642 use super::*;
1643
1644 fn written(notes: Vec<Note>) -> Vec<String> {
1645 notes
1646 .iter()
1647 .map(|note| {
1648 let length = note.duration().map_or(1.0, Duration::quarter_length);
1649 match note.tie() {
1650 Some(tie) => format!(
1651 "{} {length} {}",
1652 note.pitch().name_with_octave(),
1653 tie.tie_type().as_str()
1654 ),
1655 None => format!("{} {length}", note.pitch().name_with_octave()),
1656 }
1657 })
1658 .collect()
1659 }
1660
1661 #[test]
1663 fn an_ornament_answers_what_music21_s_answers() {
1664 let directions = [
1665 (OrnamentKind::GeneralMordent, None),
1666 (OrnamentKind::Mordent, Some(IntervalDirection::Descending)),
1667 (
1668 OrnamentKind::InvertedMordent,
1669 Some(IntervalDirection::Ascending),
1670 ),
1671 (OrnamentKind::Trill, Some(IntervalDirection::Ascending)),
1672 (
1673 OrnamentKind::InvertedTrill,
1674 Some(IntervalDirection::Descending),
1675 ),
1676 (OrnamentKind::Shake, Some(IntervalDirection::Ascending)),
1677 (OrnamentKind::GeneralAppoggiatura, None),
1678 (
1679 OrnamentKind::Appoggiatura,
1680 Some(IntervalDirection::Descending),
1681 ),
1682 (
1683 OrnamentKind::InvertedAppoggiatura,
1684 Some(IntervalDirection::Ascending),
1685 ),
1686 (OrnamentKind::Turn, None),
1687 ];
1688 for (kind, direction) in directions {
1689 assert_eq!(Ornament::of_kind(kind).direction(), direction, "{kind:?}");
1690 }
1691
1692 let key = KeySignature::new(0);
1693 let mut quarter = Note::from_name("C4").unwrap();
1694 quarter.set_duration(Duration::new(1.0).unwrap());
1695 let tremolo = Ornament::of_kind(OrnamentKind::Tremolo);
1696 let played = tremolo.realize(&quarter, &key).unwrap().into_notes();
1697 assert_eq!(played.len(), 8);
1698 assert_eq!(
1699 written(played)[..2],
1700 ["C4 0.125 start", "C4 0.125 continue"]
1701 );
1702
1703 let mut half_step = Ornament::of_kind(OrnamentKind::HalfStepMordent);
1704 assert!(
1705 half_step
1706 .set_accidental(Accidental::new("sharp").ok())
1707 .is_err()
1708 );
1709
1710 let mut trill = Ornament::of_kind(OrnamentKind::Trill);
1711 trill.set_nachschlag(true);
1712 let played = written(trill.realize(&quarter, &key).unwrap().into_notes());
1713 assert_eq!(
1714 played,
1715 [
1716 "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125", "D4 0.125", "C4 0.125",
1717 "B3 0.125"
1718 ]
1719 );
1720 }
1721}