From c24fa6202833014a87715ab0346af30b8bc0d2b9 Mon Sep 17 00:00:00 2001 From: Tom Gowan Date: Tue, 23 Oct 2018 20:13:29 +1100 Subject: [PATCH] error handling --- asio-sys/src/errors.rs | 71 ++++++++++++++++--------- asio-sys/src/lib.rs | 114 +++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 74 deletions(-) diff --git a/asio-sys/src/errors.rs b/asio-sys/src/errors.rs index 12096d9..0c92d02 100644 --- a/asio-sys/src/errors.rs +++ b/asio-sys/src/errors.rs @@ -2,7 +2,7 @@ use std::error::Error; use std::fmt; #[derive(Debug)] -pub enum AsioError { +pub enum AsioDriverError { NoResult(String), BufferError(String), DriverLoadError, @@ -10,7 +10,19 @@ pub enum AsioError { } #[derive(Debug)] -enum AsioErrorWrapper { +pub enum AsioError { + NoDrivers, + HardwareMalfunction, + InvalidInput, + BadMode, + HardwareStuck, + NoRate, + ASE_NoMemory, + UnknownError, +} + +#[derive(Debug)] +pub enum AsioErrorWrapper { ASE_OK = 0, // This value will be returned whenever the call succeeded ASE_SUCCESS = 0x3f4847a0, // unique success return value for ASIOFuture calls ASE_NotPresent = -1000, // hardware input or output is not present or available @@ -23,13 +35,31 @@ enum AsioErrorWrapper { Invalid, } +impl fmt::Display for AsioDriverError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + 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", + } + } +} + impl fmt::Display for AsioError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - ASIOError::NoResult(ref e) => write!(f, "Driver {} not found", e), - ASIOError::BufferError(ref e) => write!(f, "Buffer Error: {}", e), - ASIOError::DriverLoadError => write!(f, "Couldn't load the driver"), - ASIOError::TypeError => write!(f, "Couldn't convert sample type"), AsioError::NoDrivers => { write!(f, "hardware input or output is not present or available") }, @@ -53,13 +83,9 @@ impl fmt::Display for AsioError { } } -impl Error for ASIOError { +impl Error for AsioError { fn description(&self) -> &str { match *self { - ASIOError::NoResult(_) => "Couln't find driver", - ASIOError::BufferError(_) => "Error creating the buffer", - ASIOError::DriverLoadError => "Error loading the driver", - ASIOError::TypeError => "Error getting sample type", AsioError::NoDrivers => "hardware input or output is not present or available", AsioError::HardwareMalfunction => { "hardware is malfunctioning (can be returned by any ASIO function)" @@ -73,7 +99,6 @@ impl Error for ASIOError { } } } - macro_rules! asio_error_helper { ($x:expr, $ae:ident{ $($v:ident),+ }, $inval:ident) => { match $x { @@ -85,7 +110,7 @@ macro_rules! asio_error_helper { macro_rules! asio_result { ($result:expr) => { - match asio_error!( + match asio_error_helper!( $result, AsioErrorWrapper { ASE_OK, @@ -100,16 +125,16 @@ macro_rules! asio_result { }, Invalid ) { - ASE_OK => Ok(()), - ASE_SUCCESS => Ok(()), - ASE_NotPresent => Err(AsioError::NoDrivers), - ASE_HWMalfunction => Err(AsioError::HardwareMalfunction), - ASE_InvalidParameter => Err(AsioError::InvalidInput), - ASE_InvalidMode => Err(AsioError::BadMode), - ASE_SPNotAdvancing => Err(AsioError::HardwareStuck), - ASE_NoClock => Err(AsioError::NoRate), - ASE_NoMemory => Err(AsioError::ASE_NoMemory), - Invalid => Err(AsioError::UnknownError), + 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), } }; } diff --git a/asio-sys/src/lib.rs b/asio-sys/src/lib.rs index 07c378e..4016d39 100644 --- a/asio-sys/src/lib.rs +++ b/asio-sys/src/lib.rs @@ -8,9 +8,10 @@ extern crate num; extern crate num_derive; mod asio_import; +#[macro_use] pub mod errors; -use errors::ASIOError; +use errors::{AsioError, AsioDriverError, AsioErrorWrapper}; use std::ffi::CStr; use std::ffi::CString; use std::mem; @@ -150,7 +151,7 @@ extern "C" fn buffer_switch_time_info( } impl Drivers { - pub fn load(driver_name: &str) -> Result { + pub fn load(driver_name: &str) -> Result { let mut drivers = ASIO_DRIVERS.lock().unwrap(); match *drivers { Some(_) => { @@ -168,10 +169,10 @@ impl Drivers { unsafe { let mut asio_drivers = ai::AsioDrivers::new(); let load_result = asio_drivers.loadDriver(raw); - asio_init(&mut driver_info)?; + let init_result = asio_init(&mut driver_info); // Take back ownership my_driver_name = CString::from_raw(raw); - if load_result { + if load_result && init_result.is_ok() { println!("Creating drivers"); *drivers = Some(DriverWrapper { drivers: asio_drivers, @@ -179,7 +180,7 @@ impl Drivers { STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst); Ok(Drivers {}) } else { - Err(ASIOError::DriverLoadError) + Err(AsioDriverError::DriverLoadError) } } }, @@ -200,7 +201,7 @@ impl Drivers { let mut ins: c_long = 0; let mut outs: c_long = 0; unsafe { - asio_get_channels(&mut ins, &mut outs)?; + asio_get_channels(&mut ins, &mut outs).expect("failed to get channels"); channel = Channel { ins: ins as i64, outs: outs as i64, @@ -217,16 +218,14 @@ impl Drivers { let mut rate: c_double = 0.0f64; unsafe { - asio_get_sample_rate(&mut rate)?; + asio_get_sample_rate(&mut rate).expect("failed to get sample rate"); sample_rate = SampleRate { rate: rate as u32 }; } sample_rate } - pub fn get_data_type(&self) -> Result { - let data_type: Result; - + pub fn get_data_type(&self) -> Result { // Initialize memory for calls let mut channel_info = ai::ASIOChannelInfo { channel: 0, @@ -237,15 +236,20 @@ impl Drivers { name: [0 as c_char; 32], }; unsafe { - asio_get_channel_info(&mut channel_info)?; - data_type = num::FromPrimitive::from_i32(channel_info.type_) - .map_or(Err(ASIOError::TypeError), |t| Ok(t)); + match asio_get_channel_info(&mut channel_info) { + Ok(_) => { + num::FromPrimitive::from_i32(channel_info.type_) + .map_or(Err(AsioDriverError::TypeError), |t| Ok(t)) + }, + Err(e) => { + println!("Error getting data type {}", e); + Err(AsioDriverError::DriverLoadError) + }, + } } - - data_type } - pub fn prepare_input_stream(&self, num_channels: usize) -> Result { + pub fn prepare_input_stream(&self, num_channels: usize) -> Result { let mut buffer_infos = vec![ AsioBufferInfo { is_input: 1, @@ -267,7 +271,7 @@ impl Drivers { let mut pref_b_size: c_long = 0; let mut grans: c_long = 0; - let mut result = Err(ASIOError::NoResult("not implimented".to_owned())); + let mut result = Err(AsioDriverError::NoResult("not implimented".to_owned())); unsafe { asio_get_buffer_size( @@ -275,7 +279,7 @@ impl Drivers { &mut max_b_size, &mut pref_b_size, &mut grans, - )?; + ).expect("Failed getting buffers"); result = if pref_b_size > 0 { let mut buffer_info_convert: Vec = buffer_infos .into_iter() @@ -289,7 +293,7 @@ impl Drivers { pref_b_size, &mut callbacks_convert, ); - if buffer_result == 0 { + if buffer_result.is_ok() { let mut buffer_infos: Vec = buffer_info_convert .into_iter() .map(|bi| mem::transmute::(bi)) @@ -305,14 +309,14 @@ impl Drivers { buffer_size: pref_b_size, }); } - Err(ASIOError::BufferError(format!( + Err(AsioDriverError::BufferError(format!( "failed to create buffers, error \ - code: {}", + code: {:?}", buffer_result ))) } else { - Err(ASIOError::BufferError( + Err(AsioDriverError::BufferError( "Failed to get buffer size".to_owned(), )) }; @@ -321,7 +325,7 @@ impl Drivers { } /// Creates the output stream - pub fn prepare_output_stream(&self, num_channels: usize) -> Result { + pub fn prepare_output_stream(&self, num_channels: usize) -> Result { // Initialize data for FFI let mut buffer_infos = vec![ AsioBufferInfo { @@ -344,7 +348,7 @@ impl Drivers { let mut pref_b_size: c_long = 0; let mut grans: c_long = 0; - let mut result = Err(ASIOError::NoResult("not implimented".to_owned())); + let mut result = Err(AsioDriverError::NoResult("not implimented".to_owned())); unsafe { // Get the buffer sizes @@ -357,7 +361,7 @@ impl Drivers { &mut max_b_size, &mut pref_b_size, &mut grans, - )?; + ).expect("Failed getting buffers"); result = if pref_b_size > 0 { let mut buffer_info_convert: Vec = buffer_infos .into_iter() @@ -371,7 +375,7 @@ impl Drivers { pref_b_size, &mut callbacks_convert, ); - if buffer_result == 0 { + if buffer_result.is_ok() { let mut buffer_infos: Vec = buffer_info_convert .into_iter() .map(|bi| mem::transmute::(bi)) @@ -387,12 +391,12 @@ impl Drivers { buffer_size: pref_b_size, }); } - Err(ASIOError::BufferError(format!( - "failed to create buffers, error code: {}", + Err(AsioDriverError::BufferError(format!( + "failed to create buffers, error code: {:?}", buffer_result ))) } else { - Err(ASIOError::BufferError( + Err(AsioDriverError::BufferError( "Failed to get buffer size".to_owned(), )) }; @@ -490,8 +494,8 @@ pub fn get_driver_list() -> Vec { pub fn destroy_stream(stream: AsioStream) { unsafe { - asio_dispose_buffers()?; - asio_exit()?; + asio_dispose_buffers().expect("Failed to dispose buffers"); + asio_exit().expect("Failed to exit asio"); } } @@ -509,49 +513,57 @@ pub fn stop() { } } -fn asio_init(di: &mut ai::ASIODriverInfo) -> Result<(), AsioError> { - asio_result!(ASIOInit(di)); +unsafe fn asio_init(di: &mut ai::ASIODriverInfo) -> Result<(), AsioError> { + let result = ai::ASIOInit(di); + asio_result!(result) } -fn asio_get_channels(ins: &mut c_long, outs: &mut outs) -> Result<(), AsioError> { - asio_result!(ai::ASIOGetChannels(ins, outs)) +unsafe fn asio_get_channels(ins: &mut c_long, outs: &mut c_long) -> Result<(), AsioError> { + let result = ai::ASIOGetChannels(ins, outs); + asio_result!(result) } -fn asio_get_sample_rate(rate: &mut c_double) -> Result<(), AsioError> { - asio_result!(ai::get_sample_rate(rate)) +unsafe fn asio_get_sample_rate(rate: &mut c_double) -> Result<(), AsioError> { + let result = ai::get_sample_rate(rate); + asio_result!(result) } -fn asio_get_channel_info(ci: &mut ai::ASIOChannelInfo) -> Result<(), AsioError> { - asio_result!(ai::ASIOGetChannelInfo(ci)) +unsafe fn asio_get_channel_info(ci: &mut ai::ASIOChannelInfo) -> Result<(), AsioError> { + let result = ai::ASIOGetChannelInfo(ci); + asio_result!(result) } -fn asio_get_buffer_size( +unsafe fn asio_get_buffer_size( min_b_size: &mut c_long, max_b_size: &mut c_long, pref_b_size: &mut c_long, grans: &mut c_long, ) -> Result<(), AsioError> { - asio_result!(ai::ASIOGetBufferSize( + let result = ai::ASIOGetBufferSize( min_b_size, max_b_size, pref_b_size, grans, - )) + ); + asio_result!(result) } -fn asio_create_buffers( - buffer_info_convert: &mut ai::ASIOBufferInfo, num_channels: i32, pref_b_size: c_long, +unsafe fn asio_create_buffers( + buffer_info_convert: *mut ai::ASIOBufferInfo, num_channels: i32, pref_b_size: c_long, callbacks_convert: &mut ai::ASIOCallbacks, ) -> Result<(), AsioError> { - asio_result!(ai::ASIOCreateBuffers( + let result = ai::ASIOCreateBuffers( buffer_info_convert, num_channels, pref_b_size, callbacks_convert, - )) + ); + asio_result!(result) } -fn asio_dispose_buffers() -> Result<(), AsioError> { - asio_result!(ai::ASIODisposeBuffers()) +unsafe fn asio_dispose_buffers() -> Result<(), AsioError> { + let result = ai::ASIODisposeBuffers(); + asio_result!(result) } -fn asio_exit() -> Result<(), AsioError> { - asio_result!(ai::ASIOExit()) -} +unsafe fn asio_exit() -> Result<(), AsioError> { + let result = ai::ASIOExit(); + asio_result!(result) +} \ No newline at end of file