diff --git a/src/alsa/mod.rs b/src/alsa/mod.rs index 969dc14..1c8006e 100644 --- a/src/alsa/mod.rs +++ b/src/alsa/mod.rs @@ -313,8 +313,7 @@ impl Device { return Err(DefaultFormatError::StreamTypeNotSupported); } Err(SupportedFormatsError::BackendSpecific { err }) => { - unimplemented!(); - //return Err(err.into()); + return Err(err.into()); } Ok(fmts) => fmts.collect(), } diff --git a/src/coreaudio/mod.rs b/src/coreaudio/mod.rs index 828db72..feff675 100644 --- a/src/coreaudio/mod.rs +++ b/src/coreaudio/mod.rs @@ -224,18 +224,25 @@ impl Device { scope: AudioObjectPropertyScope, ) -> Result { - fn default_format_error_from_os_status(status: OSStatus) -> Option { + fn default_format_error_from_os_status(status: OSStatus) -> Result<(), DefaultFormatError> { let err = match coreaudio::Error::from_os_status(status) { Err(err) => err, - Ok(_) => return None, + Ok(_) => return Ok(()), }; match err { - coreaudio::Error::RenderCallbackBufferFormatDoesNotMatchAudioUnitStreamFormat | - coreaudio::Error::NoKnownSubtype | coreaudio::Error::AudioUnit(coreaudio::error::AudioUnitError::FormatNotSupported) | coreaudio::Error::AudioCodec(_) | - coreaudio::Error::AudioFormat(_) => Some(DefaultFormatError::StreamTypeNotSupported), - _ => Some(DefaultFormatError::DeviceNotAvailable), + coreaudio::Error::AudioFormat(_) => { + 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 _, &asbd as *const _ as *mut _, ); - - if status != kAudioHardwareNoError as i32 { - let err = default_format_error_from_os_status(status) - .expect("no known error for OSStatus"); - return Err(err); - } + default_format_error_from_os_status(status)?; let sample_format = { let audio_format = coreaudio::audio_unit::AudioFormat::from_format_and_flag( diff --git a/src/lib.rs b/src/lib.rs index 4f717ac..adeda83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -347,6 +347,12 @@ pub enum DefaultFormatError { /// 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.")] 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`. @@ -765,6 +771,12 @@ impl From for SupportedFormatsError { } } +impl From 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 // of commonly used rates. This is always the case for wasapi and is sometimes the case for alsa. // diff --git a/src/wasapi/device.rs b/src/wasapi/device.rs index ded0722..2cac6aa 100644 --- a/src/wasapi/device.rs +++ b/src/wasapi/device.rs @@ -522,9 +522,15 @@ impl Device { com::com_initialized(); let lock = match self.ensure_future_audio_client() { - Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => - return Err(DefaultFormatError::DeviceNotAvailable), - e => e.unwrap(), + Ok(lock) => lock, + Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => { + return Err(DefaultFormatError::DeviceNotAvailable) + } + Err(e) => { + let description = format!("{}", e); + let err = BackendSpecificError { description }; + return Err(err.into()); + } }; let client = lock.unwrap().0; @@ -534,7 +540,11 @@ impl Device { Err(ref e) if e.raw_os_error() == Some(AUDCLNT_E_DEVICE_INVALIDATED) => { return Err(DefaultFormatError::DeviceNotAvailable); }, - Err(e) => panic!("{:?}", e), + Err(e) => { + let description = format!("{}", e); + let err = BackendSpecificError { description }; + return Err(err.into()); + }, Ok(()) => (), };