use crate::config::AudioConfig;
use crate::error::IoResult;
use std::fmt::Debug;
use std::time::Duration;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde-config", derive(serde::Serialize, serde::Deserialize))]
pub enum BackendType {
Cpal,
Alsa,
PipeWire,
Jack,
Null,
}
impl BackendType {
pub fn name(&self) -> &'static str {
match self {
BackendType::Cpal => "CPAL",
BackendType::Alsa => "ALSA",
BackendType::PipeWire => "PipeWire",
BackendType::Jack => "JACK",
BackendType::Null => "Null",
}
}
pub fn is_available(&self) -> bool {
match self {
BackendType::Cpal => true,
BackendType::Alsa => cfg!(target_os = "linux"),
BackendType::PipeWire => cfg!(target_os = "linux"),
BackendType::Jack => cfg!(any(target_os = "linux", target_os = "macos")),
BackendType::Null => true,
}
}
}
pub trait AudioBackend: Debug {
fn backend_type(&self) -> BackendType;
fn config(&self) -> &AudioConfig;
fn config_mut(&mut self) -> &mut AudioConfig;
fn init(&mut self) -> IoResult<()>;
fn start(&mut self) -> IoResult<()>;
fn stop(&mut self) -> IoResult<()>;
fn read(&mut self, buffer: &mut [f32]) -> IoResult<usize>;
fn write(&mut self, buffer: &[f32]) -> IoResult<usize>;
fn xruns(&self) -> u32;
fn latency(&self) -> Duration;
fn list_input_devices(&self) -> Vec<String>;
fn list_output_devices(&self) -> Vec<String>;
}
impl<T: AudioBackend + ?Sized> AudioBackend for Box<T> {
fn backend_type(&self) -> BackendType {
(**self).backend_type()
}
fn config(&self) -> &AudioConfig {
(**self).config()
}
fn config_mut(&mut self) -> &mut AudioConfig {
(**self).config_mut()
}
fn init(&mut self) -> IoResult<()> {
(**self).init()
}
fn start(&mut self) -> IoResult<()> {
(**self).start()
}
fn stop(&mut self) -> IoResult<()> {
(**self).stop()
}
fn read(&mut self, buffer: &mut [f32]) -> IoResult<usize> {
(**self).read(buffer)
}
fn write(&mut self, buffer: &[f32]) -> IoResult<usize> {
(**self).write(buffer)
}
fn xruns(&self) -> u32 {
(**self).xruns()
}
fn latency(&self) -> Duration {
(**self).latency()
}
fn list_input_devices(&self) -> Vec<String> {
(**self).list_input_devices()
}
fn list_output_devices(&self) -> Vec<String> {
(**self).list_output_devices()
}
}
#[derive(Debug, Clone)]
pub struct DeviceInfo {
pub name: String,
pub backend: BackendType,
pub is_default: bool,
pub max_input_channels: u32,
pub max_output_channels: u32,
pub supported_sample_rates: Vec<u32>,
pub supported_buffer_sizes: Vec<u32>,
}