event_performance/
event_performance.rs

1use music_timer::{music_time::MusicTime, music_timer_engine::MusicTimerState};
2
3struct PerformanceState {
4    is_playing: bool,
5    performance_end: MusicTime,
6    events: Vec<MusicTime>,
7    event_head: usize,
8}
9
10impl MusicTimerState for PerformanceState {
11    fn on_beat_interval(&mut self, current_time: &MusicTime) {
12        let event_triggered =
13            self.event_head < self.events.len() && *current_time == self.events[self.event_head];
14
15        // Advance the event head
16        if event_triggered {
17            self.event_head += 1;
18        }
19
20        // Print out esoteric data
21        println!(
22            "{:02}.{}.{} = {}",
23            current_time.get_bar(),
24            current_time.get_beat(),
25            current_time.get_beat_interval(),
26            event_triggered
27        );
28
29        // Check to end the performance
30        self.is_playing = *current_time < self.performance_end;
31    }
32    fn on_beat(&mut self, _current_time: &MusicTime) {
33        // Do something on the beat
34    }
35    fn on_bar(&mut self, _current_time: &MusicTime) {
36        //Do something on the bar
37    }
38}
39fn main() {
40    use std::thread;
41
42    // Create the performer_state with bunch of events
43    let mut performer_state = PerformanceState {
44        is_playing: true,
45        performance_end: MusicTime::new(4, 3, 8),
46        events: vec![
47            MusicTime::new(1, 1, 1),
48            MusicTime::new(2, 2, 5),
49            MusicTime::new(4, 3, 8),
50        ],
51        event_head: 0,
52    };
53
54    // Run our main loop
55    let mut performer = music_timer::create_performance_engine(3, 4, 155.0);
56
57    // We can set the delay to be half the trigger target. This will give
58    // us a resonable cycle speed with enough buffer to keep an accurate time.
59    // This of course is not needed if the application is managing thread sleeping.
60    // The shorter the sleep duration of the thread, the more accurate the
61    // time triggering will be. In most cases setting the sleep to 60fps is recommended for
62    // < 180bpm @ 4/4.
63    let sleep_duration = performer.get_beat_interval_duration() / 2;
64    println!("SLEEP_DURATION: {:?}", sleep_duration);
65
66    while performer_state.is_playing {
67        // Pass in our performance state to trigger our on event callback functions
68        performer.pulse(&mut performer_state);
69        thread::sleep(sleep_duration);
70    }
71}