Improve handling of the `DefaultFormatError`

This commit is contained in:
mitchmindtree 2019-06-21 01:34:07 +02:00
parent fbb97f51ef
commit f0e4e312c1
4 changed files with 41 additions and 18 deletions

View File

@ -313,8 +313,7 @@ impl Device {
return Err(DefaultFormatError::StreamTypeNotSupported); return Err(DefaultFormatError::StreamTypeNotSupported);
} }
Err(SupportedFormatsError::BackendSpecific { err }) => { Err(SupportedFormatsError::BackendSpecific { err }) => {
unimplemented!(); return Err(err.into());
//return Err(err.into());
} }
Ok(fmts) => fmts.collect(), Ok(fmts) => fmts.collect(),
} }

View File

@ -224,18 +224,25 @@ impl Device {
scope: AudioObjectPropertyScope, scope: AudioObjectPropertyScope,
) -> Result<Format, DefaultFormatError> ) -> Result<Format, DefaultFormatError>
{ {
fn default_format_error_from_os_status(status: OSStatus) -> Option<DefaultFormatError> { fn default_format_error_from_os_status(status: OSStatus) -> Result<(), DefaultFormatError> {
let err = match coreaudio::Error::from_os_status(status) { let err = match coreaudio::Error::from_os_status(status) {
Err(err) => err, Err(err) => err,
Ok(_) => return None, Ok(_) => return Ok(()),
}; };
match err { match err {
coreaudio::Error::RenderCallbackBufferFormatDoesNotMatchAudioUnitStreamFormat |
coreaudio::Error::NoKnownSubtype |
coreaudio::Error::AudioUnit(coreaudio::error::AudioUnitError::FormatNotSupported) | coreaudio::Error::AudioUnit(coreaudio::error::AudioUnitError::FormatNotSupported) |
coreaudio::Error::AudioCodec(_) | coreaudio::Error::AudioCodec(_) |
coreaudio::Error::AudioFormat(_) => Some(DefaultFormatError::StreamTypeNotSupported), coreaudio::Error::AudioFormat(_) => {
_ => Some(DefaultFormatError::DeviceNotAvailable), Err(DefaultFormatError::StreamTypeNotSupported)
}
coreaudio::Error::AudioUnit(coreaudio::error::AudioUnitError::NoConnection) => {
Err(DefaultFormatError::DeviceNotAvailable)
}
err => {
let description = format!("{}", std::error::Error::description(&err));
let err = BackendSpecificError { description };
Err(err.into())
}
} }
} }
@ -256,12 +263,7 @@ impl Device {
&data_size as *const _ as *mut _, &data_size as *const _ as *mut _,
&asbd as *const _ as *mut _, &asbd as *const _ as *mut _,
); );
default_format_error_from_os_status(status)?;
if status != kAudioHardwareNoError as i32 {
let err = default_format_error_from_os_status(status)
.expect("no known error for OSStatus");
return Err(err);
}
let sample_format = { let sample_format = {
let audio_format = coreaudio::audio_unit::AudioFormat::from_format_and_flag( let audio_format = coreaudio::audio_unit::AudioFormat::from_format_and_flag(

View File

@ -347,6 +347,12 @@ pub enum DefaultFormatError {
/// Returned if e.g. the default input format was requested on an output-only audio device. /// Returned if e.g. the default input format was requested on an output-only audio device.
#[fail(display = "The requested stream type is not supported by the device.")] #[fail(display = "The requested stream type is not supported by the device.")]
StreamTypeNotSupported, StreamTypeNotSupported,
/// See the `BackendSpecificError` docs for more information about this error variant.
#[fail(display = "{}", err)]
BackendSpecific {
#[fail(cause)]
err: BackendSpecificError,
}
} }
/// Error that can happen when creating a `Stream`. /// Error that can happen when creating a `Stream`.
@ -765,6 +771,12 @@ impl From<BackendSpecificError> for SupportedFormatsError {
} }
} }
impl From<BackendSpecificError> for DefaultFormatError {
fn from(err: BackendSpecificError) -> Self {
DefaultFormatError::BackendSpecific { err }
}
}
// If a backend does not provide an API for retrieving supported formats, we query it with a bunch // If a backend does not provide an API for retrieving supported formats, we query it with a bunch
// of commonly used rates. This is always the case for wasapi and is sometimes the case for alsa. // of commonly used rates. This is always the case for wasapi and is sometimes the case for alsa.
// //

View File

@ -522,9 +522,15 @@ impl Device {
com::com_initialized(); com::com_initialized();
let lock = match self.ensure_future_audio_client() { let lock = match self.ensure_future_audio_client() {
Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => Ok(lock) => lock,
return Err(DefaultFormatError::DeviceNotAvailable), Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => {
e => e.unwrap(), return Err(DefaultFormatError::DeviceNotAvailable)
}
Err(e) => {
let description = format!("{}", e);
let err = BackendSpecificError { description };
return Err(err.into());
}
}; };
let client = lock.unwrap().0; let client = lock.unwrap().0;
@ -534,7 +540,11 @@ impl Device {
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(DefaultFormatError::DeviceNotAvailable);
}, },
Err(e) => panic!("{:?}", e), Err(e) => {
let description = format!("{}", e);
let err = BackendSpecificError { description };
return Err(err.into());
},
Ok(()) => (), Ok(()) => (),
}; };