From c82d1b9316900e955320b79b3a33c654003b37b5 Mon Sep 17 00:00:00 2001 From: Marli Frost <marli@frost.red> Date: Sat, 28 Mar 2020 13:12:35 +0000 Subject: [PATCH 1/3] allow the game to start without an audio device --- voxygen/src/audio/mod.rs | 7 ++----- voxygen/src/main.rs | 17 +++++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 1709649c89..299a8c53fe 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -238,11 +238,8 @@ impl AudioFrontend { /// Returns the default audio device. /// Does not return rodio Device struct in case our audio backend changes. -pub fn get_default_device() -> String { - rodio::default_output_device() - .expect("No audio output devices detected.") - .name() - .expect("Unable to get device name") +pub fn get_default_device() -> Option<String> { + rodio::default_output_device().map(|dev| dev.name().expect("Unable to get device name")) } /// Returns a vec of the audio devices available. diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 43b6726ab6..f27beab1ff 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -44,15 +44,16 @@ fn main() { panic!("Failed to save settings: {:?}", err); } - let audio_device = || match &settings.audio.audio_device { - Some(d) => d.to_string(), - None => audio::get_default_device(), - }; + let audio_device = settings + .audio + .audio_device + .as_ref() + .map(|s| s.clone()) + .or_else(audio::get_default_device); - let mut audio = if settings.audio.audio_on { - AudioFrontend::new(audio_device(), settings.audio.max_sfx_channels) - } else { - AudioFrontend::no_audio() + let mut audio = match (audio_device, settings.audio.audio_on) { + (Some(dev), true) => AudioFrontend::new(dev, settings.audio.max_sfx_channels), + _ => AudioFrontend::no_audio() }; audio.set_music_volume(settings.audio.music_volume); From a83f09bd606b8bc1154fc54d291a54336996cb93 Mon Sep 17 00:00:00 2001 From: Marli Frost <marli@frost.red> Date: Tue, 31 Mar 2020 18:02:26 +0100 Subject: [PATCH 2/3] fix: avoid rodio API when audio is disabled --- voxygen/src/main.rs | 24 ++++++++++++++---------- voxygen/src/settings.rs | 5 +++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index f27beab1ff..f874529d10 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -1,4 +1,5 @@ #![deny(unsafe_code)] +#![feature(bool_to_option)] #![recursion_limit = "2048"] use veloren_voxygen::{ @@ -44,17 +45,20 @@ fn main() { panic!("Failed to save settings: {:?}", err); } - let audio_device = settings + let mut audio = settings .audio - .audio_device - .as_ref() - .map(|s| s.clone()) - .or_else(audio::get_default_device); - - let mut audio = match (audio_device, settings.audio.audio_on) { - (Some(dev), true) => AudioFrontend::new(dev, settings.audio.max_sfx_channels), - _ => AudioFrontend::no_audio() - }; + .audio_on + .then(|| { + settings + .audio + .audio_device + .as_ref() + .map(Clone::clone) + .or_else(audio::get_default_device) + }) + .flatten() + .map(|dev| AudioFrontend::new(dev, settings.audio.max_sfx_channels)) + .unwrap_or_else(AudioFrontend::no_audio); audio.set_music_volume(settings.audio.music_volume); audio.set_sfx_volume(settings.audio.sfx_volume); diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index a8ce79e0b4..59583661e4 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -474,6 +474,11 @@ pub struct AudioSettings { /// Audio Device that Voxygen will use to play audio. pub audio_device: Option<String>, + /// Veloren's audio system wont work on some systems, + /// so you can use this to disable it, and allow the + /// game to function + // If this option is disabled, functions in the rodio + // library MUST NOT be called. pub audio_on: bool, } From 3806f08eb00b51d78cd1ce9ff1dc38cc189b2591 Mon Sep 17 00:00:00 2001 From: Marli Frost <marli@frost.red> Date: Tue, 31 Mar 2020 19:12:49 +0100 Subject: [PATCH 3/3] feat: configure audio output using an enum --- voxygen/src/main.rs | 23 ++++++++--------------- voxygen/src/menu/main/mod.rs | 2 +- voxygen/src/session.rs | 3 ++- voxygen/src/settings.rs | 30 +++++++++++++++++++++--------- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index f874529d10..72382f5ecd 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -8,7 +8,7 @@ use veloren_voxygen::{ logging, menu::main::MainMenuState, meta::Meta, - settings::Settings, + settings::{AudioOutput, Settings}, window::Window, Direction, GlobalState, PlayState, PlayStateResult, }; @@ -45,20 +45,13 @@ fn main() { panic!("Failed to save settings: {:?}", err); } - let mut audio = settings - .audio - .audio_on - .then(|| { - settings - .audio - .audio_device - .as_ref() - .map(Clone::clone) - .or_else(audio::get_default_device) - }) - .flatten() - .map(|dev| AudioFrontend::new(dev, settings.audio.max_sfx_channels)) - .unwrap_or_else(AudioFrontend::no_audio); + let mut audio = match settings.audio.output { + AudioOutput::Off => None, + AudioOutput::Automatic => audio::get_default_device(), + AudioOutput::Device(ref dev) => Some(dev.clone()), + } + .map(|dev| AudioFrontend::new(dev, settings.audio.max_sfx_channels)) + .unwrap_or_else(AudioFrontend::no_audio); audio.set_music_volume(settings.audio.music_volume); audio.set_sfx_volume(settings.audio.sfx_volume); diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index 145d8e9b16..3e873f048d 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -36,7 +36,7 @@ impl PlayState for MainMenuState { let mut client_init: Option<ClientInit> = None; // Kick off title music - if global_state.settings.audio.audio_on && global_state.audio.music_enabled() { + if global_state.settings.audio.output.is_enabled() && global_state.audio.music_enabled() { global_state.audio.play_title_music(); } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 335b06b21d..2f1220c070 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -6,6 +6,7 @@ use crate::{ menu::char_selection::CharSelectionState, render::Renderer, scene::{camera, Scene, SceneData}, + settings::AudioOutput, window::{AnalogGameInput, Event, GameInput}, Direction, Error, GlobalState, PlayState, PlayStateResult, }; @@ -613,7 +614,7 @@ impl PlayState for SessionState { HudEvent::ChangeAudioDevice(name) => { global_state.audio.set_device(name.clone()); - global_state.settings.audio.audio_device = Some(name); + global_state.settings.audio.output = AudioOutput::Device(name); global_state.settings.save_to_file_warn(); }, HudEvent::ChangeMaxFPS(fps) => { diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 59583661e4..e28132f592 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -461,7 +461,26 @@ impl Default for GraphicsSettings { } } } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum AudioOutput { + /// Veloren's audio system wont work on some systems, + /// so you can use this to disable it, and allow the + /// game to function + // If this option is disabled, functions in the rodio + // library MUST NOT be called. + Off, + Automatic, + Device(String), +} +impl AudioOutput { + pub fn is_enabled(&self) -> bool { + match self { + Self::Off => false, + _ => true, + } + } +} /// `AudioSettings` controls the volume of different audio subsystems and which /// device is used. #[derive(Clone, Debug, Serialize, Deserialize)] @@ -473,13 +492,7 @@ pub struct AudioSettings { pub max_sfx_channels: usize, /// Audio Device that Voxygen will use to play audio. - pub audio_device: Option<String>, - /// Veloren's audio system wont work on some systems, - /// so you can use this to disable it, and allow the - /// game to function - // If this option is disabled, functions in the rodio - // library MUST NOT be called. - pub audio_on: bool, + pub output: AudioOutput, } impl Default for AudioSettings { @@ -489,8 +502,7 @@ impl Default for AudioSettings { music_volume: 0.4, sfx_volume: 0.6, max_sfx_channels: 10, - audio_device: None, - audio_on: true, + output: AudioOutput::Automatic, } } }