Skip to main content

rill_core/time/
source.rs

1//! # Clock sources for audio timing
2//!
3//! This module defines the `ClockSource` trait and related types for
4//! providing timing information to the signal graph.
5
6use super::error::TimeError;
7use super::tick::ClockTick;
8use crate::time::SystemClock;
9use std::fmt;
10
11/// A source of clock ticks for signal processing
12///
13/// Implementations can be hardware-based (ALSA, JACK) or software-based
14/// (`SystemClock`). The clock source is responsible for providing
15/// accurate timing information to the signal graph.
16///
17/// # Example
18///
19/// ```
20/// use rill_core::time::{ClockSource, SystemClock};
21///
22/// let mut clock = SystemClock::with_sample_rate(44100.0);
23/// let tick = clock.next_tick(64);
24/// ```
25pub trait ClockSource: Send + Sync + fmt::Debug {
26    /// Get the next clock tick
27    ///
28    /// # Arguments
29    /// * `block_size` - Number of samples in the next block
30    ///
31    /// # Returns
32    /// A `ClockTick` containing timing information for the next block
33    fn next_tick(&mut self, block_size: usize) -> ClockTick;
34
35    /// Get the sample rate of this clock source
36    fn sample_rate(&self) -> f32;
37
38    /// Start the clock
39    ///
40    /// This is called when the signal graph starts processing.
41    /// Default implementation does nothing.
42    fn start(&mut self) -> Result<(), TimeError> {
43        Ok(())
44    }
45
46    /// Stop the clock
47    ///
48    /// This is called when the signal graph stops processing.
49    /// Default implementation does nothing.
50    fn stop(&mut self) -> Result<(), TimeError> {
51        Ok(())
52    }
53
54    /// Check if the clock is running
55    fn is_running(&self) -> bool {
56        true
57    }
58
59    /// Get the current sample position
60    ///
61    /// Default implementation returns the position from the last tick,
62    /// but hardware clocks may provide more accurate information.
63    fn current_position(&self) -> u64 {
64        0
65    }
66}
67
68impl ClockSource for SystemClock {
69    fn next_tick(&mut self, block_size: usize) -> ClockTick {
70        self.next_tick(block_size)
71    }
72
73    fn sample_rate(&self) -> f32 {
74        self.sample_rate
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use crate::time::SystemClock;
81
82    #[test]
83    fn test_clock_source_trait() {
84        let mut clock = SystemClock::with_sample_rate(44100.0);
85
86        assert_eq!(clock.sample_rate, 44100.0);
87        //assert!(clock.is_running());
88
89        let tick = clock.next_tick(64);
90        assert_eq!(tick.sample_pos, 0);
91        assert_eq!(tick.samples_since_last, 64);
92    }
93}