indentation and no clean up on destroy stream

This commit is contained in:
Tom Gowan 2018-11-07 19:26:39 +11:00 committed by mitchmindtree
parent b70e27ed87
commit fd808b95e9
1 changed files with 564 additions and 594 deletions

View File

@ -198,8 +198,8 @@ impl EventLoop {
let Device { drivers, .. } = device; let Device { drivers, .. } = device;
let num_channels = format.channels.clone(); let num_channels = format.channels.clone();
let stream_type = drivers.get_data_type().expect("Couldn't load data type"); let stream_type = drivers.get_data_type().expect("Couldn't load data type");
self.get_input_stream(&drivers, format) let input_stream = self.get_input_stream(&drivers, format);
.map(|stream_buffer_size| { input_stream.map(|stream_buffer_size| {
let cpal_num_samples = stream_buffer_size * num_channels as usize; let cpal_num_samples = stream_buffer_size * num_channels as usize;
let count = self.stream_count.fetch_add(1, Ordering::SeqCst); let count = self.stream_count.fetch_add(1, Ordering::SeqCst);
let asio_streams = self.asio_streams.clone(); let asio_streams = self.asio_streams.clone();
@ -239,7 +239,6 @@ impl EventLoop {
// This is most performance critical part of the ASIO bindings. // This is most performance critical part of the ASIO bindings.
sys::set_callback(move |index| unsafe { sys::set_callback(move |index| unsafe {
// if not playing return early // if not playing return early
// TODO is this lock necessary
{ {
if let Some(s) = cpal_streams.lock().unwrap().get(count - 1) { if let Some(s) = cpal_streams.lock().unwrap().get(count - 1) {
if let Some(s) = s { if let Some(s) = s {
@ -250,16 +249,21 @@ impl EventLoop {
} }
} }
// Get the stream // Get the stream
// TODO is this lock necessary let stream_lock = asio_streams.lock().unwrap();
if let Some(ref asio_stream) = asio_streams.lock().unwrap().input { let ref asio_stream = match stream_lock.input {
Some(ref asio_stream) => asio_stream,
None => return (),
};
// Get the callback // Get the callback
// TODO is this lock necessary
let mut callbacks = callbacks.lock().unwrap(); let mut callbacks = callbacks.lock().unwrap();
// Theres only a single callback because theres only one event loop // Theres only a single callback because theres only one event loop
// TODO is 64bit necessary. Might be using more memory then needed let callback = match callbacks.as_mut() {
match callbacks.as_mut() { Some(callback) => callback,
Some(callback) => { None => return (),
};
// Macro to convert sample from ASIO to CPAL type // Macro to convert sample from ASIO to CPAL type
macro_rules! convert_sample { macro_rules! convert_sample {
// floats types required different conversion // floats types required different conversion
@ -268,16 +272,14 @@ impl EventLoop {
$SampleTypeIdent:ident, $SampleTypeIdent:ident,
$Sample:expr $Sample:expr
) => { ) => {
(*$Sample as f64 (*$Sample as f64 / ::std::$SampleTypeIdent::MAX as f64) as f32
/ ::std::$SampleTypeIdent::MAX as f64) as f32
}; };
($AsioTypeIdent:ident, ($AsioTypeIdent:ident,
f64, f64,
$SampleTypeIdent:ident, $SampleTypeIdent:ident,
$Sample:expr $Sample:expr
) => { ) => {
*$Sample as f64 *$Sample as f64 / ::std::$SampleTypeIdent::MAX as f64
/ ::std::$SampleTypeIdent::MAX as f64
}; };
($AsioTypeIdent:ident, ($AsioTypeIdent:ident,
$SampleType:ty, $SampleType:ty,
@ -285,8 +287,7 @@ impl EventLoop {
$Sample:expr $Sample:expr
) => { ) => {
(*$Sample as i64 * ::std::$SampleTypeIdent::MAX as i64 (*$Sample as i64 * ::std::$SampleTypeIdent::MAX as i64
/ ::std::$AsioTypeIdent::MAX as i64) / ::std::$AsioTypeIdent::MAX as i64) as $SampleType
as $SampleType
}; };
}; };
// This creates gets the buffer and interleaves it. // This creates gets the buffer and interleaves it.
@ -306,14 +307,10 @@ impl EventLoop {
// For each channel write the asio buffer to // For each channel write the asio buffer to
// the cpal buffer // the cpal buffer
for (i, channel) in for (i, channel) in $Buffers.channel.iter_mut().enumerate() {
$Buffers.channel.iter_mut().enumerate() let buff_ptr = asio_stream.buffer_infos[i].buffers[index as usize]
{
let buff_ptr = asio_stream.buffer_infos[i].buffers
[index as usize]
as *mut $AsioType; as *mut $AsioType;
let asio_buffer: &'static [$AsioType] = let asio_buffer: &'static [$AsioType] = std::slice::from_raw_parts(
std::slice::from_raw_parts(
buff_ptr, buff_ptr,
asio_stream.buffer_size as usize, asio_stream.buffer_size as usize,
); );
@ -351,15 +348,9 @@ impl EventLoop {
callback( callback(
StreamId(count), StreamId(count),
StreamData::Input { StreamData::Input {
buffer: UnknownTypeInputBuffer::$SampleFormat( buffer: UnknownTypeInputBuffer::$SampleFormat(::InputBuffer {
::InputBuffer { buffer: Some(super::super::InputBuffer::Asio(buff)),
buffer: Some( }),
super::super::InputBuffer::Asio(
buff,
),
),
},
),
}, },
); );
}; };
@ -480,10 +471,6 @@ impl EventLoop {
} }
_ => println!("unsupported format {:?}", stream_type), _ => println!("unsupported format {:?}", stream_type),
} }
}
None => return (),
}
}
}); });
// Create stream and set to paused // Create stream and set to paused
self.cpal_streams self.cpal_streams
@ -503,8 +490,8 @@ impl EventLoop {
let Device { drivers, .. } = device; let Device { drivers, .. } = device;
let num_channels = format.channels.clone(); let num_channels = format.channels.clone();
let stream_type = drivers.get_data_type().expect("Couldn't load data type"); let stream_type = drivers.get_data_type().expect("Couldn't load data type");
self.get_output_stream(&drivers, format) let output_stream = self.get_output_stream(&drivers, format);
.map(|stream_buffer_size| { output_stream.map(|stream_buffer_size| {
let cpal_num_samples = stream_buffer_size * num_channels as usize; let cpal_num_samples = stream_buffer_size * num_channels as usize;
let count = self.stream_count.fetch_add(1, Ordering::SeqCst); let count = self.stream_count.fetch_add(1, Ordering::SeqCst);
let asio_streams = self.asio_streams.clone(); let asio_streams = self.asio_streams.clone();
@ -537,7 +524,6 @@ impl EventLoop {
sys::set_callback(move |index| unsafe { sys::set_callback(move |index| unsafe {
// if not playing return early // if not playing return early
// TODO is this lock necessary
{ {
if let Some(s) = cpal_streams.lock().unwrap().get(count - 1) { if let Some(s) = cpal_streams.lock().unwrap().get(count - 1) {
if let Some(s) = s { if let Some(s) = s {
@ -547,12 +533,22 @@ impl EventLoop {
} }
} }
} }
// Get the output stream // Get the stream
// TODO is this lock necessary let stream_lock = asio_streams.lock().unwrap();
if let Some(ref asio_stream) = asio_streams.lock().unwrap().output { let ref asio_stream = match stream_lock.output {
// Number of samples needed total Some(ref asio_stream) => asio_stream,
None => return (),
};
// Get the callback
let mut callbacks = callbacks.lock().unwrap(); let mut callbacks = callbacks.lock().unwrap();
// Theres only a single callback because theres only one event loop
let callback = match callbacks.as_mut() {
Some(callback) => callback,
None => return (),
};
// Convert sample depending on the sample type // Convert sample depending on the sample type
macro_rules! convert_sample { macro_rules! convert_sample {
($AsioTypeIdent:ident, ($AsioTypeIdent:ident,
@ -560,16 +556,14 @@ impl EventLoop {
$SampleTypeIdent:ident, $SampleTypeIdent:ident,
$Sample:expr $Sample:expr
) => { ) => {
(*$Sample as f64 (*$Sample as f64 / ::std::$SampleTypeIdent::MAX as f64) as f32
/ ::std::$SampleTypeIdent::MAX as f64) as f32
}; };
($AsioTypeIdent:ident, ($AsioTypeIdent:ident,
f64, f64,
$SampleTypeIdent:ident, $SampleTypeIdent:ident,
$Sample:expr $Sample:expr
) => { ) => {
*$Sample as f64 *$Sample as f64 / ::std::$SampleTypeIdent::MAX as f64
/ ::std::$SampleTypeIdent::MAX as f64
}; };
($AsioTypeIdent:ident, ($AsioTypeIdent:ident,
$AsioType:ty, $AsioType:ty,
@ -581,9 +575,6 @@ impl EventLoop {
}; };
}; };
// Theres only a single callback because theres only one event loop
match callbacks.as_mut() {
Some(callback) => {
macro_rules! try_callback { macro_rules! try_callback {
($SampleFormat:ident, ($SampleFormat:ident,
$SampleType:ty, $SampleType:ty,
@ -609,11 +600,9 @@ impl EventLoop {
StreamData::Output { StreamData::Output {
buffer: UnknownTypeOutputBuffer::$SampleFormat( buffer: UnknownTypeOutputBuffer::$SampleFormat(
::OutputBuffer { ::OutputBuffer {
target: Some( target: Some(super::super::OutputBuffer::Asio(
super::super::OutputBuffer::Asio(
buff, buff,
), )),
),
}, },
), ),
}, },
@ -632,26 +621,22 @@ impl EventLoop {
let silence = match index { let silence = match index {
0 => { 0 => {
if !sys::SILENCE_FIRST.load(Ordering::SeqCst) { if !sys::SILENCE_FIRST.load(Ordering::SeqCst) {
sys::SILENCE_FIRST sys::SILENCE_FIRST.store(true, Ordering::SeqCst);
.store(true, Ordering::SeqCst); sys::SILENCE_SECOND.store(false, Ordering::SeqCst);
sys::SILENCE_SECOND
.store(false, Ordering::SeqCst);
true true
} else { } else {
false false
} }
}, }
1 => { 1 => {
if !sys::SILENCE_SECOND.load(Ordering::SeqCst) { if !sys::SILENCE_SECOND.load(Ordering::SeqCst) {
sys::SILENCE_SECOND sys::SILENCE_SECOND.store(true, Ordering::SeqCst);
.store(true, Ordering::SeqCst); sys::SILENCE_FIRST.store(false, Ordering::SeqCst);
sys::SILENCE_FIRST
.store(false, Ordering::SeqCst);
true true
} else { } else {
false false
} }
}, }
_ => unreachable!(), _ => unreachable!(),
}; };
@ -659,16 +644,13 @@ impl EventLoop {
// the asio buffer // the asio buffer
for (i, channel) in my_buffers.channel.iter().enumerate() { for (i, channel) in my_buffers.channel.iter().enumerate() {
let buff_ptr = asio_stream.buffer_infos[i].buffers let buff_ptr = asio_stream.buffer_infos[i].buffers
[index as usize] [index as usize] as *mut $AsioType;
as *mut $AsioType;
let asio_buffer: &'static mut [$AsioType] = let asio_buffer: &'static mut [$AsioType] =
std::slice::from_raw_parts_mut( std::slice::from_raw_parts_mut(
buff_ptr, buff_ptr,
asio_stream.buffer_size as usize, asio_stream.buffer_size as usize,
); );
for (asio_s, cpal_s) in for (asio_s, cpal_s) in asio_buffer.iter_mut().zip(channel) {
asio_buffer.iter_mut().zip(channel)
{
if silence { if silence {
*asio_s = 0.0 as $AsioType; *asio_s = 0.0 as $AsioType;
} }
@ -801,10 +783,6 @@ impl EventLoop {
} }
_ => println!("unsupported format {:?}", stream_type), _ => println!("unsupported format {:?}", stream_type),
} }
}
None => return (),
}
}
}); });
// Create the stream paused // Create the stream paused
self.cpal_streams self.cpal_streams
@ -846,19 +824,9 @@ impl EventLoop {
} }
/// Destroy the cpal stream based on the ID. /// Destroy the cpal stream based on the ID.
/// If no cpal streams exist then destory the
/// ASIO streams and clean up
pub fn destroy_stream(&self, stream_id: StreamId) { pub fn destroy_stream(&self, stream_id: StreamId) {
let mut streams = self.cpal_streams.lock().unwrap(); let mut streams = self.cpal_streams.lock().unwrap();
streams.get_mut(stream_id.0).take(); streams.get_mut(stream_id.0).take();
let count = self.stream_count.fetch_sub(1, Ordering::SeqCst);
if count == 1 {
*self.asio_streams.lock().unwrap() = sys::AsioStreams {
output: None,
input: None,
};
sys::clean_up();
}
} }
/// Run the cpal callbacks /// Run the cpal callbacks
@ -868,9 +836,7 @@ impl EventLoop {
{ {
let callback: &mut (FnMut(StreamId, StreamData) + Send) = &mut callback; let callback: &mut (FnMut(StreamId, StreamData) + Send) = &mut callback;
// Transmute needed to convince the compiler that the callback has a static lifetime // Transmute needed to convince the compiler that the callback has a static lifetime
*self.callbacks *self.callbacks.lock().unwrap() = Some(unsafe { mem::transmute(callback) });
.lock()
.unwrap() = Some(unsafe { mem::transmute(callback) });
loop { loop {
// A sleep here to prevent the loop being // A sleep here to prevent the loop being
// removed in --release // removed in --release
@ -883,6 +849,10 @@ impl EventLoop {
/// Currently event loop is never dropped. /// Currently event loop is never dropped.
impl Drop for EventLoop { impl Drop for EventLoop {
fn drop(&mut self) { fn drop(&mut self) {
*self.asio_streams.lock().unwrap() = sys::AsioStreams {
output: None,
input: None,
};
sys::clean_up(); sys::clean_up();
} }
} }