audio_master/backend/
backend.rs1use std::{
2 hash::DefaultHasher,
3 sync::{Arc, RwLock},
4};
5
6use cpal::{PauseStreamError, PlayStreamError, SupportedStreamConfigRange};
7
8use crate::{
10 audio_buffer::{AudioBuffer, AudioChannelLayout},
11 float_type::FloatType,
12};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum RawAudioStreamError {
16 DeviceNotAvailable,
17 Internal(String),
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum RawAudioStreamState {
22 Ok,
23
24 Err,
27
28 Silence,
30
31 Other(String),
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum AudioHostError {
38 NoDevice,
39 NoConfig,
40 UnknownSampleFormat,
41 UnknownChannelCount,
42 UnknownStreamConfig,
43 DeviceNotAvailable,
44 InvalidArgument,
45 StreamIdOverflow,
46 UnknownError,
47 Internal(String),
48}
49
50#[derive(Debug, Clone)]
51pub struct Device {
52 pub name: String,
53 pub sample_rate: u32,
54 pub channels: AudioChannelLayout,
55 pub id: usize,
56}
57
58pub trait AudioHostImpl {
59 fn new() -> AudioHost;
60
61 fn default_output_device(&self) -> Option<Device>;
63
64 fn get_device_by_id(&self, id: usize) -> Result<Device, AudioHostError>;
66
67 fn devices(&self) -> Vec<Device>;
69
70 fn create_stream_default(
73 &mut self,
74 feeder: Box<dyn StreamFeederTrait<f32>>,
75 buffer_size: usize,
76 ) -> Result<RawAudioStream<f32>, AudioHostError>;
77
78 fn create_stream(
81 &mut self,
82 feeder: Box<dyn StreamFeederTrait<f32>>,
83 buffer_size: usize,
84 device_id: usize,
85 ) -> Result<RawAudioStream<f32>, AudioHostError>;
86}
87
88pub trait RawAudioStreamImpl: Sized {
89 fn close(&mut self);
92
93 fn play(&mut self) -> Result<(), RawAudioStreamError>;
96
97 fn pause(&mut self) -> Result<(), RawAudioStreamError>;
100
101 fn is_running(&self) -> bool;
103
104 fn get_sample_rate(&self) -> u32;
106
107 fn get_timestamp(&self) -> usize;
109}
110
111pub trait StreamFeederTrait<T: FloatType + Send + Sync> {
112 fn process(&mut self, input: &mut AudioBuffer<T>) -> RawAudioStreamState;
114
115 fn emit_stream_error(&mut self, error: &str);
117
118 fn emit_stream_close(&mut self);
120
121 fn emit_stream_play(&mut self);
123
124 fn emit_stream_pause(&mut self);
126}
127
128#[derive(Clone)]
129pub struct AudioHost {
130 pub(super) core: Arc<RwLock<cpal::Host>>,
131}
132
133pub struct RawAudioStreamInner<T: FloatType> {
134 pub(super) core: Option<cpal::Stream>,
135 pub(super) is_running: bool,
136 pub(super) buffer: AudioBuffer<T>,
137 pub(super) buffer_offset: usize,
138 pub(super) sample_rate: u32,
139
140 pub(super) sample_rate_1000: f64,
143 pub(super) feeder: Box<dyn StreamFeederTrait<T>>,
144
145 pub(super) timestamp: usize,
147}
148
149#[derive(Clone)]
150pub struct RawAudioStream<T: FloatType> {
151 pub(super) inner: Arc<RwLock<RawAudioStreamInner<T>>>,
152}
153
154pub trait PrivateImpl: Sized {
155 fn channels_to_layout(channels: usize) -> Option<AudioChannelLayout>;
157
158 fn conv_cpal_play_stream_error(error: PlayStreamError) -> RawAudioStreamError;
160
161 fn conv_cpal_pause_stream_error(error: PauseStreamError) -> RawAudioStreamError;
163
164 fn cpal_device_to_device(device: cpal::Device) -> Option<Device>;
166
167 fn generate_id_from_cpal_device(device: &cpal::Device) -> i64;
170 fn hash_config_range(config: &SupportedStreamConfigRange, hasher: &mut DefaultHasher);
171}
172
173pub trait AudioHostPrivateImpl: Sized {
174 fn get_cpal_device_by_id(&self, id: usize) -> Result<cpal::Device, AudioHostError>;
176
177 fn create_stream_with_device<T: FloatType + Send + Sync + 'static>(
179 &mut self,
180 device: &cpal::Device,
181 buffer_size: usize,
182 feeder: Box<dyn StreamFeederTrait<T>>,
183 ) -> Result<Arc<RwLock<RawAudioStreamInner<T>>>, AudioHostError>;
184}
185
186pub trait RawAudioStreamPrivateImpl<T: FloatType + Send + Sync>: Sized {
187 fn user_cpal_process(&mut self, buffer: &mut [f32], channels: AudioChannelLayout);
189}
190
191pub struct Private {}