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,
    )
}