error wrappers
This commit is contained in:
parent
4ba291e8be
commit
ec172bbc47
|
@ -2,20 +2,53 @@ use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ASIOError {
|
pub enum AsioError {
|
||||||
NoResult(String),
|
NoResult(String),
|
||||||
BufferError(String),
|
BufferError(String),
|
||||||
DriverLoadError,
|
DriverLoadError,
|
||||||
TypeError,
|
TypeError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ASIOError {
|
#[derive(Debug)]
|
||||||
|
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
|
||||||
|
ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function)
|
||||||
|
ASE_InvalidParameter, // input parameter invalid
|
||||||
|
ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode
|
||||||
|
ASE_SPNotAdvancing, // hardware is not running when sample position is inquired
|
||||||
|
ASE_NoClock, // sample clock or rate cannot be determined or is not present
|
||||||
|
ASE_NoMemory, // not enough memory for completing the request
|
||||||
|
Invalid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for AsioError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
ASIOError::NoResult(ref e) => write!(f, "Driver {} not found", e),
|
ASIOError::NoResult(ref e) => write!(f, "Driver {} not found", e),
|
||||||
ASIOError::BufferError(ref e) => write!(f, "Buffer Error: {}", e),
|
ASIOError::BufferError(ref e) => write!(f, "Buffer Error: {}", e),
|
||||||
ASIOError::DriverLoadError => write!(f, "Couldn't load the driver"),
|
ASIOError::DriverLoadError => write!(f, "Couldn't load the driver"),
|
||||||
ASIOError::TypeError => write!(f, "Couldn't convert sample type"),
|
ASIOError::TypeError => write!(f, "Couldn't convert sample type"),
|
||||||
|
AsioError::NoDrivers => {
|
||||||
|
write!(f, "hardware input or output is not present or available")
|
||||||
|
},
|
||||||
|
AsioError::HardwareMalfunction => write!(
|
||||||
|
f,
|
||||||
|
"hardware is malfunctioning (can be returned by any ASIO function)"
|
||||||
|
),
|
||||||
|
AsioError::InvalidInput => write!(f, "input parameter invalid"),
|
||||||
|
AsioError::BadMode => write!(f, "hardware is in a bad mode or used in a bad mode"),
|
||||||
|
AsioError::HardwareStuck => write!(
|
||||||
|
f,
|
||||||
|
"hardware is not running when sample position is inquired"
|
||||||
|
),
|
||||||
|
AsioError::NoRate => write!(
|
||||||
|
f,
|
||||||
|
"sample clock or rate cannot be determined or is not present"
|
||||||
|
),
|
||||||
|
AsioError::ASE_NoMemory => write!(f, "not enough memory for completing the request"),
|
||||||
|
AsioError::UnknownError => write!(f, "Error not in SDK"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +60,56 @@ impl Error for ASIOError {
|
||||||
ASIOError::BufferError(_) => "Error creating the buffer",
|
ASIOError::BufferError(_) => "Error creating the buffer",
|
||||||
ASIOError::DriverLoadError => "Error loading the driver",
|
ASIOError::DriverLoadError => "Error loading the driver",
|
||||||
ASIOError::TypeError => "Error getting sample type",
|
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)"
|
||||||
|
},
|
||||||
|
AsioError::InvalidInput => "input parameter invalid",
|
||||||
|
AsioError::BadMode => "hardware is in a bad mode or used in a bad mode",
|
||||||
|
AsioError::HardwareStuck => "hardware is not running when sample position is inquired",
|
||||||
|
AsioError::NoRate => "sample clock or rate cannot be determined or is not present",
|
||||||
|
AsioError::ASE_NoMemory => "not enough memory for completing the request",
|
||||||
|
AsioError::UnknownError => "Error not in SDK",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! asio_error_helper {
|
||||||
|
($x:expr, $ae:ident{ $($v:ident),+ }, $inval:ident) => {
|
||||||
|
match $x {
|
||||||
|
$(_ if $x == $ae::$v as i32 => $ae::$v,)+
|
||||||
|
_ => $ae::$inval,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! asio_result {
|
||||||
|
($result:expr) => {
|
||||||
|
match asio_error!(
|
||||||
|
$result,
|
||||||
|
AsioErrorWrapper {
|
||||||
|
ASE_OK,
|
||||||
|
ASE_SUCCESS,
|
||||||
|
ASE_NotPresent,
|
||||||
|
ASE_HWMalfunction,
|
||||||
|
ASE_InvalidParameter,
|
||||||
|
ASE_InvalidMode,
|
||||||
|
ASE_SPNotAdvancing,
|
||||||
|
ASE_NoClock,
|
||||||
|
ASE_NoMemory
|
||||||
|
},
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -10,16 +10,16 @@ extern crate num_derive;
|
||||||
mod asio_import;
|
mod asio_import;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
||||||
use std::os::raw::c_char;
|
use errors::ASIOError;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::mem;
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
use std::os::raw::c_double;
|
||||||
use std::os::raw::c_long;
|
use std::os::raw::c_long;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::os::raw::c_double;
|
|
||||||
use errors::ASIOError;
|
|
||||||
use std::mem;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use asio_import as ai;
|
use asio_import as ai;
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ pub struct CbArgs<S, D> {
|
||||||
|
|
||||||
struct BufferCallback(Box<FnMut(i32) + Send>);
|
struct BufferCallback(Box<FnMut(i32) + Send>);
|
||||||
|
|
||||||
lazy_static!{
|
lazy_static! {
|
||||||
static ref buffer_callback: Mutex<Option<BufferCallback>> = Mutex::new(None);
|
static ref buffer_callback: Mutex<Option<BufferCallback>> = Mutex::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static!{
|
lazy_static! {
|
||||||
static ref ASIO_DRIVERS: Mutex<Option<DriverWrapper>> = Mutex::new(None);
|
static ref ASIO_DRIVERS: Mutex<Option<DriverWrapper>> = Mutex::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,43 +66,6 @@ pub struct AsioStream {
|
||||||
pub buffer_size: i32,
|
pub buffer_size: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum AsioErrorConvert {
|
|
||||||
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
|
|
||||||
ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function)
|
|
||||||
ASE_InvalidParameter, // input parameter invalid
|
|
||||||
ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode
|
|
||||||
ASE_SPNotAdvancing, // hardware is not running when sample position is inquired
|
|
||||||
ASE_NoClock, // sample clock or rate cannot be determined or is not present
|
|
||||||
ASE_NoMemory, // not enough memory for completing the request
|
|
||||||
Invalid,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! asio_error {
|
|
||||||
($x:expr, $ae:ident{ $($v:ident),+ }, $inval:ident) => {
|
|
||||||
match $x {
|
|
||||||
$(_ if $x == $ae::$v as i32 => $ae::$v,)+
|
|
||||||
_ => $ae::$inval,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn result_to_error(result: i32) -> AsioErrorConvert {
|
|
||||||
asio_error!(result,
|
|
||||||
AsioErrorConvert{
|
|
||||||
ASE_OK,
|
|
||||||
ASE_SUCCESS,
|
|
||||||
ASE_NotPresent,
|
|
||||||
ASE_HWMalfunction,
|
|
||||||
ASE_InvalidParameter,
|
|
||||||
ASE_InvalidMode,
|
|
||||||
ASE_SPNotAdvancing,
|
|
||||||
ASE_NoClock,
|
|
||||||
ASE_NoMemory}, Invalid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a direct copy of the ASIOSampleType
|
// This is a direct copy of the ASIOSampleType
|
||||||
// inside ASIO SDK.
|
// inside ASIO SDK.
|
||||||
#[derive(Debug, FromPrimitive)]
|
#[derive(Debug, FromPrimitive)]
|
||||||
|
@ -175,34 +138,29 @@ extern "C" fn buffer_switch(double_buffer_index: c_long, direct_process: c_long)
|
||||||
extern "C" fn sample_rate_did_change(s_rate: c_double) -> () {}
|
extern "C" fn sample_rate_did_change(s_rate: c_double) -> () {}
|
||||||
|
|
||||||
extern "C" fn asio_message(
|
extern "C" fn asio_message(
|
||||||
selector: c_long,
|
selector: c_long, value: c_long, message: *mut (), opt: *mut c_double,
|
||||||
value: c_long,
|
|
||||||
message: *mut (),
|
|
||||||
opt: *mut c_double,
|
|
||||||
) -> c_long {
|
) -> c_long {
|
||||||
4 as c_long
|
4 as c_long
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn buffer_switch_time_info(
|
extern "C" fn buffer_switch_time_info(
|
||||||
params: *mut ai::ASIOTime,
|
params: *mut ai::ASIOTime, double_buffer_index: c_long, direct_process: c_long,
|
||||||
double_buffer_index: c_long,
|
|
||||||
direct_process: c_long,
|
|
||||||
) -> *mut ai::ASIOTime {
|
) -> *mut ai::ASIOTime {
|
||||||
params
|
params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Drivers {
|
impl Drivers {
|
||||||
pub fn load(driver_name: &str) -> Result<Self, ASIOError> {
|
pub fn load(driver_name: &str) -> Result<Self, ASIOError> {
|
||||||
let mut drivers = ASIO_DRIVERS.lock().unwrap();
|
let mut drivers = ASIO_DRIVERS.lock().unwrap();
|
||||||
match *drivers {
|
match *drivers {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||||
Ok(Drivers{})
|
Ok(Drivers {})
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
// Make owned CString to send to load driver
|
// Make owned CString to send to load driver
|
||||||
let mut my_driver_name = CString::new(driver_name).expect("Can't go from str to CString");
|
let mut my_driver_name =
|
||||||
|
CString::new(driver_name).expect("Can't go from str to CString");
|
||||||
let raw = my_driver_name.into_raw();
|
let raw = my_driver_name.into_raw();
|
||||||
let mut driver_info = ai::ASIODriverInfo {
|
let mut driver_info = ai::ASIODriverInfo {
|
||||||
_bindgen_opaque_blob: [0u32; 43],
|
_bindgen_opaque_blob: [0u32; 43],
|
||||||
|
@ -210,14 +168,16 @@ impl Drivers {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut asio_drivers = ai::AsioDrivers::new();
|
let mut asio_drivers = ai::AsioDrivers::new();
|
||||||
let load_result = asio_drivers.loadDriver(raw);
|
let load_result = asio_drivers.loadDriver(raw);
|
||||||
ai::ASIOInit(&mut driver_info);
|
asio_init(&mut driver_info)?;
|
||||||
// Take back ownership
|
// Take back ownership
|
||||||
my_driver_name = CString::from_raw(raw);
|
my_driver_name = CString::from_raw(raw);
|
||||||
if load_result {
|
if load_result {
|
||||||
println!("Creating drivers");
|
println!("Creating drivers");
|
||||||
*drivers = Some(DriverWrapper{drivers: asio_drivers});
|
*drivers = Some(DriverWrapper {
|
||||||
|
drivers: asio_drivers,
|
||||||
|
});
|
||||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||||
Ok(Drivers{})
|
Ok(Drivers {})
|
||||||
} else {
|
} else {
|
||||||
Err(ASIOError::DriverLoadError)
|
Err(ASIOError::DriverLoadError)
|
||||||
}
|
}
|
||||||
|
@ -240,7 +200,7 @@ impl Drivers {
|
||||||
let mut ins: c_long = 0;
|
let mut ins: c_long = 0;
|
||||||
let mut outs: c_long = 0;
|
let mut outs: c_long = 0;
|
||||||
unsafe {
|
unsafe {
|
||||||
println!("Channels result {:?}", result_to_error(ai::ASIOGetChannels(&mut ins, &mut outs)));
|
asio_get_channels(&mut ins, &mut outs)?;
|
||||||
channel = Channel {
|
channel = Channel {
|
||||||
ins: ins as i64,
|
ins: ins as i64,
|
||||||
outs: outs as i64,
|
outs: outs as i64,
|
||||||
|
@ -257,7 +217,7 @@ impl Drivers {
|
||||||
let mut rate: c_double = 0.0f64;
|
let mut rate: c_double = 0.0f64;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
println!("sample rate {:?}", result_to_error(ai::get_sample_rate(&mut rate)));
|
asio_get_sample_rate(&mut rate)?;
|
||||||
sample_rate = SampleRate { rate: rate as u32 };
|
sample_rate = SampleRate { rate: rate as u32 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +237,7 @@ impl Drivers {
|
||||||
name: [0 as c_char; 32],
|
name: [0 as c_char; 32],
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
println!("data type {:?}", result_to_error(ai::ASIOGetChannelInfo(&mut channel_info)));
|
asio_get_channel_info(&mut channel_info)?;
|
||||||
data_type = num::FromPrimitive::from_i32(channel_info.type_)
|
data_type = num::FromPrimitive::from_i32(channel_info.type_)
|
||||||
.map_or(Err(ASIOError::TypeError), |t| Ok(t));
|
.map_or(Err(ASIOError::TypeError), |t| Ok(t));
|
||||||
}
|
}
|
||||||
|
@ -291,7 +251,8 @@ impl Drivers {
|
||||||
is_input: 1,
|
is_input: 1,
|
||||||
channel_num: 0,
|
channel_num: 0,
|
||||||
buffers: [std::ptr::null_mut(); 2],
|
buffers: [std::ptr::null_mut(); 2],
|
||||||
}; num_channels
|
};
|
||||||
|
num_channels
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut callbacks = AsioCallbacks {
|
let mut callbacks = AsioCallbacks {
|
||||||
|
@ -306,30 +267,31 @@ impl Drivers {
|
||||||
let mut pref_b_size: c_long = 0;
|
let mut pref_b_size: c_long = 0;
|
||||||
let mut grans: c_long = 0;
|
let mut grans: c_long = 0;
|
||||||
|
|
||||||
|
|
||||||
let mut result = Err(ASIOError::NoResult("not implimented".to_owned()));
|
let mut result = Err(ASIOError::NoResult("not implimented".to_owned()));
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
ai::ASIOGetBufferSize(
|
asio_get_buffer_size(
|
||||||
&mut min_b_size,
|
&mut min_b_size,
|
||||||
&mut max_b_size,
|
&mut max_b_size,
|
||||||
&mut pref_b_size,
|
&mut pref_b_size,
|
||||||
&mut grans,
|
&mut grans,
|
||||||
);
|
)?;
|
||||||
result = if pref_b_size > 0 {
|
result = if pref_b_size > 0 {
|
||||||
let mut buffer_info_convert: Vec<ai::ASIOBufferInfo> = buffer_infos.into_iter()
|
let mut buffer_info_convert: Vec<ai::ASIOBufferInfo> = buffer_infos
|
||||||
|
.into_iter()
|
||||||
.map(|bi| mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(bi))
|
.map(|bi| mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(bi))
|
||||||
.collect();
|
.collect();
|
||||||
let mut callbacks_convert =
|
let mut callbacks_convert =
|
||||||
mem::transmute::<AsioCallbacks, ai::ASIOCallbacks>(callbacks);
|
mem::transmute::<AsioCallbacks, ai::ASIOCallbacks>(callbacks);
|
||||||
let buffer_result = ai::ASIOCreateBuffers(
|
let buffer_result = asio_create_buffers(
|
||||||
buffer_info_convert.as_mut_ptr(),
|
buffer_info_convert.as_mut_ptr(),
|
||||||
num_channels as i32,
|
num_channels as i32,
|
||||||
pref_b_size,
|
pref_b_size,
|
||||||
&mut callbacks_convert,
|
&mut callbacks_convert,
|
||||||
);
|
);
|
||||||
if buffer_result == 0 {
|
if buffer_result == 0 {
|
||||||
let mut buffer_infos: Vec<AsioBufferInfo> = buffer_info_convert.into_iter()
|
let mut buffer_infos: Vec<AsioBufferInfo> = buffer_info_convert
|
||||||
|
.into_iter()
|
||||||
.map(|bi| mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(bi))
|
.map(|bi| mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(bi))
|
||||||
.collect();
|
.collect();
|
||||||
for d in &buffer_infos {
|
for d in &buffer_infos {
|
||||||
|
@ -345,7 +307,8 @@ impl Drivers {
|
||||||
}
|
}
|
||||||
Err(ASIOError::BufferError(format!(
|
Err(ASIOError::BufferError(format!(
|
||||||
"failed to create buffers,
|
"failed to create buffers,
|
||||||
error code: {}",
|
error \
|
||||||
|
code: {}",
|
||||||
buffer_result
|
buffer_result
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -365,7 +328,8 @@ impl Drivers {
|
||||||
is_input: 0,
|
is_input: 0,
|
||||||
channel_num: 0,
|
channel_num: 0,
|
||||||
buffers: [std::ptr::null_mut(); 2],
|
buffers: [std::ptr::null_mut(); 2],
|
||||||
}; num_channels
|
};
|
||||||
|
num_channels
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut callbacks = AsioCallbacks {
|
let mut callbacks = AsioCallbacks {
|
||||||
|
@ -388,38 +352,28 @@ impl Drivers {
|
||||||
// max possible size
|
// max possible size
|
||||||
// preferred size
|
// preferred size
|
||||||
// granularity
|
// granularity
|
||||||
ai::ASIOGetBufferSize(
|
asio_get_buffer_size(
|
||||||
&mut min_b_size,
|
&mut min_b_size,
|
||||||
&mut max_b_size,
|
&mut max_b_size,
|
||||||
&mut pref_b_size,
|
&mut pref_b_size,
|
||||||
&mut grans,
|
&mut grans,
|
||||||
);
|
)?;
|
||||||
result = if pref_b_size > 0 {
|
result = if pref_b_size > 0 {
|
||||||
/*
|
let mut buffer_info_convert: Vec<ai::ASIOBufferInfo> = buffer_infos
|
||||||
let mut buffer_info_convert = [
|
.into_iter()
|
||||||
mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(buffer_infos[0]),
|
|
||||||
mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(buffer_infos[1]),
|
|
||||||
];
|
|
||||||
*/
|
|
||||||
let mut buffer_info_convert: Vec<ai::ASIOBufferInfo> = buffer_infos.into_iter()
|
|
||||||
.map(|bi| mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(bi))
|
.map(|bi| mem::transmute::<AsioBufferInfo, ai::ASIOBufferInfo>(bi))
|
||||||
.collect();
|
.collect();
|
||||||
let mut callbacks_convert =
|
let mut callbacks_convert =
|
||||||
mem::transmute::<AsioCallbacks, ai::ASIOCallbacks>(callbacks);
|
mem::transmute::<AsioCallbacks, ai::ASIOCallbacks>(callbacks);
|
||||||
let buffer_result = ai::ASIOCreateBuffers(
|
let buffer_result = asio_create_buffers(
|
||||||
buffer_info_convert.as_mut_ptr(),
|
buffer_info_convert.as_mut_ptr(),
|
||||||
num_channels as i32,
|
num_channels as i32,
|
||||||
pref_b_size,
|
pref_b_size,
|
||||||
&mut callbacks_convert,
|
&mut callbacks_convert,
|
||||||
);
|
);
|
||||||
if buffer_result == 0 {
|
if buffer_result == 0 {
|
||||||
/*
|
let mut buffer_infos: Vec<AsioBufferInfo> = buffer_info_convert
|
||||||
let buffer_infos = [
|
.into_iter()
|
||||||
mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(buffer_info_convert[0]),
|
|
||||||
mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(buffer_info_convert[1]),
|
|
||||||
];
|
|
||||||
*/
|
|
||||||
let mut buffer_infos: Vec<AsioBufferInfo> = buffer_info_convert.into_iter()
|
|
||||||
.map(|bi| mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(bi))
|
.map(|bi| mem::transmute::<ai::ASIOBufferInfo, AsioBufferInfo>(bi))
|
||||||
.collect();
|
.collect();
|
||||||
for d in &buffer_infos {
|
for d in &buffer_infos {
|
||||||
|
@ -434,7 +388,8 @@ impl Drivers {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(ASIOError::BufferError(format!(
|
Err(ASIOError::BufferError(format!(
|
||||||
"failed to create buffers, error code: {}", buffer_result
|
"failed to create buffers, error code: {}",
|
||||||
|
buffer_result
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Err(ASIOError::BufferError(
|
Err(ASIOError::BufferError(
|
||||||
|
@ -452,7 +407,7 @@ impl Drop for Drivers {
|
||||||
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
println!("Destroying driver");
|
println!("Destroying driver");
|
||||||
unsafe{
|
unsafe {
|
||||||
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
||||||
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
||||||
}
|
}
|
||||||
|
@ -467,7 +422,7 @@ impl Drop for AsioStream {
|
||||||
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
println!("Destroying driver");
|
println!("Destroying driver");
|
||||||
unsafe{
|
unsafe {
|
||||||
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
||||||
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +458,7 @@ pub fn get_driver_list() -> Vec<String> {
|
||||||
let mut driver_names: [[c_char; MAX_DRIVER]; MAX_DRIVER] = [[0; MAX_DRIVER]; MAX_DRIVER];
|
let mut driver_names: [[c_char; MAX_DRIVER]; MAX_DRIVER] = [[0; MAX_DRIVER]; MAX_DRIVER];
|
||||||
let mut p_driver_name: [*mut i8; MAX_DRIVER] = [0 as *mut i8; MAX_DRIVER];
|
let mut p_driver_name: [*mut i8; MAX_DRIVER] = [0 as *mut i8; MAX_DRIVER];
|
||||||
|
|
||||||
for i in 0..MAX_DRIVER {
|
for i in 0 .. MAX_DRIVER {
|
||||||
p_driver_name[i] = driver_names[i].as_mut_ptr();
|
p_driver_name[i] = driver_names[i].as_mut_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +469,7 @@ pub fn get_driver_list() -> Vec<String> {
|
||||||
asio_drivers.getDriverNames(p_driver_name.as_mut_ptr(), MAX_DRIVER as i32);
|
asio_drivers.getDriverNames(p_driver_name.as_mut_ptr(), MAX_DRIVER as i32);
|
||||||
|
|
||||||
if num_drivers > 0 {
|
if num_drivers > 0 {
|
||||||
for i in 0..num_drivers {
|
for i in 0 .. num_drivers {
|
||||||
let mut my_driver_name = CString::new("").unwrap();
|
let mut my_driver_name = CString::new("").unwrap();
|
||||||
let name = CStr::from_ptr(p_driver_name[i as usize]);
|
let name = CStr::from_ptr(p_driver_name[i as usize]);
|
||||||
my_driver_name = name.to_owned();
|
my_driver_name = name.to_owned();
|
||||||
|
@ -533,12 +488,10 @@ pub fn get_driver_list() -> Vec<String> {
|
||||||
driver_list
|
driver_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn destroy_stream(stream: AsioStream) {
|
pub fn destroy_stream(stream: AsioStream) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ai::ASIODisposeBuffers();
|
asio_dispose_buffers()?;
|
||||||
ai::ASIOExit();
|
asio_exit()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,3 +509,49 @@ pub fn stop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn asio_init(di: &mut ai::ASIODriverInfo) -> Result<(), AsioError> {
|
||||||
|
asio_result!(ASIOInit(di));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asio_get_channels(ins: &mut c_long, outs: &mut outs) -> Result<(), AsioError> {
|
||||||
|
asio_result!(ai::ASIOGetChannels(ins, outs))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asio_get_sample_rate(rate: &mut c_double) -> Result<(), AsioError> {
|
||||||
|
asio_result!(ai::get_sample_rate(rate))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asio_get_channel_info(ci: &mut ai::ASIOChannelInfo) -> Result<(), AsioError> {
|
||||||
|
asio_result!(ai::ASIOGetChannelInfo(ci))
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
min_b_size,
|
||||||
|
max_b_size,
|
||||||
|
pref_b_size,
|
||||||
|
grans,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
buffer_info_convert,
|
||||||
|
num_channels,
|
||||||
|
pref_b_size,
|
||||||
|
callbacks_convert,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asio_dispose_buffers() -> Result<(), AsioError> {
|
||||||
|
asio_result!(ai::ASIODisposeBuffers())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asio_exit() -> Result<(), AsioError> {
|
||||||
|
asio_result!(ai::ASIOExit())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue