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
128
#![allow(dead_code)]
use super::{music_time::MusicTime, time_signature::TimeSignature};
use std::time::Duration;
#[derive(Debug)]
pub struct MusicTimeCounter {
current_time: MusicTime,
time_signature: TimeSignature,
}
impl MusicTimeCounter {
pub fn new(time_signature: TimeSignature) -> Self {
MusicTimeCounter {
current_time: MusicTime::new(1, 1, 1),
time_signature,
}
}
pub fn current_time(&self) -> &MusicTime {
&self.current_time
}
pub fn advance_beat(&mut self) {
self.current_time.advance_beat(&self.time_signature);
}
pub fn advance_beat_interval(&mut self) {
self.current_time
.advance_beat_interval(&self.time_signature);
}
pub fn beat_target_frames(&self, bpm: f32) -> Duration {
let seconds_per_beat = 60.0 / bpm;
let beat_pulse_speed = seconds_per_beat * 1000000000.0;
Duration::from_nanos(beat_pulse_speed as u64)
}
pub fn beat_interval_target_frames(&self, bpm: f32) -> Duration {
const INTERVAL_RESOLUTION: f32 = 16.0 / 2.0;
let seconds_per_beat_interval = (60.0 / bpm) / INTERVAL_RESOLUTION;
let beat_interval_pulse_speed = seconds_per_beat_interval * 1000000000.0;
Duration::from_nanos(beat_interval_pulse_speed as u64)
}
pub fn set_current_time(&mut self, current_time: MusicTime) -> &mut Self {
self.current_time = current_time;
self
}
}
impl Default for MusicTimeCounter {
fn default() -> Self {
MusicTimeCounter::new(TimeSignature::default())
}
}
mod tests {
#[test]
fn test_beat_target_frames() {
use crate::{music_time_counter::MusicTimeCounter, time_signature::TimeSignature};
use std::time::Duration;
let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
let duration = timer.beat_target_frames(80.0);
let expected = Duration::from_millis(750);
assert_eq!(duration, expected);
let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
let duration = timer.beat_target_frames(60.0);
let expected = Duration::from_secs(1);
assert_eq!(duration, expected);
}
#[test]
fn test_beat_interval_target_frames() {
use crate::{music_time_counter::MusicTimeCounter, time_signature::TimeSignature};
use std::time::Duration;
let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
let duration = timer.beat_interval_target_frames(60.0);
let expected = Duration::from_millis(125);
assert_eq!(duration, expected);
}
#[test]
fn test_set_current_time() {
use crate::{music_time::MusicTime, music_time_counter::MusicTimeCounter};
let mut timer = MusicTimeCounter::default();
assert_eq!(timer.current_time(), &MusicTime::new(1, 1, 1));
timer.advance_beat();
assert_eq!(timer.current_time(), &MusicTime::new(1, 2, 1));
timer.set_current_time(MusicTime::new(3, 2, 1));
assert_eq!(timer.current_time(), &MusicTime::new(3, 2, 1));
}
}