Update ASIO host for addition of new stream `Data` type.

This commit is contained in:
mitchmindtree 2020-01-19 19:26:23 +01:00
parent 1b5cf579cb
commit c0a28b5198
2 changed files with 32 additions and 36 deletions

View File

@ -3,15 +3,13 @@ extern crate parking_lot;
use crate::{ use crate::{
BuildStreamError, BuildStreamError,
Data,
DefaultFormatError, DefaultFormatError,
DeviceNameError, DeviceNameError,
DevicesError, DevicesError,
Format, Format,
InputData,
OutputData,
PauseStreamError, PauseStreamError,
PlayStreamError, PlayStreamError,
Sample,
StreamError, StreamError,
SupportedFormatsError, SupportedFormatsError,
}; };
@ -91,29 +89,27 @@ impl DeviceTrait for Device {
Device::default_output_format(self) Device::default_output_format(self)
} }
fn build_input_stream<T, D, E>( fn build_input_stream<D, E>(
&self, &self,
format: &Format, format: &Format,
data_callback: D, data_callback: D,
error_callback: E, error_callback: E,
) -> Result<Self::Stream, BuildStreamError> ) -> Result<Self::Stream, BuildStreamError>
where where
T: Sample, D: FnMut(&Data) + Send + 'static,
D: FnMut(InputData<T>) + Send + 'static,
E: FnMut(StreamError) + Send + 'static E: FnMut(StreamError) + Send + 'static
{ {
Device::build_input_stream(self, format, data_callback, error_callback) Device::build_input_stream(self, format, data_callback, error_callback)
} }
fn build_output_stream<T, D, E>( fn build_output_stream<D, E>(
&self, &self,
format: &Format, format: &Format,
data_callback: D, data_callback: D,
error_callback: E, error_callback: E,
) -> Result<Self::Stream, BuildStreamError> ) -> Result<Self::Stream, BuildStreamError>
where where
T: Sample, D: FnMut(&mut Data) + Send + 'static,
D: FnMut(OutputData<T>) + Send + 'static,
E: FnMut(StreamError) + Send + 'static E: FnMut(StreamError) + Send + 'static
{ {
Device::build_output_stream(self, format, data_callback, error_callback) Device::build_output_stream(self, format, data_callback, error_callback)

View File

@ -9,9 +9,8 @@ use std::sync::Arc;
use super::parking_lot::Mutex; use super::parking_lot::Mutex;
use BackendSpecificError; use BackendSpecificError;
use BuildStreamError; use BuildStreamError;
use Data;
use Format; use Format;
use InputData;
use OutputData;
use PauseStreamError; use PauseStreamError;
use PlayStreamError; use PlayStreamError;
use Sample; use Sample;
@ -58,18 +57,16 @@ impl Stream {
} }
impl Device { impl Device {
pub fn build_input_stream<T, D, E>( pub fn build_input_stream<D, E>(
&self, &self,
format: &Format, format: &Format,
mut data_callback: D, mut data_callback: D,
_error_callback: E, _error_callback: E,
) -> Result<Stream, BuildStreamError> ) -> Result<Stream, BuildStreamError>
where where
T: Sample, D: FnMut(&Data) + Send + 'static,
D: FnMut(InputData<T>) + Send + 'static,
E: FnMut(StreamError) + Send + 'static, E: FnMut(StreamError) + Send + 'static,
{ {
assert_eq!(format.data_type, T::FORMAT, "sample type does not match `format.data_type`");
let stream_type = self.driver.input_data_type().map_err(build_stream_err)?; let stream_type = self.driver.input_data_type().map_err(build_stream_err)?;
// Ensure that the desired sample type is supported. // Ensure that the desired sample type is supported.
@ -118,7 +115,7 @@ impl Device {
where where
A: AsioSample, A: AsioSample,
B: Sample, B: Sample,
D: FnMut(InputData<B>) + Send + 'static, D: FnMut(&Data) + Send + 'static,
F: Fn(A) -> A, F: Fn(A) -> A,
{ {
// 1. Write the ASIO channels to the CPAL buffer. // 1. Write the ASIO channels to the CPAL buffer.
@ -132,13 +129,15 @@ impl Device {
} }
// 2. Deliver the interleaved buffer to the callback. // 2. Deliver the interleaved buffer to the callback.
let data = InputData { buffer: interleaved }; let data = interleaved.as_mut_ptr() as *mut ();
callback(data); let len = interleaved.len();
let data = Data::from_parts(data, len, B::FORMAT);
callback(&data);
} }
match (&stream_type, data_type) { match (&stream_type, data_type) {
(&sys::AsioSampleType::ASIOSTInt16LSB, SampleFormat::I16) => { (&sys::AsioSampleType::ASIOSTInt16LSB, SampleFormat::I16) => {
process_input_callback::<i16, T, _, _>( process_input_callback::<i16, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -147,7 +146,7 @@ impl Device {
); );
} }
(&sys::AsioSampleType::ASIOSTInt16MSB, SampleFormat::I16) => { (&sys::AsioSampleType::ASIOSTInt16MSB, SampleFormat::I16) => {
process_input_callback::<i16, T, _, _>( process_input_callback::<i16, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -160,7 +159,7 @@ impl Device {
// trait for the `to_le` and `to_be` methods, but this does not support floats. // trait for the `to_le` and `to_be` methods, but this does not support floats.
(&sys::AsioSampleType::ASIOSTFloat32LSB, SampleFormat::F32) | (&sys::AsioSampleType::ASIOSTFloat32LSB, SampleFormat::F32) |
(&sys::AsioSampleType::ASIOSTFloat32MSB, SampleFormat::F32) => { (&sys::AsioSampleType::ASIOSTFloat32MSB, SampleFormat::F32) => {
process_input_callback::<f32, T, _, _>( process_input_callback::<f32, f32, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -173,7 +172,7 @@ impl Device {
// `process_output_callback` function above by removing the unnecessary sample // `process_output_callback` function above by removing the unnecessary sample
// conversion function. // conversion function.
(&sys::AsioSampleType::ASIOSTInt32LSB, SampleFormat::I16) => { (&sys::AsioSampleType::ASIOSTInt32LSB, SampleFormat::I16) => {
process_input_callback::<i32, T, _, _>( process_input_callback::<i32, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -182,7 +181,7 @@ impl Device {
); );
} }
(&sys::AsioSampleType::ASIOSTInt32MSB, SampleFormat::I16) => { (&sys::AsioSampleType::ASIOSTInt32MSB, SampleFormat::I16) => {
process_input_callback::<i32, T, _, _>( process_input_callback::<i32, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -194,7 +193,7 @@ impl Device {
// trait for the `to_le` and `to_be` methods, but this does not support floats. // trait for the `to_le` and `to_be` methods, but this does not support floats.
(&sys::AsioSampleType::ASIOSTFloat64LSB, SampleFormat::F32) | (&sys::AsioSampleType::ASIOSTFloat64LSB, SampleFormat::F32) |
(&sys::AsioSampleType::ASIOSTFloat64MSB, SampleFormat::F32) => { (&sys::AsioSampleType::ASIOSTFloat64MSB, SampleFormat::F32) => {
process_input_callback::<f64, T, _, _>( process_input_callback::<f64, f32, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
asio_stream, asio_stream,
@ -224,18 +223,16 @@ impl Device {
}) })
} }
pub fn build_output_stream<T, D, E>( pub fn build_output_stream<D, E>(
&self, &self,
format: &Format, format: &Format,
mut data_callback: D, mut data_callback: D,
_error_callback: E, _error_callback: E,
) -> Result<Stream, BuildStreamError> ) -> Result<Stream, BuildStreamError>
where where
T: Sample, D: FnMut(&mut Data) + Send + 'static,
D: FnMut(OutputData<T>) + Send + 'static,
E: FnMut(StreamError) + Send + 'static, E: FnMut(StreamError) + Send + 'static,
{ {
assert_eq!(format.data_type, T::FORMAT, "sample type does not match `format.data_type`");
let stream_type = self.driver.output_data_type().map_err(build_stream_err)?; let stream_type = self.driver.output_data_type().map_err(build_stream_err)?;
// Ensure that the desired sample type is supported. // Ensure that the desired sample type is supported.
@ -308,12 +305,15 @@ impl Device {
where where
A: Sample, A: Sample,
B: AsioSample, B: AsioSample,
D: FnMut(OutputData<A>) + Send + 'static, D: FnMut(&mut Data) + Send + 'static,
F: Fn(B) -> B, F: Fn(B) -> B,
{ {
// 1. Render interleaved buffer from callback. // 1. Render interleaved buffer from callback.
let interleaved: &mut [A] = cast_slice_mut(interleaved); let interleaved: &mut [A] = cast_slice_mut(interleaved);
callback(OutputData { buffer: interleaved }); let data = interleaved.as_mut_ptr() as *mut ();
let len = interleaved.len();
let mut data = Data::from_parts(data, len, A::FORMAT);
callback(&mut data);
// 2. Silence ASIO channels if necessary. // 2. Silence ASIO channels if necessary.
let n_channels = interleaved.len() / asio_stream.buffer_size as usize; let n_channels = interleaved.len() / asio_stream.buffer_size as usize;
@ -337,7 +337,7 @@ impl Device {
match (data_type, &stream_type) { match (data_type, &stream_type) {
(SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt16LSB) => { (SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt16LSB) => {
process_output_callback::<T, i16, _, _>( process_output_callback::<i16, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,
@ -347,7 +347,7 @@ impl Device {
); );
} }
(SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt16MSB) => { (SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt16MSB) => {
process_output_callback::<T, i16, _, _>( process_output_callback::<i16, i16, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,
@ -361,7 +361,7 @@ impl Device {
// trait for the `to_le` and `to_be` methods, but this does not support floats. // trait for the `to_le` and `to_be` methods, but this does not support floats.
(SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat32LSB) | (SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat32LSB) |
(SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat32MSB) => { (SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat32MSB) => {
process_output_callback::<T, f32, _, _>( process_output_callback::<f32, f32, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,
@ -375,7 +375,7 @@ impl Device {
// `process_output_callback` function above by removing the unnecessary sample // `process_output_callback` function above by removing the unnecessary sample
// conversion function. // conversion function.
(SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt32LSB) => { (SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt32LSB) => {
process_output_callback::<T, i32, _, _>( process_output_callback::<i16, i32, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,
@ -385,7 +385,7 @@ impl Device {
); );
} }
(SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt32MSB) => { (SampleFormat::I16, &sys::AsioSampleType::ASIOSTInt32MSB) => {
process_output_callback::<T, i32, _, _>( process_output_callback::<i16, i32, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,
@ -398,7 +398,7 @@ impl Device {
// trait for the `to_le` and `to_be` methods, but this does not support floats. // trait for the `to_le` and `to_be` methods, but this does not support floats.
(SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat64LSB) | (SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat64LSB) |
(SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat64MSB) => { (SampleFormat::F32, &sys::AsioSampleType::ASIOSTFloat64MSB) => {
process_output_callback::<T, f64, _, _>( process_output_callback::<f32, f64, _, _>(
&mut data_callback, &mut data_callback,
&mut interleaved, &mut interleaved,
silence, silence,