From 8dc35b8609060a9921d4c3aa7d03480e6349f438 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Mon, 20 May 2019 10:54:54 -0600 Subject: [PATCH] Add audio to settings Former-commit-id: 6e18b95bb3460a3b6d971b89c767045dcdbe7344 --- voxygen/src/audio/mod.rs | 31 ++++++++++++++++++++++--------- voxygen/src/main.rs | 18 +++++++++++++++--- voxygen/src/settings.rs | 24 ++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 5ce1a2c772..e04154adfe 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -23,15 +23,6 @@ impl AudioFrontend { pub fn new() -> Self { let mut device = rodio::default_output_device().unwrap(); - for d in rodio::devices() { - if d.name().contains("jack") { - continue; - } - - device = d; - break; - } - let mut sink = rodio::SpatialSink::new(&device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]); @@ -80,4 +71,26 @@ impl AudioFrontend { pub fn set_volume(&mut self, volume: f32) { self.stream.set_volume(volume.min(1.0).max(0.0)) } + + /// Returns a vec of the audio devices available. + /// Does not return rodio Device struct in case our audio backend changes. + // TODO: Decide if this should be an associated function + pub fn get_devices(&self) -> Vec { + rodio::output_devices().map(|x| x.name()).collect() + } + + /// Returns the name of the current audio device. + /// Does not return rodio Device struct in case our audio backend changes. + pub fn get_device(&self) -> String { + self.device.name() + } + + /// Sets the current audio device from a string. + /// Does not use the rodio Device struct in case that detail changes. + /// If the string is an invalid audio device, then no change is made. + pub fn set_device(&mut self, name: String) { + if let Some(dev) = rodio::output_devices().find(|x| x.name() == name) { + self.device = dev; + } + } } diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 643674e135..bc5471dc5e 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -165,9 +165,21 @@ fn main() { audio: AudioFrontend::new(), }; - // TODO: Remove this when the volume setting can be saved - // Lower the volume to 50% - global_state.audio.set_volume(0.5); + // Load volume from audio file + global_state.audio.set_volume(settings.audio.music_volume); + + global_state.settings.audio.audio_devices = global_state.audio.get_devices(); + + // Load last used audio device, or set the current audio device as the last + // used if there is no last used + if global_state.settings.audio.audio_device != "" { + global_state + .audio + .set_device(global_state.settings.audio.audio_device); + } else { + global_state.settings.audio.audio_device = global_state.audio.get_device(); + global_state.settings.save_to_file(); + } // Set up the initial play state. let mut states: Vec> = vec![Box::new(MainMenuState::new(&mut global_state))]; diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 22950cb6d2..1f1728505f 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -12,6 +12,7 @@ pub struct Settings { pub controls: ControlSettings, pub networking: NetworkingSettings, pub log: Log, + pub audio: AudioSettings, } /// `ControlSettings` contains keybindings. @@ -52,6 +53,23 @@ pub struct Log { pub file: PathBuf, } +/// AudioSettings controls the volume of different audio subsystems and which +/// which device is used. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AudioSettings { + pub music_volume: f32, + pub sfx_volume: f32, + + /// Audio Device that Voxygen wil use to play audio. + pub audio_device: String, + + /// Audio devices that are available. Listed here so that it can be accessed + /// from the settings editor in the HUD, but skipped over because it is a + /// runtime specific detail that should not be persisted. + #[serde(skip)] + pub audio_devices: Vec, +} + impl Default for Settings { fn default() -> Self { Settings { @@ -86,6 +104,12 @@ impl Default for Settings { log: Log { file: "voxygen.log".into(), }, + audio: AudioSettings { + music_volume: 0.5, + sfx_volume: 0.5, + audio_device: "".to_string(), + audio_devices: vec![], + }, } } }