Update wasapi and emscripten backends for SupportedStreamConfig private fields
This commit is contained in:
parent
009b796b7c
commit
9bf5664f7d
|
@ -3,8 +3,8 @@ extern crate parking_lot;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
|
BuildStreamError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
|
||||||
PauseStreamError, PlayStreamError, StreamError, SupportedStreamConfig,
|
PauseStreamError, PlayStreamError, SampleFormat, StreamConfig, StreamError,
|
||||||
SupportedStreamConfigsError,
|
SupportedStreamConfig, SupportedStreamConfigsError,
|
||||||
};
|
};
|
||||||
use traits::{DeviceTrait, HostTrait, StreamTrait};
|
use traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
|
|
||||||
|
@ -84,7 +84,8 @@ impl DeviceTrait for Device {
|
||||||
|
|
||||||
fn build_input_stream_raw<D, E>(
|
fn build_input_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -92,12 +93,13 @@ impl DeviceTrait for Device {
|
||||||
D: FnMut(&Data) + Send + 'static,
|
D: FnMut(&Data) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
Device::build_input_stream_raw(self, config, data_callback, error_callback)
|
Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_output_stream_raw<D, E>(
|
fn build_output_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -105,7 +107,7 @@ impl DeviceTrait for Device {
|
||||||
D: FnMut(&mut Data) + Send + 'static,
|
D: FnMut(&mut Data) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
Device::build_output_stream_raw(self, config, data_callback, error_callback)
|
Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ use PauseStreamError;
|
||||||
use PlayStreamError;
|
use PlayStreamError;
|
||||||
use Sample;
|
use Sample;
|
||||||
use SampleFormat;
|
use SampleFormat;
|
||||||
|
use StreamConfig;
|
||||||
use StreamError;
|
use StreamError;
|
||||||
use SupportedStreamConfig;
|
use SupportedStreamConfig;
|
||||||
|
|
||||||
|
@ -59,7 +60,8 @@ impl Stream {
|
||||||
impl Device {
|
impl Device {
|
||||||
pub fn build_input_stream_raw<D, E>(
|
pub fn build_input_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
mut data_callback: D,
|
mut data_callback: D,
|
||||||
_error_callback: E,
|
_error_callback: E,
|
||||||
) -> Result<Stream, BuildStreamError>
|
) -> Result<Stream, BuildStreamError>
|
||||||
|
@ -70,14 +72,14 @@ impl Device {
|
||||||
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.
|
||||||
let sample_format = super::device::convert_data_type(&stream_type)
|
let expected_sample_format = super::device::convert_data_type(&stream_type)
|
||||||
.ok_or(BuildStreamError::StreamConfigNotSupported)?;
|
.ok_or(BuildStreamError::StreamConfigNotSupported)?;
|
||||||
if config.sample_format != sample_format {
|
if sample_format != expected_sample_format {
|
||||||
return Err(BuildStreamError::StreamConfigNotSupported);
|
return Err(BuildStreamError::StreamConfigNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_channels = config.channels.clone();
|
let num_channels = config.channels.clone();
|
||||||
let buffer_size = self.get_or_create_input_stream(config)?;
|
let buffer_size = self.get_or_create_input_stream(config, sample_format)?;
|
||||||
let cpal_num_samples = buffer_size * num_channels as usize;
|
let cpal_num_samples = buffer_size * num_channels as usize;
|
||||||
|
|
||||||
// Create the buffer depending on the size of the data type.
|
// Create the buffer depending on the size of the data type.
|
||||||
|
@ -225,7 +227,8 @@ impl Device {
|
||||||
|
|
||||||
pub fn build_output_stream_raw<D, E>(
|
pub fn build_output_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
mut data_callback: D,
|
mut data_callback: D,
|
||||||
_error_callback: E,
|
_error_callback: E,
|
||||||
) -> Result<Stream, BuildStreamError>
|
) -> Result<Stream, BuildStreamError>
|
||||||
|
@ -236,14 +239,14 @@ impl Device {
|
||||||
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.
|
||||||
let sample_format = super::device::convert_data_type(&stream_type)
|
let expected_sample_format = super::device::convert_data_type(&stream_type)
|
||||||
.ok_or(BuildStreamError::StreamConfigNotSupported)?;
|
.ok_or(BuildStreamError::StreamConfigNotSupported)?;
|
||||||
if config.sample_format != sample_format {
|
if sample_format != expected_sample_format {
|
||||||
return Err(BuildStreamError::StreamConfigNotSupported);
|
return Err(BuildStreamError::StreamConfigNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_channels = config.channels.clone();
|
let num_channels = config.channels.clone();
|
||||||
let buffer_size = self.get_or_create_output_stream(config)?;
|
let buffer_size = self.get_or_create_output_stream(config, sample_format)?;
|
||||||
let cpal_num_samples = buffer_size * num_channels as usize;
|
let cpal_num_samples = buffer_size * num_channels as usize;
|
||||||
|
|
||||||
// Create buffers depending on data type.
|
// Create buffers depending on data type.
|
||||||
|
@ -438,12 +441,13 @@ impl Device {
|
||||||
/// On success, the buffer size of the stream is returned.
|
/// On success, the buffer size of the stream is returned.
|
||||||
fn get_or_create_input_stream(
|
fn get_or_create_input_stream(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
) -> Result<usize, BuildStreamError> {
|
) -> Result<usize, BuildStreamError> {
|
||||||
match self.default_input_config() {
|
match self.default_input_config() {
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
let num_asio_channels = f.channels;
|
let num_asio_channels = f.channels;
|
||||||
check_config(&self.driver, config, num_asio_channels)
|
check_config(&self.driver, config, sample_format, num_asio_channels)
|
||||||
}
|
}
|
||||||
Err(_) => Err(BuildStreamError::StreamConfigNotSupported),
|
Err(_) => Err(BuildStreamError::StreamConfigNotSupported),
|
||||||
}?;
|
}?;
|
||||||
|
@ -478,12 +482,13 @@ impl Device {
|
||||||
/// If there is no existing ASIO Output Stream it will be created.
|
/// If there is no existing ASIO Output Stream it will be created.
|
||||||
fn get_or_create_output_stream(
|
fn get_or_create_output_stream(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
) -> Result<usize, BuildStreamError> {
|
) -> Result<usize, BuildStreamError> {
|
||||||
match self.default_output_config() {
|
match self.default_output_config() {
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
let num_asio_channels = f.channels;
|
let num_asio_channels = f.channels;
|
||||||
check_config(&self.driver, config, num_asio_channels)
|
check_config(&self.driver, config, sample_format, num_asio_channels)
|
||||||
}
|
}
|
||||||
Err(_) => Err(BuildStreamError::StreamConfigNotSupported),
|
Err(_) => Err(BuildStreamError::StreamConfigNotSupported),
|
||||||
}?;
|
}?;
|
||||||
|
@ -581,13 +586,13 @@ impl AsioSample for f64 {
|
||||||
/// Checks sample rate, data type and then finally the number of channels.
|
/// Checks sample rate, data type and then finally the number of channels.
|
||||||
fn check_config(
|
fn check_config(
|
||||||
driver: &sys::Driver,
|
driver: &sys::Driver,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
num_asio_channels: u16,
|
num_asio_channels: u16,
|
||||||
) -> Result<(), BuildStreamError> {
|
) -> Result<(), BuildStreamError> {
|
||||||
let SupportedStreamConfig {
|
let StreamConfig {
|
||||||
channels,
|
channels,
|
||||||
sample_rate,
|
sample_rate,
|
||||||
sample_format,
|
|
||||||
} = config;
|
} = config;
|
||||||
// Try and set the sample rate to what the user selected.
|
// Try and set the sample rate to what the user selected.
|
||||||
let sample_rate = sample_rate.0.into();
|
let sample_rate = sample_rate.0.into();
|
||||||
|
|
|
@ -22,7 +22,8 @@ use crate::traits::{DeviceTrait, HostTrait, StreamTrait};
|
||||||
use crate::{
|
use crate::{
|
||||||
BackendSpecificError, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError,
|
BackendSpecificError, BuildStreamError, ChannelCount, Data, DefaultStreamConfigError,
|
||||||
DeviceNameError, DevicesError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate,
|
DeviceNameError, DevicesError, PauseStreamError, PlayStreamError, SampleFormat, SampleRate,
|
||||||
StreamError, SupportedStreamConfig, SupportedStreamConfigRange, SupportedStreamConfigsError,
|
StreamConfig, StreamError, SupportedStreamConfig, SupportedStreamConfigRange,
|
||||||
|
SupportedStreamConfigsError,
|
||||||
};
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
@ -104,7 +105,8 @@ impl DeviceTrait for Device {
|
||||||
|
|
||||||
fn build_input_stream_raw<D, E>(
|
fn build_input_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -112,12 +114,13 @@ impl DeviceTrait for Device {
|
||||||
D: FnMut(&Data) + Send + 'static,
|
D: FnMut(&Data) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
Device::build_input_stream_raw(self, config, data_callback, error_callback)
|
Device::build_input_stream_raw(self, config, sample_format, data_callback, error_callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_output_stream_raw<D, E>(
|
fn build_output_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -125,7 +128,7 @@ impl DeviceTrait for Device {
|
||||||
D: FnMut(&mut Data) + Send + 'static,
|
D: FnMut(&mut Data) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
Device::build_output_stream_raw(self, config, data_callback, error_callback)
|
Device::build_output_stream_raw(self, config, sample_format, data_callback, error_callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,15 +405,17 @@ impl From<coreaudio::Error> for BuildStreamError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a coreaudio AudioStreamBasicDescription from a CPAL Format.
|
// Create a coreaudio AudioStreamBasicDescription from a CPAL Format.
|
||||||
fn asbd_from_config(config: &SupportedStreamConfig) -> AudioStreamBasicDescription {
|
fn asbd_from_config(
|
||||||
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
|
) -> AudioStreamBasicDescription {
|
||||||
let n_channels = config.channels as usize;
|
let n_channels = config.channels as usize;
|
||||||
let sample_rate = config.sample_rate.0;
|
let sample_rate = config.sample_rate.0;
|
||||||
let bytes_per_channel = config.sample_format.sample_size();
|
let bytes_per_channel = sample_format.sample_size();
|
||||||
let bits_per_channel = bytes_per_channel * 8;
|
let bits_per_channel = bytes_per_channel * 8;
|
||||||
let bytes_per_frame = n_channels * bytes_per_channel;
|
let bytes_per_frame = n_channels * bytes_per_channel;
|
||||||
let frames_per_packet = 1;
|
let frames_per_packet = 1;
|
||||||
let bytes_per_packet = frames_per_packet * bytes_per_frame;
|
let bytes_per_packet = frames_per_packet * bytes_per_frame;
|
||||||
let sample_format = config.sample_format;
|
|
||||||
let format_flags = match sample_format {
|
let format_flags = match sample_format {
|
||||||
SampleFormat::F32 => (kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked) as u32,
|
SampleFormat::F32 => (kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked) as u32,
|
||||||
_ => kAudioFormatFlagIsPacked as u32,
|
_ => kAudioFormatFlagIsPacked as u32,
|
||||||
|
@ -475,7 +480,8 @@ fn audio_unit_from_device(device: &Device, input: bool) -> Result<AudioUnit, cor
|
||||||
impl Device {
|
impl Device {
|
||||||
fn build_input_stream_raw<D, E>(
|
fn build_input_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
mut data_callback: D,
|
mut data_callback: D,
|
||||||
_error_callback: E,
|
_error_callback: E,
|
||||||
) -> Result<Stream, BuildStreamError>
|
) -> Result<Stream, BuildStreamError>
|
||||||
|
@ -625,12 +631,11 @@ impl Device {
|
||||||
let mut audio_unit = audio_unit_from_device(self, true)?;
|
let mut audio_unit = audio_unit_from_device(self, true)?;
|
||||||
|
|
||||||
// Set the stream in interleaved mode.
|
// Set the stream in interleaved mode.
|
||||||
let asbd = asbd_from_config(config);
|
let asbd = asbd_from_config(config, sample_format);
|
||||||
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
|
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
|
||||||
|
|
||||||
// Register the callback that is being called by coreaudio whenever it needs data to be
|
// Register the callback that is being called by coreaudio whenever it needs data to be
|
||||||
// fed to the audio buffer.
|
// fed to the audio buffer.
|
||||||
let sample_format = config.sample_format;
|
|
||||||
let bytes_per_channel = sample_format.sample_size();
|
let bytes_per_channel = sample_format.sample_size();
|
||||||
type Args = render_callback::Args<data::Raw>;
|
type Args = render_callback::Args<data::Raw>;
|
||||||
audio_unit.set_input_callback(move |args: Args| unsafe {
|
audio_unit.set_input_callback(move |args: Args| unsafe {
|
||||||
|
@ -663,7 +668,8 @@ impl Device {
|
||||||
|
|
||||||
fn build_output_stream_raw<D, E>(
|
fn build_output_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
config: &SupportedStreamConfig,
|
config: &StreamConfig,
|
||||||
|
sample_format: SampleFormat,
|
||||||
mut data_callback: D,
|
mut data_callback: D,
|
||||||
_error_callback: E,
|
_error_callback: E,
|
||||||
) -> Result<Stream, BuildStreamError>
|
) -> Result<Stream, BuildStreamError>
|
||||||
|
@ -678,12 +684,11 @@ impl Device {
|
||||||
let element = Element::Output;
|
let element = Element::Output;
|
||||||
|
|
||||||
// Set the stream in interleaved mode.
|
// Set the stream in interleaved mode.
|
||||||
let asbd = asbd_from_config(config);
|
let asbd = asbd_from_config(config, sample_format);
|
||||||
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
|
audio_unit.set_property(kAudioUnitProperty_StreamFormat, scope, element, Some(&asbd))?;
|
||||||
|
|
||||||
// Register the callback that is being called by coreaudio whenever it needs data to be
|
// Register the callback that is being called by coreaudio whenever it needs data to be
|
||||||
// fed to the audio buffer.
|
// fed to the audio buffer.
|
||||||
let sample_format = config.sample_format;
|
|
||||||
let bytes_per_channel = sample_format.sample_size();
|
let bytes_per_channel = sample_format.sample_size();
|
||||||
type Args = render_callback::Args<data::Raw>;
|
type Args = render_callback::Args<data::Raw>;
|
||||||
audio_unit.set_render_callback(move |args: Args| unsafe {
|
audio_unit.set_render_callback(move |args: Args| unsafe {
|
||||||
|
|
Loading…
Reference in New Issue