Update wasapi backend for stream format renaming
This commit is contained in:
parent
669aada98a
commit
e0da586f77
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
BackendSpecificError, Data, DefaultFormatError, DeviceNameError, DevicesError, Format,
|
BackendSpecificError, Data, DefaultStreamConfigError, DeviceNameError, DevicesError,
|
||||||
SampleFormat, SampleRate, SupportedFormat, SupportedFormatsError, COMMON_SAMPLE_RATES,
|
SampleFormat, SampleRate, SupportedStreamConfig, SupportedStreamConfigRange,
|
||||||
|
SupportedStreamConfigsError, COMMON_SAMPLE_RATES,
|
||||||
};
|
};
|
||||||
use std;
|
use std;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
@ -49,8 +50,8 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{traits::DeviceTrait, BuildStreamError, StreamError};
|
use crate::{traits::DeviceTrait, BuildStreamError, StreamError};
|
||||||
|
|
||||||
pub type SupportedInputFormats = std::vec::IntoIter<SupportedFormat>;
|
pub type SupportedInputConfigs = std::vec::IntoIter<SupportedStreamConfigRange>;
|
||||||
pub type SupportedOutputFormats = std::vec::IntoIter<SupportedFormat>;
|
pub type SupportedOutputConfigs = std::vec::IntoIter<SupportedStreamConfigRange>;
|
||||||
|
|
||||||
/// Wrapper because of that stupid decision to remove `Send` and `Sync` from raw pointers.
|
/// Wrapper because of that stupid decision to remove `Send` and `Sync` from raw pointers.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -67,37 +68,37 @@ pub struct Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceTrait for Device {
|
impl DeviceTrait for Device {
|
||||||
type SupportedInputFormats = SupportedInputFormats;
|
type SupportedInputConfigs = SupportedInputConfigs;
|
||||||
type SupportedOutputFormats = SupportedOutputFormats;
|
type SupportedOutputConfigs = SupportedOutputConfigs;
|
||||||
type Stream = Stream;
|
type Stream = Stream;
|
||||||
|
|
||||||
fn name(&self) -> Result<String, DeviceNameError> {
|
fn name(&self) -> Result<String, DeviceNameError> {
|
||||||
Device::name(self)
|
Device::name(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn supported_input_formats(
|
fn supported_input_configs(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Self::SupportedInputFormats, SupportedFormatsError> {
|
) -> Result<Self::SupportedInputConfigs, SupportedStreamConfigsError> {
|
||||||
Device::supported_input_formats(self)
|
Device::supported_input_configs(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn supported_output_formats(
|
fn supported_output_configs(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Self::SupportedOutputFormats, SupportedFormatsError> {
|
) -> Result<Self::SupportedOutputConfigs, SupportedStreamConfigsError> {
|
||||||
Device::supported_output_formats(self)
|
Device::supported_output_configs(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_input_format(&self) -> Result<Format, DefaultFormatError> {
|
fn default_input_config(&self) -> Result<SupportedStreamConfig, DefaultStreamConfigError> {
|
||||||
Device::default_input_format(self)
|
Device::default_input_config(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_output_format(&self) -> Result<Format, DefaultFormatError> {
|
fn default_output_config(&self) -> Result<SupportedStreamConfig, DefaultStreamConfigError> {
|
||||||
Device::default_output_format(self)
|
Device::default_output_config(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_input_stream_raw<D, E>(
|
fn build_input_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
format: &Format,
|
config: &SupportedStreamConfig,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -105,7 +106,7 @@ impl DeviceTrait for Device {
|
||||||
D: FnMut(&Data) + Send + 'static,
|
D: FnMut(&Data) + Send + 'static,
|
||||||
E: FnMut(StreamError) + Send + 'static,
|
E: FnMut(StreamError) + Send + 'static,
|
||||||
{
|
{
|
||||||
let stream_inner = self.build_input_stream_raw_inner(format)?;
|
let stream_inner = self.build_input_stream_raw_inner(config)?;
|
||||||
Ok(Stream::new_input(
|
Ok(Stream::new_input(
|
||||||
stream_inner,
|
stream_inner,
|
||||||
data_callback,
|
data_callback,
|
||||||
|
@ -115,7 +116,7 @@ impl DeviceTrait for Device {
|
||||||
|
|
||||||
fn build_output_stream_raw<D, E>(
|
fn build_output_stream_raw<D, E>(
|
||||||
&self,
|
&self,
|
||||||
format: &Format,
|
config: &SupportedStreamConfig,
|
||||||
data_callback: D,
|
data_callback: D,
|
||||||
error_callback: E,
|
error_callback: E,
|
||||||
) -> Result<Self::Stream, BuildStreamError>
|
) -> Result<Self::Stream, BuildStreamError>
|
||||||
|
@ -123,7 +124,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,
|
||||||
{
|
{
|
||||||
let stream_inner = self.build_output_stream_raw_inner(format)?;
|
let stream_inner = self.build_output_stream_raw_inner(config)?;
|
||||||
Ok(Stream::new_output(
|
Ok(Stream::new_output(
|
||||||
stream_inner,
|
stream_inner,
|
||||||
data_callback,
|
data_callback,
|
||||||
|
@ -214,7 +215,7 @@ unsafe fn data_flow_from_immendpoint(endpoint: *const IMMEndpoint) -> EDataFlow
|
||||||
pub unsafe fn is_format_supported(
|
pub unsafe fn is_format_supported(
|
||||||
client: *const IAudioClient,
|
client: *const IAudioClient,
|
||||||
waveformatex_ptr: *const mmreg::WAVEFORMATEX,
|
waveformatex_ptr: *const mmreg::WAVEFORMATEX,
|
||||||
) -> Result<bool, SupportedFormatsError> {
|
) -> Result<bool, SupportedStreamConfigsError> {
|
||||||
/*
|
/*
|
||||||
// `IsFormatSupported` checks whether the format is supported and fills
|
// `IsFormatSupported` checks whether the format is supported and fills
|
||||||
// a `WAVEFORMATEX`
|
// a `WAVEFORMATEX`
|
||||||
|
@ -258,7 +259,7 @@ pub unsafe fn is_format_supported(
|
||||||
// has been found, but not an exact match) so we also treat this as unsupported.
|
// has been found, but not an exact match) so we also treat this as unsupported.
|
||||||
match (result, check_result(result)) {
|
match (result, check_result(result)) {
|
||||||
(_, Err(ref e)) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
(_, Err(ref e)) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
||||||
Err(SupportedFormatsError::DeviceNotAvailable)
|
Err(SupportedStreamConfigsError::DeviceNotAvailable)
|
||||||
}
|
}
|
||||||
(_, Err(_)) => Ok(false),
|
(_, Err(_)) => Ok(false),
|
||||||
(winerror::S_FALSE, _) => Ok(false),
|
(winerror::S_FALSE, _) => Ok(false),
|
||||||
|
@ -291,11 +292,11 @@ pub unsafe fn is_format_supported(
|
||||||
// Get a cpal Format from a WAVEFORMATEX.
|
// Get a cpal Format from a WAVEFORMATEX.
|
||||||
unsafe fn format_from_waveformatex_ptr(
|
unsafe fn format_from_waveformatex_ptr(
|
||||||
waveformatex_ptr: *const mmreg::WAVEFORMATEX,
|
waveformatex_ptr: *const mmreg::WAVEFORMATEX,
|
||||||
) -> Option<Format> {
|
) -> Option<SupportedStreamConfig> {
|
||||||
fn cmp_guid(a: &GUID, b: &GUID) -> bool {
|
fn cmp_guid(a: &GUID, b: &GUID) -> bool {
|
||||||
a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 && a.Data4 == b.Data4
|
a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 && a.Data4 == b.Data4
|
||||||
}
|
}
|
||||||
let data_type = match (
|
let sample_format = match (
|
||||||
(*waveformatex_ptr).wBitsPerSample,
|
(*waveformatex_ptr).wBitsPerSample,
|
||||||
(*waveformatex_ptr).wFormatTag,
|
(*waveformatex_ptr).wFormatTag,
|
||||||
) {
|
) {
|
||||||
|
@ -315,10 +316,10 @@ unsafe fn format_from_waveformatex_ptr(
|
||||||
// Unknown data format returned by GetMixFormat.
|
// Unknown data format returned by GetMixFormat.
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let format = Format {
|
let format = SupportedStreamConfig {
|
||||||
channels: (*waveformatex_ptr).nChannels as _,
|
channels: (*waveformatex_ptr).nChannels as _,
|
||||||
sample_rate: SampleRate((*waveformatex_ptr).nSamplesPerSec),
|
sample_rate: SampleRate((*waveformatex_ptr).nSamplesPerSec),
|
||||||
data_type,
|
sample_format,
|
||||||
};
|
};
|
||||||
Some(format)
|
Some(format)
|
||||||
}
|
}
|
||||||
|
@ -433,7 +434,7 @@ impl Device {
|
||||||
// number of channels seems to be supported. Any more or less returns an invalid
|
// number of channels seems to be supported. Any more or less returns an invalid
|
||||||
// parameter error. Thus we just assume that the default number of channels is the only
|
// parameter error. Thus we just assume that the default number of channels is the only
|
||||||
// number supported.
|
// number supported.
|
||||||
fn supported_formats(&self) -> Result<SupportedInputFormats, SupportedFormatsError> {
|
fn supported_formats(&self) -> Result<SupportedInputConfigs, SupportedStreamConfigsError> {
|
||||||
// initializing COM because we call `CoTaskMemFree` to release the format.
|
// initializing COM because we call `CoTaskMemFree` to release the format.
|
||||||
com::com_initialized();
|
com::com_initialized();
|
||||||
|
|
||||||
|
@ -441,7 +442,7 @@ impl Device {
|
||||||
let lock = match self.ensure_future_audio_client() {
|
let lock = match self.ensure_future_audio_client() {
|
||||||
Ok(lock) => lock,
|
Ok(lock) => lock,
|
||||||
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
||||||
return Err(SupportedFormatsError::DeviceNotAvailable)
|
return Err(SupportedStreamConfigsError::DeviceNotAvailable)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let description = format!("{}", e);
|
let description = format!("{}", e);
|
||||||
|
@ -457,7 +458,7 @@ impl Device {
|
||||||
match check_result((*client).GetMixFormat(&mut default_waveformatex_ptr.0)) {
|
match check_result((*client).GetMixFormat(&mut default_waveformatex_ptr.0)) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
||||||
return Err(SupportedFormatsError::DeviceNotAvailable);
|
return Err(SupportedStreamConfigsError::DeviceNotAvailable);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let description = format!("{}", e);
|
let description = format!("{}", e);
|
||||||
|
@ -514,7 +515,8 @@ impl Device {
|
||||||
Some(fmt) => fmt,
|
Some(fmt) => fmt,
|
||||||
None => {
|
None => {
|
||||||
let description =
|
let description =
|
||||||
"could not create a `cpal::Format` from a `WAVEFORMATEX`".to_string();
|
"could not create a `cpal::SupportedStreamConfig` from a `WAVEFORMATEX`"
|
||||||
|
.to_string();
|
||||||
let err = BackendSpecificError { description };
|
let err = BackendSpecificError { description };
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
|
@ -522,13 +524,15 @@ impl Device {
|
||||||
let mut supported_formats = Vec::with_capacity(supported_sample_rates.len());
|
let mut supported_formats = Vec::with_capacity(supported_sample_rates.len());
|
||||||
for rate in supported_sample_rates {
|
for rate in supported_sample_rates {
|
||||||
format.sample_rate = SampleRate(rate as _);
|
format.sample_rate = SampleRate(rate as _);
|
||||||
supported_formats.push(SupportedFormat::from(format.clone()));
|
supported_formats.push(SupportedStreamConfigRange::from(format.clone()));
|
||||||
}
|
}
|
||||||
Ok(supported_formats.into_iter())
|
Ok(supported_formats.into_iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn supported_input_formats(&self) -> Result<SupportedInputFormats, SupportedFormatsError> {
|
pub fn supported_input_configs(
|
||||||
|
&self,
|
||||||
|
) -> Result<SupportedInputConfigs, SupportedStreamConfigsError> {
|
||||||
if self.data_flow() == eCapture {
|
if self.data_flow() == eCapture {
|
||||||
self.supported_formats()
|
self.supported_formats()
|
||||||
// If it's an output device, assume no input formats.
|
// If it's an output device, assume no input formats.
|
||||||
|
@ -537,9 +541,9 @@ impl Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn supported_output_formats(
|
pub fn supported_output_configs(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<SupportedOutputFormats, SupportedFormatsError> {
|
) -> Result<SupportedOutputConfigs, SupportedStreamConfigsError> {
|
||||||
if self.data_flow() == eRender {
|
if self.data_flow() == eRender {
|
||||||
self.supported_formats()
|
self.supported_formats()
|
||||||
// If it's an input device, assume no output formats.
|
// If it's an input device, assume no output formats.
|
||||||
|
@ -552,14 +556,14 @@ impl Device {
|
||||||
// processor to mix them together.
|
// processor to mix them together.
|
||||||
//
|
//
|
||||||
// One format is guaranteed to be supported, the one returned by `GetMixFormat`.
|
// One format is guaranteed to be supported, the one returned by `GetMixFormat`.
|
||||||
fn default_format(&self) -> Result<Format, DefaultFormatError> {
|
fn default_format(&self) -> Result<SupportedStreamConfig, DefaultStreamConfigError> {
|
||||||
// initializing COM because we call `CoTaskMemFree`
|
// initializing COM because we call `CoTaskMemFree`
|
||||||
com::com_initialized();
|
com::com_initialized();
|
||||||
|
|
||||||
let lock = match self.ensure_future_audio_client() {
|
let lock = match self.ensure_future_audio_client() {
|
||||||
Ok(lock) => lock,
|
Ok(lock) => lock,
|
||||||
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
||||||
return Err(DefaultFormatError::DeviceNotAvailable)
|
return Err(DefaultStreamConfigError::DeviceNotAvailable)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let description = format!("{}", e);
|
let description = format!("{}", e);
|
||||||
|
@ -573,7 +577,7 @@ impl Device {
|
||||||
let mut format_ptr = WaveFormatExPtr(ptr::null_mut());
|
let mut format_ptr = WaveFormatExPtr(ptr::null_mut());
|
||||||
match check_result((*client).GetMixFormat(&mut format_ptr.0)) {
|
match check_result((*client).GetMixFormat(&mut format_ptr.0)) {
|
||||||
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
|
||||||
return Err(DefaultFormatError::DeviceNotAvailable);
|
return Err(DefaultStreamConfigError::DeviceNotAvailable);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let description = format!("{}", e);
|
let description = format!("{}", e);
|
||||||
|
@ -584,7 +588,7 @@ impl Device {
|
||||||
};
|
};
|
||||||
|
|
||||||
format_from_waveformatex_ptr(format_ptr.0)
|
format_from_waveformatex_ptr(format_ptr.0)
|
||||||
.ok_or(DefaultFormatError::StreamTypeNotSupported)
|
.ok_or(DefaultStreamConfigError::StreamTypeNotSupported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,26 +597,26 @@ impl Device {
|
||||||
endpoint.data_flow()
|
endpoint.data_flow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_input_format(&self) -> Result<Format, DefaultFormatError> {
|
pub fn default_input_config(&self) -> Result<SupportedStreamConfig, DefaultStreamConfigError> {
|
||||||
if self.data_flow() == eCapture {
|
if self.data_flow() == eCapture {
|
||||||
self.default_format()
|
self.default_format()
|
||||||
} else {
|
} else {
|
||||||
Err(DefaultFormatError::StreamTypeNotSupported)
|
Err(DefaultStreamConfigError::StreamTypeNotSupported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_output_format(&self) -> Result<Format, DefaultFormatError> {
|
pub fn default_output_config(&self) -> Result<SupportedStreamConfig, DefaultStreamConfigError> {
|
||||||
let data_flow = self.data_flow();
|
let data_flow = self.data_flow();
|
||||||
if data_flow == eRender {
|
if data_flow == eRender {
|
||||||
self.default_format()
|
self.default_format()
|
||||||
} else {
|
} else {
|
||||||
Err(DefaultFormatError::StreamTypeNotSupported)
|
Err(DefaultStreamConfigError::StreamTypeNotSupported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_input_stream_raw_inner(
|
pub(crate) fn build_input_stream_raw_inner(
|
||||||
&self,
|
&self,
|
||||||
format: &Format,
|
format: &SupportedStreamConfig,
|
||||||
) -> Result<StreamInner, BuildStreamError> {
|
) -> Result<StreamInner, BuildStreamError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Making sure that COM is initialized.
|
// Making sure that COM is initialized.
|
||||||
|
@ -749,14 +753,14 @@ impl Device {
|
||||||
playing: false,
|
playing: false,
|
||||||
max_frames_in_buffer,
|
max_frames_in_buffer,
|
||||||
bytes_per_frame: waveformatex.nBlockAlign,
|
bytes_per_frame: waveformatex.nBlockAlign,
|
||||||
sample_format: format.data_type,
|
sample_format: format.sample_format,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_output_stream_raw_inner(
|
pub(crate) fn build_output_stream_raw_inner(
|
||||||
&self,
|
&self,
|
||||||
format: &Format,
|
format: &SupportedStreamConfig,
|
||||||
) -> Result<StreamInner, BuildStreamError> {
|
) -> Result<StreamInner, BuildStreamError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Making sure that COM is initialized.
|
// Making sure that COM is initialized.
|
||||||
|
@ -893,7 +897,7 @@ impl Device {
|
||||||
playing: false,
|
playing: false,
|
||||||
max_frames_in_buffer,
|
max_frames_in_buffer,
|
||||||
bytes_per_frame: waveformatex.nBlockAlign,
|
bytes_per_frame: waveformatex.nBlockAlign,
|
||||||
sample_format: format.data_type,
|
sample_format: format.sample_format,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1141,19 +1145,21 @@ pub fn default_output_device() -> Option<Device> {
|
||||||
// Turns a `Format` into a `WAVEFORMATEXTENSIBLE`.
|
// Turns a `Format` into a `WAVEFORMATEXTENSIBLE`.
|
||||||
//
|
//
|
||||||
// Returns `None` if the WAVEFORMATEXTENSIBLE does not support the given format.
|
// Returns `None` if the WAVEFORMATEXTENSIBLE does not support the given format.
|
||||||
fn format_to_waveformatextensible(format: &Format) -> Option<mmreg::WAVEFORMATEXTENSIBLE> {
|
fn format_to_waveformatextensible(
|
||||||
let format_tag = match format.data_type {
|
config: &SupportedStreamConfig,
|
||||||
|
) -> Option<mmreg::WAVEFORMATEXTENSIBLE> {
|
||||||
|
let format_tag = match config.sample_format {
|
||||||
SampleFormat::I16 => mmreg::WAVE_FORMAT_PCM,
|
SampleFormat::I16 => mmreg::WAVE_FORMAT_PCM,
|
||||||
SampleFormat::F32 => mmreg::WAVE_FORMAT_EXTENSIBLE,
|
SampleFormat::F32 => mmreg::WAVE_FORMAT_EXTENSIBLE,
|
||||||
SampleFormat::U16 => return None,
|
SampleFormat::U16 => return None,
|
||||||
};
|
};
|
||||||
let channels = format.channels as WORD;
|
let channels = config.channels as WORD;
|
||||||
let sample_rate = format.sample_rate.0 as DWORD;
|
let sample_rate = config.sample_rate.0 as DWORD;
|
||||||
let sample_bytes = format.data_type.sample_size() as WORD;
|
let sample_bytes = config.sample_format.sample_size() as WORD;
|
||||||
let avg_bytes_per_sec = u32::from(channels) * sample_rate * u32::from(sample_bytes);
|
let avg_bytes_per_sec = u32::from(channels) * sample_rate * u32::from(sample_bytes);
|
||||||
let block_align = channels * sample_bytes;
|
let block_align = channels * sample_bytes;
|
||||||
let bits_per_sample = 8 * sample_bytes;
|
let bits_per_sample = 8 * sample_bytes;
|
||||||
let cb_size = match format.data_type {
|
let cb_size = match config.sample_format {
|
||||||
SampleFormat::I16 => 0,
|
SampleFormat::I16 => 0,
|
||||||
SampleFormat::F32 => {
|
SampleFormat::F32 => {
|
||||||
let extensible_size = mem::size_of::<mmreg::WAVEFORMATEXTENSIBLE>();
|
let extensible_size = mem::size_of::<mmreg::WAVEFORMATEXTENSIBLE>();
|
||||||
|
@ -1177,7 +1183,7 @@ fn format_to_waveformatextensible(format: &Format) -> Option<mmreg::WAVEFORMATEX
|
||||||
const KSAUDIO_SPEAKER_DIRECTOUT: DWORD = 0;
|
const KSAUDIO_SPEAKER_DIRECTOUT: DWORD = 0;
|
||||||
let channel_mask = KSAUDIO_SPEAKER_DIRECTOUT;
|
let channel_mask = KSAUDIO_SPEAKER_DIRECTOUT;
|
||||||
|
|
||||||
let sub_format = match format.data_type {
|
let sub_format = match config.sample_format {
|
||||||
SampleFormat::I16 => ksmedia::KSDATAFORMAT_SUBTYPE_PCM,
|
SampleFormat::I16 => ksmedia::KSDATAFORMAT_SUBTYPE_PCM,
|
||||||
SampleFormat::F32 => ksmedia::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
|
SampleFormat::F32 => ksmedia::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT,
|
||||||
SampleFormat::U16 => return None,
|
SampleFormat::U16 => return None,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
extern crate winapi;
|
extern crate winapi;
|
||||||
|
|
||||||
pub use self::device::{
|
pub use self::device::{
|
||||||
default_input_device, default_output_device, Device, Devices, SupportedInputFormats,
|
default_input_device, default_output_device, Device, Devices, SupportedInputConfigs,
|
||||||
SupportedOutputFormats,
|
SupportedOutputConfigs,
|
||||||
};
|
};
|
||||||
pub use self::stream::Stream;
|
pub use self::stream::Stream;
|
||||||
use self::winapi::um::winnt::HRESULT;
|
use self::winapi::um::winnt::HRESULT;
|
||||||
|
|
Loading…
Reference in New Issue