music_timer/
music_time_counter.rs1#![allow(dead_code)]
2
3use super::{music_time::MusicTime, time_signature::TimeSignature};
8use std::time::Duration;
9
10#[derive(Debug)]
11pub struct MusicTimeCounter {
13 current_time: MusicTime,
14 time_signature: TimeSignature,
15}
16
17impl MusicTimeCounter {
18 pub fn new(time_signature: TimeSignature) -> Self {
29 MusicTimeCounter {
30 current_time: MusicTime::new(1, 1, 1),
31 time_signature,
32 }
33 }
34
35 pub fn current_time(&self) -> &MusicTime {
37 &self.current_time
38 }
39
40 pub fn advance_beat(&mut self) {
42 self.current_time.advance_beat(&self.time_signature);
43 }
44
45 pub fn advance_beat_interval(&mut self) {
47 self.current_time
48 .advance_beat_interval(&self.time_signature);
49 }
50
51 pub fn beat_target_frames(&self, bpm: f32) -> Duration {
56 let seconds_per_beat = 60.0 / bpm;
57 let beat_pulse_speed = seconds_per_beat * 1000000000.0;
58 Duration::from_nanos(beat_pulse_speed as u64)
59 }
60
61 pub fn beat_interval_target_frames(&self, bpm: f32) -> Duration {
66 const INTERVAL_RESOLUTION: f32 = 16.0 / 2.0;
67 let seconds_per_beat_interval = (60.0 / bpm) / INTERVAL_RESOLUTION;
68 let beat_interval_pulse_speed = seconds_per_beat_interval * 1000000000.0;
69 Duration::from_nanos(beat_interval_pulse_speed as u64)
70 }
71
72 pub fn set_current_time(&mut self, current_time: MusicTime) -> &mut Self {
77 self.current_time = current_time;
78 self
79 }
80}
81
82impl Default for MusicTimeCounter {
83 fn default() -> Self {
85 MusicTimeCounter::new(TimeSignature::default())
86 }
87}
88
89mod tests {
90 #[test]
91 fn test_beat_target_frames() {
92 use crate::{music_time_counter::MusicTimeCounter, time_signature::TimeSignature};
93 use std::time::Duration;
94
95 let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
96 let duration = timer.beat_target_frames(80.0);
97 let expected = Duration::from_millis(750);
98 assert_eq!(duration, expected);
99
100 let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
101 let duration = timer.beat_target_frames(60.0);
102 let expected = Duration::from_secs(1);
103 assert_eq!(duration, expected);
104 }
105
106 #[test]
107 fn test_beat_interval_target_frames() {
108 use crate::{music_time_counter::MusicTimeCounter, time_signature::TimeSignature};
109 use std::time::Duration;
110
111 let timer = MusicTimeCounter::new(TimeSignature::new(4, 4));
112 let duration = timer.beat_interval_target_frames(60.0);
113 let expected = Duration::from_millis(125);
114 assert_eq!(duration, expected);
115 }
116
117 #[test]
118 fn test_set_current_time() {
119 use crate::{music_time::MusicTime, music_time_counter::MusicTimeCounter};
120
121 let mut timer = MusicTimeCounter::default();
122 assert_eq!(timer.current_time(), &MusicTime::new(1, 1, 1));
123 timer.advance_beat();
124 assert_eq!(timer.current_time(), &MusicTime::new(1, 2, 1));
125 timer.set_current_time(MusicTime::new(3, 2, 1));
126 assert_eq!(timer.current_time(), &MusicTime::new(3, 2, 1));
127 }
128}