Multiple streams
This commit is contained in:
parent
c24fa62028
commit
76eb07a274
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
|
@ -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| {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue