use music_timer::{music_time::MusicTime, music_timer_engine::MusicTimerState};
use std::time::{Duration, SystemTime};
struct PerformanceState {
start_time: SystemTime,
previous_time: Duration,
total_time: Duration,
target_sleep_duration: Duration,
}
impl PerformanceState {
fn new(target_sleep_duration: Duration) -> Self {
PerformanceState {
start_time: SystemTime::now(),
previous_time: Duration::default(),
total_time: Duration::default(),
target_sleep_duration,
}
}
}
impl MusicTimerState for PerformanceState {
fn on_beat_interval(&mut self, now_time: &MusicTime) {
self.previous_time = self.total_time;
self.total_time = SystemTime::now()
.duration_since(self.start_time)
.expect("Time flow reversed");
let time_delta = self.total_time - self.previous_time;
println!(
"|{}.{}.{}| {:?} -> {:?} <> {:?} ",
now_time.get_bar(),
now_time.get_beat(),
now_time.get_beat_interval(),
self.total_time,
time_delta,
self.target_sleep_duration
);
}
fn on_beat(&mut self, _now_time: &MusicTime) {}
fn on_bar(&mut self, _now_time: &MusicTime) {}
}
#[test]
fn test_drift_60bpm() {
use std::thread;
let mut performer = music_timer::create_performance_engine(4, 4, 60.0);
let mut performer_state = PerformanceState::new(performer.get_beat_interval_duration());
let end_time = MusicTime::new(3, 1, 1);
while performer.get_current_time() <= &end_time {
performer.pulse(&mut performer_state);
thread::sleep(Duration::from_millis(1000 / 60));
}
let calculated_play_back_duration = performer.get_beat_interval_duration() * 8 * 4 * 2;
println!("calculated_play_back_duration: {:?}", calculated_play_back_duration);
let time_error_bound = Duration::from_millis(50);
let lower_bound = calculated_play_back_duration - time_error_bound;
let upper_bound = calculated_play_back_duration + time_error_bound;
assert!(
performer_state.total_time > lower_bound,
"Time is too slow"
);
assert!(performer_state.total_time < upper_bound, "Time was too fast");
}
#[test]
fn test_drift_140bpm() {
use std::thread;
let mut performer = music_timer::create_performance_engine(3, 4, 140.0);
let mut performer_state = PerformanceState::new(performer.get_beat_interval_duration());
let end_time = MusicTime::new(3, 1, 1);
while performer.get_current_time() <= &end_time {
performer.pulse(&mut performer_state);
thread::sleep(Duration::from_millis(1000 / 60));
}
let calculated_play_back_duration = performer.get_beat_interval_duration() * 8 * 3 * 2;
println!("calculated_play_back_duration: {:?}", calculated_play_back_duration);
let time_error_bound = Duration::from_millis(50);
let lower_bound = calculated_play_back_duration - time_error_bound;
let upper_bound = calculated_play_back_duration + time_error_bound;
assert!(
performer_state.total_time > lower_bound,
"Time is too slow"
);
assert!(performer_state.total_time < upper_bound, "Time was too fast");
}