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}