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
#![allow(dead_code)] #![crate_name = "music_timer"] /// /// _Music Timer_ is a crate with music time and counting utilities featuring a callback performance engine to help with triggering events in music time. Written in Rust. /// /// # Example /// ``` /// use music_timer::{ /// music_time::MusicTime, /// music_timer_engine::MusicTimerState, /// }; /// /// struct PerformanceState { /// is_playing: bool, /// performance_end: MusicTime, /// events: Vec<MusicTime>, /// event_head: usize, /// } /// /// impl MusicTimerState for PerformanceState { /// fn on_beat_interval(&mut self, current_time: &MusicTime) { /// let event_triggered = /// self.event_head < self.events.len() && *current_time == self.events[self.event_head]; /// /// // Advance the event head /// if event_triggered { /// self.event_head += 1; /// } /// /// // Print out esoteric data /// println!( /// "{:02}.{}.{} = {}", /// current_time.get_bar(), /// current_time.get_beat(), /// current_time.get_beat_interval(), /// event_triggered /// ); /// /// // Check to end the performance /// self.is_playing = *current_time < self.performance_end; /// } /// fn on_beat(&mut self, _current_time: &MusicTime) { /// // Do something on the beat /// } /// fn on_bar(&mut self, _current_time: &MusicTime) { /// // Do something on the bar /// } /// } /// /// fn main() { /// use std::thread; /// /// // Create the performer_state with bunch of events /// let mut performer_state = PerformanceState { /// is_playing: true, /// performance_end: MusicTime::new(4, 3, 8), /// events: vec![ /// MusicTime::new(1, 1, 1), /// MusicTime::new(2, 2, 5), /// MusicTime::new(4, 3, 8), /// ], /// event_head: 0, /// }; /// /// // Run our main loop /// let mut performer = music_timer::create_performance_engine(3, 4, 155.0); /// /// // We can set the delay to be half the trigger target. This will give /// // us a reasonable cycle speed with enough buffer to keep an accurate time. /// // This of course is not needed if the application is managing thread sleeping. /// // The shorter the sleep duration of the thread, the more accurate the /// // time triggering will be. In most cases setting the sleep to 60fps is recommended for /// // < 180bpm @ 4/4. /// let sleep_duration = performer.get_beat_interval_duration() / 2; /// println!("SLEEP_DURATION: {:?}", sleep_duration); /// /// while performer_state.is_playing { /// // Pass in our performance state to trigger our on event callback functions /// performer.pulse(&mut performer_state); /// thread::sleep(sleep_duration); /// } /// } /// ``` /// /// /// pub mod music_time; pub mod music_time_counter; pub mod music_timer_engine; pub mod time_signature; /// Returns a person with the name given them /// /// # Arguments /// /// * `numerator` - The upper part of a time signature. Must be none 0. /// * `denominator` - The lower part of a time signature. Only 2, 4, 8, 16, 32 are supported. /// * `bpm` - The beats per minute. /// /// # Example /// /// ``` /// let mut performer = music_timer::create_performance_engine(3, 4, 155.0); /// ``` pub fn create_performance_engine( numerator: u8, denominator: u8, bpm: f32, ) -> music_timer_engine::MusicTimerEngine { music_timer_engine::MusicTimerEngine::new( time_signature::TimeSignature::new(numerator, denominator), bpm, ) }