Multiple streams

This commit is contained in:
Tom Gowan 2018-10-24 17:34:31 +11:00 committed by mitchmindtree
parent c24fa62028
commit 76eb07a274
3 changed files with 69 additions and 29 deletions

View File

@ -34,7 +34,7 @@ pub struct CbArgs<S, D> {
struct BufferCallback(Box<FnMut(i32) + Send>);
lazy_static! {
static ref buffer_callback: Mutex<Option<BufferCallback>> = Mutex::new(None);
static ref buffer_callback: Mutex<[Option<BufferCallback>; 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<F: 'static>(mut callback: F) -> ()
pub fn set_callback<F: 'static>(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);
}
}
@ -567,3 +582,13 @@ 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)
}

View File

@ -128,7 +128,15 @@ impl Iterator for Devices {
// so returning first in list as default
pub fn default_input_device() -> Option<Device> {
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<Device> {
pub fn default_output_device() -> Option<Device> {
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| {

View File

@ -16,8 +16,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use SampleFormat;
pub struct EventLoop {
asio_stream: Arc<Mutex<Option<sys::AsioStream>>>,
stream_count: Arc<AtomicUsize>,
asio_streams: Arc<Mutex<Vec<Option<sys::AsioStream>>>>,
stream_count: AtomicUsize,
callbacks: Arc<Mutex<Vec<&'static mut (FnMut(StreamId, StreamData) + Send)>>>,
}
@ -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);
}