Refactor asio-sys to use less global state and more RAII

The asio-sys examples have been tested and still work nicely. The CPAL
asio host has not yet been updated for these changes.
This commit is contained in:
mitchmindtree 2019-06-28 03:00:52 +10:00
parent 05f8b7dc43
commit efe683133c
4 changed files with 486 additions and 706 deletions

View File

@ -34,19 +34,20 @@ pub struct Format {
} }
fn main() { fn main() {
for name in sys::get_driver_list() { let asio = sys::Asio::new();
for name in asio.driver_names() {
println!("Driver: {:?}", name); println!("Driver: {:?}", name);
let driver = sys::Drivers::load(&name).expect("failed to load driver"); let driver = asio.load_driver(&name).expect("failed to load driver");
let channels = driver.get_channels(); let channels = driver.channels().expect("failed to retrieve channel counts");
let sample_rate = driver.get_sample_rate(); let sample_rate = driver.sample_rate().expect("failed to retrieve sample rate");
let in_fmt = Format { let in_fmt = Format {
channels: channels.ins as _, channels: channels.ins as _,
sample_rate: SampleRate(sample_rate.rate as _), sample_rate: SampleRate(sample_rate as _),
data_type: SampleFormat::F32, data_type: SampleFormat::F32,
}; };
let out_fmt = Format { let out_fmt = Format {
channels: channels.outs as _, channels: channels.outs as _,
sample_rate: SampleRate(sample_rate.rate as _), sample_rate: SampleRate(sample_rate as _),
data_type: SampleFormat::F32, data_type: SampleFormat::F32,
}; };
println!(" Input {:?}", in_fmt); println!(" Input {:?}", in_fmt);

View File

@ -1,13 +1,11 @@
extern crate asio_sys as sys; extern crate asio_sys as sys;
fn main() { fn main() {
let driver_list = sys::get_driver_list(); let asio = sys::Asio::new();
for driver in asio.driver_names() {
for driver in &driver_list {
println!("Driver: {}", driver); println!("Driver: {}", driver);
let driver = asio.load_driver(&driver).expect("failed to load drivers");
let driver = sys::Drivers::load(driver).expect("failed to load drivers"); println!(" Channels: {:?}", driver.channels().expect("failed to get channels"));
println!(" Channels: {:?}", driver.get_channels()); println!(" Sample rate: {:?}", driver.sample_rate().expect("failed to get sample rate"));
println!(" Sample rate: {:?}", driver.get_sample_rate());
} }
} }

View File

@ -1,14 +1,15 @@
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
/// Errors that might occur during `Asio::load_driver`.
#[derive(Debug)] #[derive(Debug)]
pub enum AsioDriverError { pub enum LoadDriverError {
NoResult(String), LoadDriverFailed,
BufferError(String), DriverAlreadyExists,
DriverLoadError, InitializationFailed(AsioError),
TypeError,
} }
/// General errors returned by ASIO.
#[derive(Debug)] #[derive(Debug)]
pub enum AsioError { pub enum AsioError {
NoDrivers, NoDrivers,
@ -35,25 +36,9 @@ pub enum AsioErrorWrapper {
Invalid, Invalid,
} }
impl fmt::Display for AsioDriverError { impl fmt::Display for LoadDriverError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { write!(f, "{}", self.description())
AsioDriverError::NoResult(ref e) => write!(f, "Driver {} not found", e),
AsioDriverError::BufferError(ref e) => write!(f, "Buffer Error: {}", e),
AsioDriverError::DriverLoadError => write!(f, "Couldn't load the driver"),
AsioDriverError::TypeError => write!(f, "Couldn't convert sample type"),
}
}
}
impl Error for AsioDriverError {
fn description(&self) -> &str {
match *self {
AsioDriverError::NoResult(_) => "Couln't find driver",
AsioDriverError::BufferError(_) => "Error creating the buffer",
AsioDriverError::DriverLoadError => "Error loading the driver",
AsioDriverError::TypeError => "Error getting sample type",
}
} }
} }
@ -83,6 +68,20 @@ impl fmt::Display for AsioError {
} }
} }
impl Error for LoadDriverError {
fn description(&self) -> &str {
match *self {
LoadDriverError::LoadDriverFailed => {
"ASIO `loadDriver` function returned `false` indicating failure"
}
LoadDriverError::InitializationFailed(ref err) => err.description(),
LoadDriverError::DriverAlreadyExists => {
"ASIO only supports loading one driver at a time"
}
}
}
}
impl Error for AsioError { impl Error for AsioError {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
@ -99,42 +98,27 @@ impl Error for AsioError {
} }
} }
} }
macro_rules! asio_error_helper {
($x:expr, $ae:ident{ $($v:ident),+ }, $inval:ident) => { impl From<AsioError> for LoadDriverError {
match $x { fn from(err: AsioError) -> Self {
$(_ if $x == $ae::$v as i32 => $ae::$v,)+ LoadDriverError::InitializationFailed(err)
_ => $ae::$inval,
} }
};
} }
macro_rules! asio_result { macro_rules! asio_result {
($result:expr) => { ($e:expr) => {{
match asio_error_helper!( let res = { $e };
$result, match res {
AsioErrorWrapper { r if r == AsioErrorWrapper::ASE_OK as i32 => Ok(()),
ASE_OK, r if r == AsioErrorWrapper::ASE_SUCCESS as i32 => Ok(()),
ASE_SUCCESS, r if r == AsioErrorWrapper::ASE_NotPresent as i32 => Err(AsioError::NoDrivers),
ASE_NotPresent, r if r == AsioErrorWrapper::ASE_HWMalfunction as i32 => Err(AsioError::HardwareMalfunction),
ASE_HWMalfunction, r if r == AsioErrorWrapper::ASE_InvalidParameter as i32 => Err(AsioError::InvalidInput),
ASE_InvalidParameter, r if r == AsioErrorWrapper::ASE_InvalidMode as i32 => Err(AsioError::BadMode),
ASE_InvalidMode, r if r == AsioErrorWrapper::ASE_SPNotAdvancing as i32 => Err(AsioError::HardwareStuck),
ASE_SPNotAdvancing, r if r == AsioErrorWrapper::ASE_NoClock as i32 => Err(AsioError::NoRate),
ASE_NoClock, r if r == AsioErrorWrapper::ASE_NoMemory as i32 => Err(AsioError::ASE_NoMemory),
ASE_NoMemory _ => Err(AsioError::UnknownError),
},
Invalid
) {
AsioErrorWrapper::ASE_OK => Ok(()),
AsioErrorWrapper::ASE_SUCCESS => Ok(()),
AsioErrorWrapper::ASE_NotPresent => Err(AsioError::NoDrivers),
AsioErrorWrapper::ASE_HWMalfunction => Err(AsioError::HardwareMalfunction),
AsioErrorWrapper::ASE_InvalidParameter => Err(AsioError::InvalidInput),
AsioErrorWrapper::ASE_InvalidMode => Err(AsioError::BadMode),
AsioErrorWrapper::ASE_SPNotAdvancing => Err(AsioError::HardwareStuck),
AsioErrorWrapper::ASE_NoClock => Err(AsioError::NoRate),
AsioErrorWrapper::ASE_NoMemory => Err(AsioError::ASE_NoMemory),
AsioErrorWrapper::Invalid => Err(AsioError::UnknownError),
} }
}; }};
} }

File diff suppressed because it is too large Load Diff