Keep driver alive
This commit is contained in:
parent
ae7a03d788
commit
2ef7008615
|
@ -17,6 +17,7 @@ use std::os::raw::c_double;
|
|||
use errors::ASIOError;
|
||||
use std::mem;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use asio_import as ai;
|
||||
|
||||
|
@ -33,6 +34,12 @@ lazy_static!{
|
|||
static ref buffer_callback: Mutex<Option<BufferCallback>> = Mutex::new(None);
|
||||
}
|
||||
|
||||
lazy_static!{
|
||||
static ref ASIO_DRIVERS: Mutex<Option<DriverWrapper>> = Mutex::new(None);
|
||||
}
|
||||
|
||||
static STREAM_DRIVER_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Channel {
|
||||
pub ins: i64,
|
||||
|
@ -45,9 +52,7 @@ pub struct SampleRate {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Drivers {
|
||||
drivers: Arc<Mutex<DriverWrapper>>,
|
||||
}
|
||||
pub struct Drivers;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DriverWrapper {
|
||||
|
@ -151,6 +156,13 @@ extern "C" fn buffer_switch_time_info(
|
|||
|
||||
impl Drivers {
|
||||
pub fn load(driver_name: &str) -> Result<Self, ASIOError> {
|
||||
let mut drivers = ASIO_DRIVERS.lock().unwrap();
|
||||
match *drivers {
|
||||
Some(_) => {
|
||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
Ok(Drivers{})
|
||||
},
|
||||
None => {
|
||||
// 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 raw = my_driver_name.into_raw();
|
||||
|
@ -160,11 +172,15 @@ impl Drivers {
|
|||
// Take back ownership
|
||||
my_driver_name = CString::from_raw(raw);
|
||||
if load_result {
|
||||
Ok(Drivers{ drivers: Arc::new(Mutex::new(DriverWrapper{drivers: asio_drivers})) })
|
||||
*drivers = Some(DriverWrapper{drivers: asio_drivers});
|
||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
Ok(Drivers{})
|
||||
} else {
|
||||
Err(ASIOError::DriverLoadError)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the channels for the driver it's passed
|
||||
|
@ -305,6 +321,7 @@ impl Drivers {
|
|||
}
|
||||
println!("channels: {:?}", num_channels);
|
||||
|
||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
return Ok(AsioStream {
|
||||
buffer_infos: buffer_infos,
|
||||
buffer_size: pref_b_size,
|
||||
|
@ -324,7 +341,9 @@ impl Drivers {
|
|||
result
|
||||
}
|
||||
|
||||
/// Creates the output stream
|
||||
pub fn prepare_output_stream(&self) -> Result<AsioStream, ASIOError> {
|
||||
// Initialize data for FFI
|
||||
let mut buffer_infos = [
|
||||
AsioBufferInfo {
|
||||
is_input: 0,
|
||||
|
@ -358,7 +377,13 @@ impl Drivers {
|
|||
let mut result = Err(ASIOError::NoResult("not implimented".to_owned()));
|
||||
|
||||
unsafe {
|
||||
// Initialize ASIO stream
|
||||
ai::ASIOInit(&mut driver_info);
|
||||
// Get the buffer sizes
|
||||
// min possilbe size
|
||||
// max possible size
|
||||
// preferred size
|
||||
// granularity
|
||||
ai::ASIOGetBufferSize(
|
||||
&mut min_b_size,
|
||||
&mut max_b_size,
|
||||
|
@ -388,15 +413,14 @@ impl Drivers {
|
|||
}
|
||||
println!("channels: {:?}", num_channels);
|
||||
|
||||
STREAM_DRIVER_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
return Ok(AsioStream {
|
||||
buffer_infos: buffer_infos,
|
||||
buffer_size: pref_b_size,
|
||||
});
|
||||
}
|
||||
Err(ASIOError::BufferError(format!(
|
||||
"failed to create buffers,
|
||||
error code: {}",
|
||||
buffer_result
|
||||
"failed to create buffers, error code: {}", buffer_result
|
||||
)))
|
||||
} else {
|
||||
Err(ASIOError::BufferError(
|
||||
|
@ -408,14 +432,38 @@ impl Drivers {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for DriverWrapper {
|
||||
impl Drop for Drivers {
|
||||
fn drop(&mut self) {
|
||||
println!("dropping drivers");
|
||||
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
||||
if count == 1 {
|
||||
println!("Destroying driver");
|
||||
unsafe{
|
||||
ai::destruct_AsioDrivers(&mut self.drivers);
|
||||
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
||||
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AsioStream {
|
||||
fn drop(&mut self) {
|
||||
println!("dropping stream");
|
||||
let count = STREAM_DRIVER_COUNT.fetch_sub(1, Ordering::SeqCst);
|
||||
if count == 1 {
|
||||
println!("Destroying driver");
|
||||
unsafe{
|
||||
if let Some(mut asio_drivers) = (*ASIO_DRIVERS.lock().unwrap()).take() {
|
||||
ai::destruct_AsioDrivers(&mut asio_drivers.drivers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for DriverWrapper {}
|
||||
|
||||
impl BufferCallback {
|
||||
fn run(&mut self, index: i32) {
|
||||
let mut cb = &mut self.0;
|
||||
|
@ -476,6 +524,7 @@ pub fn get_driver_list() -> Vec<String> {
|
|||
pub fn destroy_stream(stream: AsioStream) {
|
||||
unsafe {
|
||||
ai::ASIODisposeBuffers();
|
||||
ai::ASIOExit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue