Fix #322 - Refactored audio output device enumeration to fail gracefully when audio devices with null or otherwise unusable names are encountered

This commit is contained in:
Ben Wallis 2020-06-07 16:00:31 +01:00
parent ea414f6921
commit 1d564f53c7
2 changed files with 19 additions and 8 deletions

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- new tail bone for quad_small body - new tail bone for quad_small body
- slim the game size through lossless asset optimization - slim the game size through lossless asset optimization
- Lanterns now stop glowing if you throw a lit one out of your inventory - Lanterns now stop glowing if you throw a lit one out of your inventory
- Fixed a crash caused by certain audio devices on OSX
### Removed ### Removed

View File

@ -239,7 +239,10 @@ impl AudioFrontend {
/// Returns the default audio device. /// Returns the default audio device.
/// Does not return rodio Device struct in case our audio backend changes. /// Does not return rodio Device struct in case our audio backend changes.
pub fn get_default_device() -> Option<String> { pub fn get_default_device() -> Option<String> {
rodio::default_output_device().map(|dev| dev.name().expect("Unable to get device name")) match rodio::default_output_device() {
Some(x) => Some(x.name().ok()?),
None => None,
}
} }
/// Returns a vec of the audio devices available. /// Returns a vec of the audio devices available.
@ -247,19 +250,26 @@ pub fn get_default_device() -> Option<String> {
pub fn list_devices() -> Vec<String> { pub fn list_devices() -> Vec<String> {
list_devices_raw() list_devices_raw()
.iter() .iter()
.map(|x| x.name().expect("Unable to get device name")) .map(|x| x.name().unwrap())
.collect() .collect()
} }
/// Returns vec of devices /// Returns vec of devices
fn list_devices_raw() -> Vec<Device> { fn list_devices_raw() -> Vec<Device> {
rodio::output_devices() match rodio::output_devices() {
.expect("Unable to get output devices") Ok(devices) => {
.collect() // Filter out any devices that the name isn't available for
devices.filter(|d| d.name().is_ok()).collect()
},
Err(_) => {
log::warn!("Failed to enumerate audio output devices, audio will not be available");
Vec::new()
},
}
} }
fn get_device_raw(device: &str) -> Option<Device> { fn get_device_raw(device: &str) -> Option<Device> {
rodio::output_devices() list_devices_raw()
.expect("Unable to get output devices") .into_iter()
.find(|d| d.name().expect("Unable to get device name") == device) .find(|d| d.name().unwrap() == device)
} }