1use crate::duration::PrimitiveDuration;
4
5#[derive(Debug, Clone, Copy)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[repr(transparent)]
8pub struct Tempo {
9 pub bpm: f64,
10}
11
12impl Tempo {
13 #[inline]
14 pub const fn new(bpm: f64) -> Self {
15 Self { bpm }
16 }
17
18 #[inline]
19 pub const fn value(&self) -> f64 {
20 self.bpm
21 }
22}
23
24#[derive(Debug, Clone, Copy)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26#[repr(transparent)]
27pub struct Measure(pub usize);
28
29impl Measure {
30 #[inline]
31 pub const fn new(measure: usize) -> Self {
32 Self(measure)
33 }
34
35 #[inline]
36 pub const fn value(&self) -> usize {
37 self.0
38 }
39}
40
41#[derive(Debug, Clone, Copy)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43#[repr(transparent)]
44pub struct Beat(pub usize);
45
46impl Beat {
47 #[inline]
48 pub const fn new(beat: usize) -> Self {
49 Self(beat)
50 }
51
52 #[inline]
53 pub const fn value(&self) -> usize {
54 self.0
55 }
56}
57
58#[derive(Debug, Clone, Copy)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60pub struct BeatFraction {
61 pub numerator: usize,
62 pub denominator: PrimitiveDuration,
63}
64
65impl BeatFraction {
66 #[inline]
67 pub const fn new(numerator: usize, denominator: PrimitiveDuration) -> Self {
68 Self {
69 numerator,
70 denominator,
71 }
72 }
73
74 #[inline]
75 pub fn simplify(&self) -> Self {
76 let mut numerator = self.numerator;
77 let mut denominator = self.denominator;
78 while numerator % 2 == 0 && denominator != PrimitiveDuration::WHOLE {
79 numerator /= 2;
80 denominator = denominator.double();
81 }
82 Self {
83 numerator,
84 denominator,
85 }
86 }
87}