From 6fbb701826e833ecf79a7e5e0337f47c6e47dde1 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 15 Jan 2020 17:21:11 +0100 Subject: [PATCH] Update CoreAudio backend for removal of `UnknownBufferType` --- asio-sys/Cargo.toml | 2 +- src/host/coreaudio/mod.rs | 156 +++++++++++++++++++++----------------- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/asio-sys/Cargo.toml b/asio-sys/Cargo.toml index 7a92552..4677411 100644 --- a/asio-sys/Cargo.toml +++ b/asio-sys/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["audio", "sound", "asio", "steinberg"] build = "build.rs" [target.'cfg(any(target_os = "windows"))'.build-dependencies] -bindgen = "0.42.0" +bindgen = "0.51.0" walkdir = "2" cc = "1.0.25" diff --git a/src/host/coreaudio/mod.rs b/src/host/coreaudio/mod.rs index 17af18b..aeef5af 100644 --- a/src/host/coreaudio/mod.rs +++ b/src/host/coreaudio/mod.rs @@ -1,35 +1,26 @@ extern crate coreaudio; extern crate core_foundation_sys; -use ChannelCount; -use BackendSpecificError; -use BuildStreamError; -use DefaultFormatError; -use DeviceNameError; -use DevicesError; -use Format; -use PauseStreamError; -use PlayStreamError; -use SupportedFormatsError; -use SampleFormat; -use SampleRate; -use StreamData; -use StreamError; -use SupportedFormat; -use UnknownTypeInputBuffer; -use UnknownTypeOutputBuffer; -use traits::{DeviceTrait, HostTrait, StreamTrait}; - -use std::ffi::CStr; -use std::fmt; -use std::mem; -use std::cell::RefCell; -use std::os::raw::c_char; -use std::ptr::null; -use std::slice; -use std::thread; -use std::time::Duration; - +use crate::{ + ChannelCount, + BackendSpecificError, + BuildStreamError, + DefaultFormatError, + DeviceNameError, + DevicesError, + Format, + InputData, + OutputData, + PauseStreamError, + PlayStreamError, + Sample, + SampleFormat, + SampleRate, + StreamError, + SupportedFormat, + SupportedFormatsError, +}; +use crate::traits::{DeviceTrait, HostTrait, StreamTrait}; use self::coreaudio::audio_unit::{AudioUnit, Scope, Element}; use self::coreaudio::audio_unit::render_callback::{self, data}; use self::coreaudio::sys::{ @@ -69,6 +60,15 @@ use self::core_foundation_sys::string::{ CFStringRef, CFStringGetCStringPtr, }; +use std::ffi::CStr; +use std::fmt; +use std::mem; +use std::cell::RefCell; +use std::os::raw::c_char; +use std::ptr::null; +use std::slice; +use std::thread; +use std::time::Duration; mod enumerate; @@ -131,11 +131,33 @@ impl DeviceTrait for Device { Device::default_output_format(self) } - fn build_input_stream(&self, format: &Format, data_callback: D, error_callback: E) -> Result where D: FnMut(StreamData) + Send + 'static, E: FnMut(StreamError) + Send + 'static { + fn build_input_stream( + &self, + format: &Format, + data_callback: D, + error_callback: E, + ) -> Result + where + T: Sample, + D: FnMut(InputData) + Send + 'static, + E: FnMut(StreamError) + Send + 'static, + { + assert_eq!(T::FORMAT, format.data_type); Device::build_input_stream(self, format, data_callback, error_callback) } - fn build_output_stream(&self, format: &Format, data_callback: D, error_callback: E) -> Result where D: FnMut(StreamData) + Send + 'static, E: FnMut(StreamError) + Send + 'static { + fn build_output_stream( + &self, + format: &Format, + data_callback: D, + error_callback: E, + ) -> Result + where + T: Sample, + D: FnMut(OutputData) + Send + 'static, + E: FnMut(StreamError) + Send + 'static, + { + assert_eq!(T::FORMAT, format.data_type); Device::build_output_stream(self, format, data_callback, error_callback) } } @@ -478,7 +500,17 @@ fn audio_unit_from_device(device: &Device, input: bool) -> Result(&self, format: &Format, mut data_callback: D, _error_callback: E) -> Result where D: FnMut(StreamData) + Send + 'static, E: FnMut(StreamError) + Send + 'static { + fn build_input_stream( + &self, + format: &Format, + mut data_callback: D, + _error_callback: E, + ) -> Result + where + T: Sample, + D: FnMut(InputData) + Send + 'static, + E: FnMut(StreamError) + Send + 'static, + { // The scope and element for working with a device's input stream. let scope = Scope::Output; let element = Element::Input; @@ -625,8 +657,7 @@ impl Device { // Register the callback that is being called by coreaudio whenever it needs data to be // fed to the audio buffer. - let sample_format = format.data_type; - let bytes_per_channel = format.data_type.sample_size(); + let bytes_per_channel = std::mem::size_of::(); type Args = render_callback::Args; audio_unit.set_input_callback(move |args: Args| unsafe { let ptr = (*args.data.data).mBuffers.as_ptr() as *const AudioBuffer; @@ -640,23 +671,10 @@ impl Device { mData: data } = buffers[0]; - // A small macro to simplify handling the callback for different sample types. - macro_rules! try_callback { - ($SampleFormat:ident, $SampleType:ty) => {{ - let data_len = (data_byte_size as usize / bytes_per_channel) as usize; - let data_slice = slice::from_raw_parts(data as *const $SampleType, data_len); - let unknown_type_buffer = UnknownTypeInputBuffer::$SampleFormat(::InputBuffer { buffer: data_slice }); - let stream_data = StreamData::Input { buffer: unknown_type_buffer }; - data_callback(stream_data); - }}; - } - - match sample_format { - SampleFormat::F32 => try_callback!(F32, f32), - SampleFormat::I16 => try_callback!(I16, i16), - SampleFormat::U16 => try_callback!(U16, u16), - } - + let data_len = (data_byte_size as usize / bytes_per_channel) as usize; + let data_slice = slice::from_raw_parts(data as *const T, data_len); + let input_data = InputData { buffer: data_slice }; + data_callback(input_data); Ok(()) })?; @@ -669,7 +687,17 @@ impl Device { })) } - fn build_output_stream(&self, format: &Format, mut data_callback: D, _error_callback: E) -> Result where D: FnMut(StreamData) + Send + 'static, E: FnMut(StreamError) + Send + 'static { + fn build_output_stream( + &self, + format: &Format, + mut data_callback: D, + _error_callback: E, + ) -> Result + where + T: Sample, + D: FnMut(OutputData) + Send + 'static, + E: FnMut(StreamError) + Send + 'static, + { let mut audio_unit = audio_unit_from_device(self, false)?; // The scope and element for working with a device's output stream. @@ -682,8 +710,7 @@ impl Device { // Register the callback that is being called by coreaudio whenever it needs data to be // fed to the audio buffer. - let sample_format = format.data_type; - let bytes_per_channel = format.data_type.sample_size(); + let bytes_per_channel = std::mem::size_of::(); type Args = render_callback::Args; audio_unit.set_render_callback(move |args: Args| unsafe { // If `run()` is currently running, then a callback will be available from this list. @@ -695,23 +722,10 @@ impl Device { mData: data } = (*args.data.data).mBuffers[0]; - // A small macro to simplify handling the callback for different sample types. - macro_rules! try_callback { - ($SampleFormat:ident, $SampleType:ty, $equilibrium:expr) => {{ - let data_len = (data_byte_size as usize / bytes_per_channel) as usize; - let data_slice = slice::from_raw_parts_mut(data as *mut $SampleType, data_len); - let unknown_type_buffer = UnknownTypeOutputBuffer::$SampleFormat(::OutputBuffer { buffer: data_slice }); - let stream_data = StreamData::Output { buffer: unknown_type_buffer }; - data_callback(stream_data); - }}; - } - - match sample_format { - SampleFormat::F32 => try_callback!(F32, f32, 0.0), - SampleFormat::I16 => try_callback!(I16, i16, 0), - SampleFormat::U16 => try_callback!(U16, u16, ::std::u16::MAX / 2), - } - + let data_len = (data_byte_size as usize / bytes_per_channel) as usize; + let data_slice = slice::from_raw_parts_mut(data as *mut T, data_len); + let output_data = OutputData { buffer: data_slice }; + data_callback(output_data); Ok(()) })?;