From 76eb07a2741dd925e3f944241f65a9ab07712d6a Mon Sep 17 00:00:00 2001 From: Tom Gowan Date: Wed, 24 Oct 2018 17:34:31 +1100 Subject: [PATCH] Multiple streams --- asio-sys/src/lib.rs | 49 ++++++++++++++++++++++------- src/platform/windows/asio/device.rs | 20 ++++++++++-- src/platform/windows/asio/stream.rs | 29 +++++++++-------- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/asio-sys/src/lib.rs b/asio-sys/src/lib.rs index 4016d39..b2655c2 100644 --- a/asio-sys/src/lib.rs +++ b/asio-sys/src/lib.rs @@ -34,7 +34,7 @@ pub struct CbArgs { struct BufferCallback(Box); lazy_static! { - static ref buffer_callback: Mutex> = Mutex::new(None); + static ref buffer_callback: Mutex<[Option; 2]> = Mutex::new([None, None]); } lazy_static! { @@ -127,11 +127,20 @@ struct AsioCallbacks { direct_process: c_long, ) -> *mut ai::ASIOTime, } - -extern "C" fn buffer_switch(double_buffer_index: c_long, direct_process: c_long) -> () { +extern "C" fn buffer_switch_output(double_buffer_index: c_long, direct_process: c_long) -> () { let mut bc = buffer_callback.lock().unwrap(); + println!("output"); - if let Some(ref mut bc) = *bc { + if let Some(ref mut bc) = bc[0] { + bc.run(double_buffer_index); + } +} + +extern "C" fn buffer_switch_input(double_buffer_index: c_long, direct_process: c_long) -> () { + let mut bc = buffer_callback.lock().unwrap(); + println!("input"); + + if let Some(ref mut bc) = bc[1] { bc.run(double_buffer_index); } } @@ -260,7 +269,7 @@ impl Drivers { ]; let mut callbacks = AsioCallbacks { - buffer_switch: buffer_switch, + buffer_switch: buffer_switch_input, sample_rate_did_change: sample_rate_did_change, asio_message: asio_message, buffer_switch_time_info: buffer_switch_time_info, @@ -337,7 +346,7 @@ impl Drivers { ]; let mut callbacks = AsioCallbacks { - buffer_switch: buffer_switch, + buffer_switch: buffer_switch_output, sample_rate_did_change: sample_rate_did_change, asio_message: asio_message, buffer_switch_time_info: buffer_switch_time_info, @@ -446,12 +455,18 @@ impl BufferCallback { unsafe impl Send for AsioStream {} -pub fn set_callback(mut callback: F) -> () +pub fn set_callback(input: bool, mut callback: F) -> () where F: FnMut(i32) + Send, { let mut bc = buffer_callback.lock().unwrap(); - *bc = Some(BufferCallback(Box::new(callback))); + if input { + println!("Set input callback"); + bc[1] = Some(BufferCallback(Box::new(callback))); + }else{ + println!("Set output callback"); + bc[0] = Some(BufferCallback(Box::new(callback))); + } } /// Returns a list of all the ASIO drivers @@ -501,15 +516,15 @@ pub fn destroy_stream(stream: AsioStream) { pub fn play() { unsafe { - let result = ai::ASIOStart(); - println!("start result: {}", result); + let result = asio_start(); + println!("start result: {:?}", result); } } pub fn stop() { unsafe { - let result = ai::ASIOStop(); - println!("start result: {}", result); + let result = asio_stop(); + println!("stop result: {:?}", result); } } @@ -566,4 +581,14 @@ unsafe fn asio_dispose_buffers() -> Result<(), AsioError> { unsafe fn asio_exit() -> Result<(), AsioError> { let result = ai::ASIOExit(); asio_result!(result) +} + +unsafe fn asio_start() -> Result<(), AsioError> { + let result = ai::ASIOStart(); + asio_result!(result) +} + +unsafe fn asio_stop() -> Result<(), AsioError> { + let result = ai::ASIOStop(); + asio_result!(result) } \ No newline at end of file diff --git a/src/platform/windows/asio/device.rs b/src/platform/windows/asio/device.rs index 1bff1b9..af64202 100644 --- a/src/platform/windows/asio/device.rs +++ b/src/platform/windows/asio/device.rs @@ -128,7 +128,15 @@ impl Iterator for Devices { // so returning first in list as default pub fn default_input_device() -> Option { let mut driver_list = sys::get_driver_list(); - match driver_list.pop() { + // Remove + let d_name = driver_list.into_iter() + .filter(|d| d == "ASIO4ALL v2") + //.filter(|d| d.name() == "Dante Via (x64)") + //.filter(|d| d.name() == "Dante Virtual Soundcard (x64)") + .next(); + //match driver_list.pop() { + match d_name { + // end remove Some(name) => { sys::Drivers::load(&name) .or_else(|e| { @@ -144,7 +152,15 @@ pub fn default_input_device() -> Option { pub fn default_output_device() -> Option { let mut driver_list = sys::get_driver_list(); - match driver_list.pop() { + // Remove + let d_name = driver_list.into_iter() + .filter(|d| d == "ASIO4ALL v2") + //.filter(|d| d.name() == "Dante Via (x64)") + //.filter(|d| d.name() == "Dante Virtual Soundcard (x64)") + .next(); + //match driver_list.pop() { + match d_name { + // end remove Some(name) => { sys::Drivers::load(&name) .or_else(|e| { diff --git a/src/platform/windows/asio/stream.rs b/src/platform/windows/asio/stream.rs index 43ac99f..3407d75 100644 --- a/src/platform/windows/asio/stream.rs +++ b/src/platform/windows/asio/stream.rs @@ -16,8 +16,8 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use SampleFormat; pub struct EventLoop { - asio_stream: Arc>>, - stream_count: Arc, + asio_streams: Arc>>>, + stream_count: AtomicUsize, callbacks: Arc>>, } @@ -55,8 +55,8 @@ struct Buffers { impl EventLoop { pub fn new() -> EventLoop { EventLoop { - asio_stream: Arc::new(Mutex::new(None)), - stream_count: Arc::new(AtomicUsize::new(0)), + asio_streams: Arc::new(Mutex::new(Vec::new())), + stream_count: AtomicUsize::new(0), callbacks: Arc::new(Mutex::new(Vec::new())), } } @@ -77,11 +77,11 @@ impl EventLoop { let cpal_num_samples = (stream.buffer_size as usize) * num_channels as usize; { - *self.asio_stream.lock().unwrap() = Some(stream); + self.asio_streams.lock().unwrap().push(Some(stream)); } let count = self.stream_count.load(Ordering::SeqCst); self.stream_count.store(count + 1, Ordering::SeqCst); - let asio_stream = self.asio_stream.clone(); + let asio_streams = self.asio_streams.clone(); let callbacks = self.callbacks.clone(); let bytes_per_channel = format.data_type.sample_size(); @@ -126,8 +126,8 @@ impl EventLoop { } }; - sys::set_callback(move |index| unsafe { - if let Some(ref asio_stream) = *asio_stream.lock().unwrap() { + sys::set_callback(true, move |index| unsafe { + if let Some(ref asio_stream) = asio_streams.lock().unwrap()[count - 1] { // Number of samples needed total let mut callbacks = callbacks.lock().unwrap(); @@ -153,7 +153,6 @@ impl EventLoop { let buff_ptr = asio_stream .buffer_infos[i] .buffers[index as usize] as *mut $AsioType; - //.offset(asio_stream.buffer_size as isize * i as isize); let asio_buffer: &'static [$AsioType] = std::slice::from_raw_parts( buff_ptr, @@ -244,11 +243,11 @@ pub fn build_output_stream( let cpal_num_samples = (stream.buffer_size as usize) * num_channels as usize; { - *self.asio_stream.lock().unwrap() = Some(stream); + self.asio_streams.lock().unwrap().push(Some(stream)); } let count = self.stream_count.load(Ordering::SeqCst); self.stream_count.store(count + 1, Ordering::SeqCst); - let asio_stream = self.asio_stream.clone(); + let asio_streams = self.asio_streams.clone(); let callbacks = self.callbacks.clone(); let bytes_per_channel = format.data_type.sample_size(); // Create buffers @@ -292,8 +291,8 @@ pub fn build_output_stream( } }; - sys::set_callback(move |index| unsafe { - if let Some(ref asio_stream) = *asio_stream.lock().unwrap() { + sys::set_callback(false, move |index| unsafe { + if let Some(ref asio_stream) = asio_streams.lock().unwrap()[count - 1] { // Number of samples needed total let mut callbacks = callbacks.lock().unwrap(); @@ -402,8 +401,8 @@ pub fn pause_stream(&self, stream: StreamId) { sys::stop(); } pub fn destroy_stream(&self, stream_id: StreamId) { - let mut asio_stream_lock = self.asio_stream.lock().unwrap(); - let old_stream = mem::replace(&mut *asio_stream_lock, None); + let mut asio_streams_lock = self.asio_streams.lock().unwrap(); + let old_stream = mem::replace(asio_streams_lock.get_mut(stream_id.0 - 1).expect("stream count out of bounds"), None); if let Some(old_stream) = old_stream { sys::destroy_stream(old_stream); }