Re-added device selector to settings with new rodio

This commit is contained in:
jiminycrick 2020-11-05 14:16:00 -08:00
parent decb0e3e24
commit 8f5a22671d
8 changed files with 120 additions and 60 deletions

View File

@ -20,7 +20,7 @@ use crate::audio::{
fader::{FadeDirection, Fader},
Listener,
};
use rodio::{Device, OutputStream, OutputStreamHandle, Sample, Sink, Source, SpatialSink};
use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink};
use vek::*;
#[derive(PartialEq, Clone, Copy)]

View File

@ -13,7 +13,7 @@ use std::time::Duration;
use tracing::warn;
use common::assets;
use cpal::traits::DeviceTrait;
use cpal::traits::{DeviceTrait, HostTrait};
use rodio::{source::Source, Decoder, Device, OutputStream, OutputStreamHandle, StreamError};
use vek::*;
@ -31,9 +31,10 @@ pub struct Listener {
/// Voxygen's [`GlobalState`](../struct.GlobalState.html#structfield.audio) to
/// provide access to devices and playback control in-game
pub struct AudioFrontend {
//pub device: String,
pub device: String,
pub device_list: Vec<String>,
pub audio_device: Option<Device>,
pub stream: Option<rodio::OutputStream>,
//pub device_list: Vec<String>,
audio_stream: Option<rodio::OutputStreamHandle>,
sound_cache: SoundCache,
@ -46,12 +47,33 @@ pub struct AudioFrontend {
impl AudioFrontend {
/// Construct with given device
pub fn new(max_sfx_channels: usize) -> Self {
//let audio_device = get_device_raw(&device);
pub fn new(dev: String, max_sfx_channels: usize) -> Self {
let audio_device = get_device_raw(&dev);
let device = match get_default_device() {
Some(d) => d,
None => "".to_string(),
};
//if let Some(this_device) = device {
//let (stream, audio_stream) = match get_stream(&device.clone().unwrap()) {
// Ok(s) => (Some(s.0), Some(s.1)),
// Err(_) => (None, None),
//};
//} else {
let (stream, audio_stream) = match get_default_stream() {
Ok(s) => (Some(s.0), Some(s.1)),
Err(_) => (None, None),
};
//}
//let (stream, audio_stream) = match &device {
// Some(dev) => match get_stream(&dev) {
// Ok(s) => (Some(s.0), Some(s.1)),
// Err(_) => (None, None),
// },
// None => match get_default_stream() {
// Ok(s) => (Some(s.0), Some(s.1)),
// Err(_) => (None, None),
// },
//};
let mut sfx_channels = Vec::with_capacity(max_sfx_channels);
if let Some(audio_stream) = &audio_stream {
@ -59,8 +81,9 @@ impl AudioFrontend {
};
Self {
//device,
//device_list: list_devices(),
device,
device_list: list_devices(),
audio_device,
stream,
audio_stream,
sound_cache: SoundCache::default(),
@ -75,9 +98,9 @@ impl AudioFrontend {
/// Construct in `no-audio` mode for debugging
pub fn no_audio() -> Self {
Self {
//device: "none".to_string(),
//device_list: Vec::new(),
//audio_device: None,
device: "".to_string(),
device_list: Vec::new(),
audio_device: None,
stream: None,
audio_stream: None,
sound_cache: SoundCache::default(),
@ -266,11 +289,11 @@ impl AudioFrontend {
}
}
//// TODO: figure out how badly this will break things when it is called
//pub fn set_device(&mut self, name: String) {
// self.device = name.clone();
// self.audio_device = get_device_raw(&name);
//}
// TODO: figure out how badly this will break things when it is called
pub fn set_device(&mut self, name: String) {
self.device = name.clone();
self.audio_device = get_device_raw(&name);
}
}
///// Returns the default audio device.
@ -281,12 +304,25 @@ impl AudioFrontend {
// None => None,
// }
//}
pub fn get_default_device() -> Option<String> {
match cpal::default_host().default_output_device() {
Some(x) => Some(x.name().ok()?),
None => None,
}
}
/// Returns the default stream
pub fn get_default_stream() -> Result<(OutputStream, OutputStreamHandle), StreamError> {
rodio::OutputStream::try_default()
}
/// Returns a stream on the specified device
pub fn get_stream(
device: &rodio::Device,
) -> Result<(OutputStream, OutputStreamHandle), StreamError> {
rodio::OutputStream::try_from_device(device)
}
///// Returns a vec of the audio devices available.
///// Does not return rodio Device struct in case our audio backend changes.
//pub fn list_devices() -> Vec<String> {
@ -309,9 +345,25 @@ pub fn get_default_stream() -> Result<(OutputStream, OutputStreamHandle), Stream
// },
// }
//}
fn list_devices_raw() -> Vec<cpal::Device> {
match cpal::default_host().devices() {
Ok(devices) => devices.filter(|d| d.name().is_ok()).collect(),
Err(_) => {
warn!("Failed to enumerate audio output devices, audio will not be available");
Vec::new()
},
}
}
fn list_devices() -> Vec<String> {
list_devices_raw()
.iter()
.map(|x| x.name().unwrap())
.collect()
}
//
//fn get_device_raw(device: &str) -> Option<Device> {
// list_devices_raw()
// .into_iter()
// .find(|d| d.name().unwrap() == device)
//}
fn get_device_raw(device: &str) -> Option<Device> {
list_devices_raw()
.into_iter()
.find(|d| d.name().unwrap() == device)
}

View File

@ -131,7 +131,9 @@ impl EventMapper for BlockEventMapper {
for sounds in sounds.iter() {
if !(sounds.cond)(state) {
continue;
} else if sounds.sfx == SfxEvent::Birdcall && thread_rng().gen_bool(0.995) {
} else if (sounds.sfx == SfxEvent::Birdcall || sounds.sfx == SfxEvent::Owl)
&& thread_rng().gen_bool(0.995)
{
continue;
}
@ -159,7 +161,7 @@ impl EventMapper for BlockEventMapper {
// Iterate through each individual block
for block in blocks {
if sounds.sfx == SfxEvent::Birdcall && thread_rng().gen_bool(0.999) {
if (sounds.sfx == SfxEvent::Birdcall || sounds.sfx == SfxEvent::Owl) && thread_rng().gen_bool(0.999) {
continue;
}
let block_pos: Vec3<i32> = absolute_pos + block;

View File

@ -319,7 +319,7 @@ pub enum Event {
AdjustFigureLoDRenderDistance(u32),
AdjustMusicVolume(f32),
AdjustSfxVolume(f32),
//ChangeAudioDevice(String),
ChangeAudioDevice(String),
ChangeMaxFPS(u32),
ChangeFOV(u16),
ChangeGamma(f32),
@ -2131,9 +2131,9 @@ impl Hud {
settings_window::Event::MaximumFPS(max_fps) => {
events.push(Event::ChangeMaxFPS(max_fps));
},
//settings_window::Event::ChangeAudioDevice(name) => {
// events.push(Event::ChangeAudioDevice(name));
//},
settings_window::Event::ChangeAudioDevice(name) => {
events.push(Event::ChangeAudioDevice(name));
},
settings_window::Event::CrosshairType(crosshair_type) => {
events.push(Event::CrosshairType(crosshair_type));
},

View File

@ -291,7 +291,7 @@ pub enum Event {
ChangeRenderMode(Box<RenderMode>),
AdjustMusicVolume(f32),
AdjustSfxVolume(f32),
//ChangeAudioDevice(String),
ChangeAudioDevice(String),
MaximumFPS(u32),
CrosshairTransp(f32),
CrosshairType(CrosshairType),
@ -2693,32 +2693,30 @@ impl<'a> Widget for SettingsWindow<'a> {
events.push(Event::AdjustSfxVolume(new_val));
}
// Audio Device Selector
// --------------------------------------------
// let device = &self.global_state.audio.device;
//let device_list = &self.global_state.audio.device_list;
//Text::new(&self.localized_strings.get("hud.settings.audio_device"
// )) .down_from(state.ids.sfx_volume_slider, 10.0)
// .font_size(self.fonts.cyri.scale(14))
// .font_id(self.fonts.cyri.conrod_id)
// .color(TEXT_COLOR)
// .set(state.ids.audio_device_text, ui);
// Audio Device Selector --------------------------------------------
let device = &self.global_state.audio.device;
let device_list = &self.global_state.audio.device_list;
Text::new(&self.localized_strings.get("hud.settings.audio_device"))
.down_from(state.ids.sfx_volume_slider, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.audio_device_text, ui);
//// Get which device is currently selected
//let selected = device_list.iter().position(|x|
// x.contains(device));
// Get which device is currently selected
let selected = device_list.iter().position(|x| x.contains(device));
//if let Some(clicked) = DropDownList::new(&device_list, selected)
// .w_h(400.0, 22.0)
// .color(MENU_BG)
// .label_color(TEXT_COLOR)
// .label_font_id(self.fonts.opensans.conrod_id)
// .down_from(state.ids.audio_device_text, 10.0)
// .set(state.ids.audio_device_list, ui)
//{
// let new_val = device_list[clicked].clone();
// events.push(Event::ChangeAudioDevice(new_val));
//}
if let Some(clicked) = DropDownList::new(&device_list, selected)
.w_h(400.0, 22.0)
.color(MENU_BG)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.opensans.conrod_id)
.down_from(state.ids.audio_device_text, 10.0)
.set(state.ids.audio_device_list, ui)
{
let new_val = device_list[clicked].clone();
events.push(Event::ChangeAudioDevice(new_val));
}
}
// 5) Languages Tab -----------------------------------

View File

@ -144,10 +144,10 @@ fn main() {
// Setup audio
let mut audio = match settings.audio.output {
AudioOutput::Off => None,
AudioOutput::Automatic => audio::get_default_stream().ok(),
//AudioOutput::Device(ref dev) => Some(dev.clone()),
AudioOutput::Automatic => audio::get_default_device(),
AudioOutput::Device(ref dev) => Some(dev.clone()),
}
.map(|dev| AudioFrontend::new(/* dev, */ settings.audio.max_sfx_channels))
.map(|dev| AudioFrontend::new(dev, settings.audio.max_sfx_channels))
.unwrap_or_else(AudioFrontend::no_audio);
audio.set_music_volume(settings.audio.music_volume);

View File

@ -9,6 +9,7 @@ use vek::*;
pub struct BlocksOfInterest {
pub leaves: Vec<Vec3<i32>>,
pub grass: Vec<Vec3<i32>>,
pub water: Vec<Vec3<i32>>,
pub embers: Vec<Vec3<i32>>,
pub beehives: Vec<Vec3<i32>>,
pub reeds: Vec<Vec3<i32>>,
@ -23,6 +24,7 @@ impl BlocksOfInterest {
span!(_guard, "from_chunk", "BlocksOfInterest::from_chunk");
let mut leaves = Vec::new();
let mut grass = Vec::new();
let mut water = Vec::new();
let mut embers = Vec::new();
let mut beehives = Vec::new();
let mut reeds = Vec::new();
@ -50,6 +52,11 @@ impl BlocksOfInterest {
grass.push(pos)
}
},
BlockKind::Water => {
if thread_rng().gen_range(0, 16) == 0 {
water.push(pos)
}
},
_ => match block.get_sprite() {
Some(SpriteKind::Ember) => embers.push(pos),
Some(SpriteKind::Beehive) => beehives.push(pos),
@ -71,6 +78,7 @@ impl BlocksOfInterest {
Self {
leaves,
grass,
water,
embers,
beehives,
reeds,

View File

@ -901,12 +901,12 @@ impl PlayState for SessionState {
global_state.settings.audio.sfx_volume = sfx_volume;
global_state.settings.save_to_file_warn();
},
//HudEvent::ChangeAudioDevice(name) => {
// global_state.audio.set_device(name.clone());
HudEvent::ChangeAudioDevice(name) => {
global_state.audio.set_device(name.clone());
// global_state.settings.audio.output = AudioOutput::Device(name);
// global_state.settings.save_to_file_warn();
//},
global_state.settings.audio.output = AudioOutput::Device(name);
global_state.settings.save_to_file_warn();
},
HudEvent::ChangeMaxFPS(fps) => {
global_state.settings.graphics.max_fps = fps;
global_state.settings.save_to_file_warn();