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}, fader::{FadeDirection, Fader},
Listener, Listener,
}; };
use rodio::{Device, OutputStream, OutputStreamHandle, Sample, Sink, Source, SpatialSink}; use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink};
use vek::*; use vek::*;
#[derive(PartialEq, Clone, Copy)] #[derive(PartialEq, Clone, Copy)]

View File

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

View File

@ -131,7 +131,9 @@ impl EventMapper for BlockEventMapper {
for sounds in sounds.iter() { for sounds in sounds.iter() {
if !(sounds.cond)(state) { if !(sounds.cond)(state) {
continue; 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; continue;
} }
@ -159,7 +161,7 @@ impl EventMapper for BlockEventMapper {
// Iterate through each individual block // Iterate through each individual block
for block in blocks { 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; continue;
} }
let block_pos: Vec3<i32> = absolute_pos + block; let block_pos: Vec3<i32> = absolute_pos + block;

View File

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

View File

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

View File

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

View File

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

View File

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