Update ASIO host for addition of new stream `Data` type.
This commit is contained in:
parent
1b5cf579cb
commit
c0a28b5198
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue