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
#![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; /// Creates a new music timer performance engine. /// /// # 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, ) }