Skip to main content

rill_io/
lib.rs

1//! Audio I/O backends for Rill
2//!
3//! This crate provides a unified interface to various audio backends
4//! using dynamic ring buffers for cross-thread I/O.
5
6#![warn(missing_docs)]
7
8mod backend;
9mod buffer;
10mod config;
11mod engine;
12mod error;
13
14pub mod backends;
15pub mod processor;
16
17pub use backend::{AudioBackend, BackendType, DeviceInfo};
18pub use config::AudioConfig;
19pub use engine::{AudioEngine, AudioProcessor, EngineState};
20pub use error::{IoError, IoResult};
21
22pub use backends::NullBackend;
23
24#[cfg(feature = "cpal")]
25pub use backends::CpalBackend;
26
27#[cfg(feature = "alsa")]
28pub use backends::AlsaBackend;
29
30#[cfg(feature = "pipewire")]
31pub use backends::PipewireBackend;
32
33#[cfg(feature = "jack")]
34pub use backends::JackBackend;
35
36// Processor re-exports
37pub use processor::{GainProcessor, MonoMixerProcessor, PassThroughProcessor, SilenceProcessor};
38
39#[cfg(feature = "graph")]
40pub use processor::GraphProcessor;
41
42#[cfg(feature = "examples")]
43pub use processor::SineProcessor;
44
45#[cfg(feature = "examples")]
46pub use processor::CaptureProcessor;
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use crate::config::AudioConfig;
52    use crate::processor::{
53        GainProcessor, MonoMixerProcessor, PassThroughProcessor, SilenceProcessor,
54    };
55
56    #[test]
57    fn test_config_default() {
58        let config = AudioConfig::default();
59        assert_eq!(config.sample_rate, 48000);
60        assert_eq!(config.buffer_size, 256);
61        assert_eq!(config.input_channels, 2);
62        assert_eq!(config.output_channels, 2);
63    }
64
65    #[test]
66    fn test_config_with_methods() {
67        let config = AudioConfig::new()
68            .with_sample_rate(44100)
69            .with_buffer_size(512)
70            .with_channels(1);
71        assert_eq!(config.sample_rate, 44100);
72        assert_eq!(config.buffer_size, 512);
73    }
74
75    #[test]
76    fn test_latency_calculation() {
77        let config = AudioConfig::new()
78            .with_sample_rate(48000)
79            .with_buffer_size(256);
80        let latency_sec = config.latency_seconds();
81        let latency_ms = config.latency_ms();
82        assert!((latency_sec - 256.0 / 48000.0).abs() < 1e-10);
83        assert!((latency_ms - 256.0 * 1000.0 / 48000.0).abs() < 1e-10);
84    }
85
86    #[test]
87    fn test_gain_processor() {
88        let mut proc = GainProcessor::new(2.0);
89        let input = vec![1.0, 2.0, 3.0];
90        let mut output = vec![0.0; 3];
91        proc.process(&input, &mut output);
92        assert_eq!(output, vec![2.0, 4.0, 6.0]);
93    }
94
95    #[test]
96    fn test_passthrough_processor() {
97        let mut proc = PassThroughProcessor;
98        let input = vec![1.0, -1.0, 0.5];
99        let mut output = vec![0.0; 3];
100        proc.process(&input, &mut output);
101        assert_eq!(output, input);
102    }
103
104    #[test]
105    fn test_silence_processor() {
106        let mut proc = SilenceProcessor;
107        let input = vec![1.0, 2.0, 3.0];
108        let mut output = vec![1.0; 3];
109        proc.process(&input, &mut output);
110        assert_eq!(output, vec![0.0; 3]);
111    }
112
113    #[test]
114    fn test_mono_mixer_processor() {
115        let mut proc = MonoMixerProcessor;
116        let input = vec![0.8, 0.2, 0.5, 0.5, 1.0, 0.0];
117        let mut output = vec![0.0; 3];
118        proc.process(&input, &mut output);
119        assert_eq!(output, vec![0.5, 0.5, 0.5]);
120    }
121}