note_pen/
measure.rs

1use crate::{Clef, TimeSignature};
2use crate::chord::Chord;
3use crate::duration::Duration;
4use crate::key::Key;
5use crate::note::Note;
6
7#[derive(Debug, Clone, PartialEq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct Color {
10    pub red: u8,
11    pub green: u8,
12    pub blue: u8,
13    pub alpha: u8,
14}
15
16#[derive(Debug, Clone, PartialEq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Placement {
19    Above,
20    Below
21}
22
23#[derive(Debug, Clone, PartialEq)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub struct Position {
26    pub default_x: Option<f32>,
27    pub default_y: Option<f32>,
28    pub relative_x: Option<f32>,
29    pub relative_y: Option<f32>,
30}
31
32#[derive(Debug, Clone, PartialEq)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct Font {
35    font_family: Option<String>,
36    font_size: Option<f32>,
37    font_style: Option<String>
38}
39
40#[derive(Debug, Clone, PartialEq)]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42pub enum ArticulationType {
43    Accent,
44    StrongAccent,
45    Staccato,
46    Tenuto,
47    DetachedLegato,
48    Staccatissimo,
49    Spiccato,
50    Scoop,
51    Plop,
52    DoIt,
53    FallOff,
54    BreathMark,
55    Caesura,
56    Stress,
57    Unstress,
58    SoftAccent,
59    OtherArticulation {
60        smufl: Option<String>,
61        text: String,
62    },
63}
64
65#[derive(Debug, Clone, PartialEq)]
66#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67pub struct Articulation {
68    pub articulation_type: ArticulationType,
69    pub placement: Option<Placement>,
70    pub position: Option<Position>,
71    pub font: Option<Font>,
72    pub color: Option<Color>,
73}
74
75#[derive(Debug, Clone, PartialEq)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77pub enum OrnamentType {
78    TrillMark,
79    Turn,
80    DelayedTurn,
81    InvertedTurn,
82    DelayedInvertedTurn,
83    VerticalTurn,
84    Shake,
85    WavyLine,
86    Mordent,
87    InvertedMordent,
88    Schleifer,
89    Tremolo,
90    OtherOrnament
91}
92
93#[derive(Debug, Clone, PartialEq)]
94#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
95pub struct Ornament {
96    pub ornament_type: OrnamentType,
97    pub placement: Option<Placement>,
98    pub position: Option<Position>,
99    pub font: Option<Font>,
100    pub color: Option<Color>,
101}
102
103#[derive(Debug, Clone, PartialEq)]
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105pub enum Dynamic {
106    P,
107    PP,
108    PPP,
109    PPPP,
110    PPPPP,
111    PPPPPP,
112    F,
113    FF,
114    FFF,
115    FFFF,
116    FFFFF,
117    FFFFFF,
118    MP,
119    MF,
120    SF,
121    SFP,
122    SFPP,
123    FP,
124    RF,
125    RFZ,
126    SFZ,
127    SFFZ,
128    FZ,
129    N,
130    PF,
131    SFZP,
132    OtherDynamics {
133        glyph_name: String,
134    }
135}
136
137#[derive(Debug, Clone, PartialEq)]
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
139pub struct Tied {
140    // TODO: rest of details
141}
142
143#[derive(Debug, Clone, PartialEq)]
144#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
145pub struct Slur {
146    // TODO: rest of details
147}
148
149#[derive(Debug, Clone, PartialEq)]
150#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
151pub enum ExtendedNotation<T> {
152    Start {
153        placement: Placement,
154        id: u16,
155        details: T
156    },
157    Stop(u16),
158}
159
160#[derive(Debug, Clone, PartialEq)]
161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
162pub enum MultiExtendedNotation<T> {
163    Start {
164        placement: Placement,
165        id: u16,
166        details: T
167    },
168    Stop(u16),
169    Continue(u16),
170}
171
172#[derive(Debug, Clone, PartialEq)]
173#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
174pub enum TechnicalType {
175    UpBow,
176    DownBow,
177    Harmonic,
178    OpenString,
179    ThumbPosition,
180    Fingering,
181    Pluck,
182    DoubleTongue,
183    TripleTongue,
184    Stopped,
185    SnapPizzicato,
186    Fret,
187    String,
188    HammerOn,
189    PullOff,
190    Bend,
191    Tap,
192    Heel,
193    Toe,
194    Fingernails,
195    Hole,
196    // TODO: Finish
197    Arrow,
198    Handbell,
199    BrassBend,
200    Flip,
201    Smear,
202    Open,
203    HalfMuted,
204    HarmonMute,
205    Golpe,
206    // TODO: finish
207    OtherTechnical,
208}
209
210#[derive(Debug, Clone, PartialEq)]
211#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
212pub struct Technical {
213    pub technical_type: TechnicalType,
214    pub placement: Option<Placement>,
215    pub position: Option<Position>,
216    pub font: Option<Font>,
217    pub color: Option<Color>,
218}
219
220#[derive(Debug, Clone, PartialEq)]
221#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
222pub enum Notation {
223    Tied(MultiExtendedNotation<Tied>),
224    Slur(MultiExtendedNotation<Slur>),
225    // TODO: more info
226    Glissando(ExtendedNotation<()>),
227    // TODO: more info
228    Slide(ExtendedNotation<()>),
229    Articulation(Articulation),
230    Ornament(Ornament),
231    Dynamic(Dynamic),
232    Fermata {
233        position: Option<Position>,
234        font: Option<Font>,
235        color: Option<Color>,
236        placement: Placement,
237        // TODO: ensure complete
238    },
239    Tuplet {
240        bracket: Option<bool>,
241        show_number: Option<bool>,
242        show_type: Option<bool>,
243        number: Option<u8>,
244        placement: Option<Placement>,
245        position: Position
246    },
247    Technical(Technical),
248    // TODO: the following
249    // <arpeggiate>
250    // <non-arpeggiate>
251    // <accidental-mark>
252    // <other-notation>
253}
254
255#[derive(Debug, Clone, PartialEq)]
256#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
257pub struct Notations {
258    pub notations: Vec<Notation>,
259}
260
261#[derive(Debug, Clone, PartialEq)]
262#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
263pub enum DirectionType {
264    // TODO: fill in
265    Rehearsal,
266    Segno,
267    Coda,
268    Words {
269        text: String,
270    },
271    Symbol,
272    Wedge,
273    Dynamics(Dynamic),
274    Dashes,
275    Bracket,
276    Pedal,
277    Metronome,
278    OctaveShift,
279    HarpPedals,
280    Damp,
281    DampAll,
282    Eyeglasses,
283    StringMute,
284    Scordatura,
285    Image {
286        // TODO: force uri
287        source: String
288    },
289    PrincipalVoice,
290    Percussion,
291    AccordionRegistration,
292    StaffDivide,
293    OtherDirection,
294}
295
296#[derive(Debug, Clone, PartialEq)]
297#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
298pub struct Direction {
299    pub direction_type: DirectionType,
300    pub placement: Placement,
301    pub color: Option<Color>,
302    pub font: Option<Font>,
303    pub position: Option<Position>,
304    pub staff: Option<u8>,
305    pub voice: Option<u8>,
306}
307
308#[derive(Debug, Clone, PartialEq)]
309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
310pub enum TimedMeasureItemInner {
311    Note(Note),
312    Chord(Chord),
313    Rest,
314    Forward,
315    Backward,
316    // TODO: more customization
317    Barline,
318    // TODO: implement these:
319    // TODO: <harmony>
320    // TODO: <figured-bass>
321}
322
323#[derive(Debug, Clone, PartialEq)]
324#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
325pub struct TimeModification {
326    pub actual_notes: u8,
327    pub normal_notes: u8
328}
329
330#[derive(Debug, Clone, PartialEq)]
331#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
332pub struct TimedMeasureItem {
333    item: TimedMeasureItemInner,
334    duration: Duration,
335    position: Option<Position>,
336    /// Up or down
337    stem: Option<Placement>,
338    staff: Option<u8>,
339    voice: Option<u8>,
340    beam_id: Option<u16>,
341    time_modification: Option<TimeModification>,
342    notations: Option<Notations>,
343    /// Delay of the note
344    attack: Option<f32>,
345    // TODO: lyrics
346    // TODO: notehead
347    // TODO: notehead-text
348    // TODO: grace notes
349}
350
351#[derive(Debug, Clone)]
352#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
353pub struct Measure {
354    clef: Clef,
355    time_signature: TimeSignature,
356    key: Key,
357    notes: TimedMeasureItem,
358    directions: Vec<Direction>,
359}
360
361#[cfg(feature = "musicxml")]
362mod musicxml {
363    use super::*;
364}