1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use super::calc;
use super::{
Bars,
Beats,
Bpm,
Division,
DivType,
Ms,
NumDiv,
Ppqn,
SampleHz,
Samples,
Ticks,
TimeSig,
ms_from_measure,
samples_from_measure,
ticks_from_measure,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Measure(pub NumDiv, pub Division, pub DivType);
impl Measure {
#[inline]
pub fn num(&self) -> NumDiv {
let Measure(num, _, _) = *self;
num
}
#[inline]
pub fn div(&self) -> Division {
let Measure(_, div, _) = *self;
div
}
#[inline]
pub fn div_type(&self) -> DivType {
let Measure(_, _, div_type) = *self;
div_type
}
#[inline]
pub fn beats(&self, ts: TimeSig) -> f64 {
let Measure(num, div, div_type) = *self;
match div_type {
DivType::Whole => div.beats(ts) * num as f64,
DivType::TwoThirds => div.beats(ts) * num as f64 * (2.0 / 3.0),
}
}
#[inline]
pub fn bars(&self, ts: TimeSig) -> f64 {
self.beats(ts) / Measure(1, Division::Bar, DivType::Whole).beats(ts)
}
#[inline]
pub fn ms(&self, bpm: Bpm, ts: TimeSig) -> calc::Ms {
let Measure(num, div, div_type) = *self;
ms_from_measure(num, div, div_type, bpm, ts)
}
#[inline]
pub fn to_ms(&self, bpm: Bpm, ts: TimeSig) -> Ms {
Ms(self.ms(bpm, ts))
}
#[inline]
pub fn samples(&self, bpm: Bpm, ts: TimeSig, sample_hz: SampleHz) -> calc::Samples {
let Measure(num, div, div_type) = *self;
samples_from_measure(num, div, div_type, bpm, ts, sample_hz)
}
#[inline]
pub fn to_samples(&self, bpm: Bpm, ts: TimeSig, sample_hz: SampleHz) -> Samples {
Samples(self.samples(bpm, ts, sample_hz))
}
#[inline]
pub fn ticks(&self, ts: TimeSig, ppqn: Ppqn) -> calc::Ticks {
let Measure(num, div, div_type) = *self;
ticks_from_measure(num, div, div_type, ts, ppqn)
}
#[inline]
pub fn to_ticks(&self, ts: TimeSig, ppqn: Ppqn) -> Ticks {
Ticks(self.ticks(ts, ppqn))
}
}
impl From<Bars> for Measure {
fn from(bars: Bars) -> Self {
Measure(bars.bars(), Division::Bar, DivType::Whole)
}
}
impl From<Beats> for Measure {
fn from(beats: Beats) -> Self {
Measure(beats.beats(), Division::Beat, DivType::Whole)
}
}
impl From<Division> for Measure {
fn from(div: Division) -> Self {
Measure(1, div, DivType::Whole)
}
}