Bird calls from trees

This commit is contained in:
jiminycrick 2020-10-29 00:39:17 -07:00
parent 9e790f6cac
commit aa6b7cbb65
8 changed files with 134 additions and 111 deletions

View File

@ -9,6 +9,14 @@
], ],
threshold: 1.2, threshold: 1.2,
), ),
Birdcall: (
files: [
"voxygen.audio.sfx.ambient.birdcall_1",
"voxygen.audio.sfx.ambient.birdcall_2",
"voxygen.audio.sfx.ambient.birdcall_3",
],
threshold: 30.0,
),
// //
// Character States // Character States
// //

BIN
assets/voxygen/audio/sfx/ambient/birdcall_1.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/ambient/birdcall_2.wav (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/ambient/birdcall_3.wav (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,6 +1,6 @@
//! Handles audio device detection and playback of sound effects and music //! Handles audio device detection and playback of sound effects and music
pub mod ambient; //pub mod ambient;
pub mod channel; pub mod channel;
pub mod fader; pub mod fader;
pub mod music; pub mod music;
@ -39,12 +39,10 @@ pub struct AudioFrontend {
music_channels: Vec<MusicChannel>, music_channels: Vec<MusicChannel>,
sfx_channels: Vec<SfxChannel>, sfx_channels: Vec<SfxChannel>,
ambient_channels: Vec<AmbientChannel>, //ambient_channels: Vec<AmbientChannel>,
sfx_volume: f32, sfx_volume: f32,
music_volume: f32, music_volume: f32,
ambient_volume: f32, //ambient_volume: f32,
listener: Listener, listener: Listener,
} }
@ -64,12 +62,11 @@ impl AudioFrontend {
audio_device, audio_device,
sound_cache: SoundCache::default(), sound_cache: SoundCache::default(),
music_channels: Vec::new(), music_channels: Vec::new(),
ambient_channels: Vec::new(), //ambient_channels: Vec::new(),
sfx_channels, sfx_channels,
sfx_volume: 1.0, sfx_volume: 1.0,
music_volume: 1.0, music_volume: 1.0,
ambient_volume: 1.0, //ambient_volume: 1.0,
listener: Listener::default(), listener: Listener::default(),
} }
} }
@ -82,11 +79,11 @@ impl AudioFrontend {
audio_device: None, audio_device: None,
sound_cache: SoundCache::default(), sound_cache: SoundCache::default(),
music_channels: Vec::new(), music_channels: Vec::new(),
ambient_channels: Vec::new(), //ambient_channels: Vec::new(),
sfx_channels: Vec::new(), sfx_channels: Vec::new(),
sfx_volume: 1.0, sfx_volume: 1.0,
music_volume: 1.0, music_volume: 1.0,
ambient_volume: 1.0, //ambient_volume: 1.0,
listener: Listener::default(), listener: Listener::default(),
} }
} }
@ -94,15 +91,15 @@ impl AudioFrontend {
/// Drop any unused music channels, and update their faders /// Drop any unused music channels, and update their faders
pub fn maintain(&mut self, dt: Duration) { pub fn maintain(&mut self, dt: Duration) {
self.music_channels.retain(|c| !c.is_done()); self.music_channels.retain(|c| !c.is_done());
self.ambient_channels.retain(|c| !c.is_done()); //self.ambient_channels.retain(|c| !c.is_done());
for channel in self.music_channels.iter_mut() { for channel in self.music_channels.iter_mut() {
channel.maintain(dt); channel.maintain(dt);
} }
for channel in self.ambient_channels.iter_mut() { //for channel in self.ambient_channels.iter_mut() {
channel.maintain(dt); // channel.maintain(dt);
} //}
} }
fn get_sfx_channel(&mut self) -> Option<&mut SfxChannel> { fn get_sfx_channel(&mut self) -> Option<&mut SfxChannel> {
@ -153,34 +150,37 @@ impl AudioFrontend {
self.music_channels.last_mut() self.music_channels.last_mut()
} }
fn get_ambient_channel( //fn get_ambient_channel(
&mut self, // &mut self,
next_channel_tag: AmbientChannelTag, // next_channel_tag: AmbientChannelTag,
) -> Option<&mut AmbientChannel> { //) -> Option<&mut AmbientChannel> {
if let Some(audio_device) = &self.audio_device { // if let Some(audio_device) = &self.audio_device {
if self.ambient_channels.is_empty() { // if self.ambient_channels.is_empty() {
let mut next_ambient_channel = AmbientChannel::new(&audio_device); // let mut next_ambient_channel = AmbientChannel::new(&audio_device);
next_ambient_channel.set_volume(self.ambient_volume); // next_ambient_channel.set_volume(self.music_volume);
self.ambient_channels.push(next_ambient_channel); // self.ambient_channels.push(next_ambient_channel);
} else { // } else {
let existing_channel = self.ambient_channels.last_mut()?; // let existing_channel = self.ambient_channels.last_mut()?;
if existing_channel.get_tag() != next_channel_tag { // if existing_channel.get_tag() != next_channel_tag {
// Fade the existing channel out. It will be removed when the fade completes. // // Fade the existing channel out. It will be removed when the
existing_channel.set_fader(Fader::fade_out(2.0, self.ambient_volume)); // fade completes.
// existing_channel.set_fader(Fader::fade_out(2.0, self.music_volume));
let mut next_ambient_channel = AmbientChannel::new(&audio_device); // let mut next_ambient_channel =
// AmbientChannel::new(&audio_device);
next_ambient_channel.set_fader(Fader::fade_in(12.0, self.ambient_volume)); // next_ambient_channel.set_fader(Fader::fade_in(12.0,
// self.music_volume));
self.ambient_channels.push(next_ambient_channel); // self.ambient_channels.push(next_ambient_channel);
} // }
} // }
} // }
self.ambient_channels.last_mut() // self.ambient_channels.last_mut()
} //}
/// Play (once) an sfx file by file path at the give position and volume /// Play (once) an sfx file by file path at the give position and volume
pub fn play_sfx(&mut self, sound: &str, pos: Vec3<f32>, vol: Option<f32>) { pub fn play_sfx(&mut self, sound: &str, pos: Vec3<f32>, vol: Option<f32>) {
@ -228,34 +228,35 @@ impl AudioFrontend {
} }
} }
fn stop_ambient(&mut self, channel_tag: AmbientChannelTag) { //fn stop_ambient(&mut self, channel_tag: AmbientChannelTag) {
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
channel.stop(channel_tag); // channel.stop(channel_tag);
} // }
} //}
fn fade_out_ambient(&mut self, channel_tag: AmbientChannelTag) { //fn fade_out_ambient(&mut self, channel_tag: AmbientChannelTag) {
let ambient_volume = self.ambient_volume; // let music_volume = self.music_volume;
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
channel.set_fader(Fader::fade_out(2.0, ambient_volume)); // channel.set_fader(Fader::fade_out(2.0, music_volume));
} // }
} //}
fn fade_in_ambient(&mut self, channel_tag: AmbientChannelTag) { //fn fade_in_ambient(&mut self, channel_tag: AmbientChannelTag) {
let ambient_volume = self.ambient_volume; // let music_volume = self.music_volume;
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
channel.set_fader(Fader::fade_in(2.0, ambient_volume)); // channel.set_fader(Fader::fade_in(2.0, music_volume));
} // }
} //}
fn play_ambient(&mut self, sound: &str, channel_tag: AmbientChannelTag) { //fn play_ambient(&mut self, sound: &str, channel_tag: AmbientChannelTag) {
if let Some(channel) = self.get_ambient_channel(channel_tag) { // if let Some(channel) = self.get_ambient_channel(channel_tag) {
let file = assets::load_file(&sound, &["ogg"]).expect("Failed to load sound"); // let file = assets::load_file(&sound, &["ogg"]).expect("Failed to load
let sound = Decoder::new(file).expect("Failed to decode sound"); // sound"); let sound = Decoder::new(file).expect("Failed to decode
// sound");
channel.play(sound, channel_tag); // channel.play(sound, channel_tag);
} // }
} //}
pub fn set_listener_pos(&mut self, pos: Vec3<f32>, ori: Vec3<f32>) { pub fn set_listener_pos(&mut self, pos: Vec3<f32>, ori: Vec3<f32>) {
self.listener.pos = pos; self.listener.pos = pos;
@ -307,41 +308,41 @@ impl AudioFrontend {
} }
} }
pub fn play_exploration_ambient(&mut self, item: &str) { //pub fn play_exploration_ambient(&mut self, item: &str) {
if self.music_enabled() { // if self.music_enabled() {
self.play_ambient(item, AmbientChannelTag::Exploration) // self.play_ambient(item, AmbientChannelTag::Exploration)
} // }
} //}
pub fn fade_out_exploration_ambient(&mut self) { //pub fn fade_out_exploration_ambient(&mut self) {
if self.music_enabled() { // if self.music_enabled() {
self.fade_out_ambient(AmbientChannelTag::Exploration) // self.fade_out_ambient(AmbientChannelTag::Exploration)
} // }
} //}
pub fn fade_in_exploration_ambient(&mut self) { //pub fn fade_in_exploration_ambient(&mut self) {
if self.music_enabled() { // if self.music_enabled() {
self.fade_in_ambient(AmbientChannelTag::Exploration) // self.fade_in_ambient(AmbientChannelTag::Exploration)
} // }
} //}
pub fn stop_exploration_ambient(&mut self) { //pub fn stop_exploration_ambient(&mut self) {
if self.music_enabled() { // if self.music_enabled() {
self.stop_ambient(AmbientChannelTag::Exploration) // self.stop_ambient(AmbientChannelTag::Exploration)
} // }
} //}
pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume } pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume }
pub fn get_music_volume(&self) -> f32 { self.music_volume } pub fn get_music_volume(&self) -> f32 { self.music_volume }
pub fn get_ambient_volume(&self) -> f32 { self.ambient_volume } //pub fn get_ambient_volume(&self) -> f32 { self.music_volume }
pub fn sfx_enabled(&self) -> bool { self.sfx_volume > 0.0 } pub fn sfx_enabled(&self) -> bool { self.sfx_volume > 0.0 }
pub fn music_enabled(&self) -> bool { self.music_volume > 0.0 } pub fn music_enabled(&self) -> bool { self.music_volume > 0.0 }
pub fn ambient_enabled(&self) -> bool { self.ambient_volume > 0.0 } //pub fn ambient_enabled(&self) -> bool { self.music_volume > 0.0 }
pub fn set_sfx_volume(&mut self, sfx_volume: f32) { pub fn set_sfx_volume(&mut self, sfx_volume: f32) {
self.sfx_volume = sfx_volume; self.sfx_volume = sfx_volume;
@ -359,13 +360,13 @@ impl AudioFrontend {
} }
} }
pub fn set_ambient_volume(&mut self, ambient_volume: f32) { //pub fn set_ambient_volume(&mut self, ambient_volume: f32) {
self.ambient_volume = ambient_volume; // self.music_volume = ambient_volume;
for channel in self.ambient_channels.iter_mut() { // for channel in self.ambient_channels.iter_mut() {
channel.set_volume(ambient_volume); // channel.set_volume(ambient_volume);
} // }
} //}
// 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) {

View File

@ -11,7 +11,7 @@ use common::{
vol::RectRasterableVol, vol::RectRasterableVol,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
use rand::{prelude::SliceRandom, thread_rng}; use rand::{prelude::SliceRandom, thread_rng, Rng};
use specs::WorldExt; use specs::WorldExt;
use std::time::Instant; use std::time::Instant;
use vek::*; use vek::*;
@ -41,7 +41,7 @@ impl Default for PreviousBlockState {
} }
impl PreviousBlockState { impl PreviousBlockState {
fn new(event: SfxEvent, pos: Vec3<f32>) -> Self { fn new(event: SfxEvent) -> Self {
PreviousBlockState { PreviousBlockState {
event, event,
time: Instant::now(), time: Instant::now(),
@ -84,8 +84,6 @@ impl EventMapper for BlockEventMapper {
blocks: fn(&'a BlocksOfInterest) -> &'a [Vec3<i32>], blocks: fn(&'a BlocksOfInterest) -> &'a [Vec3<i32>],
// The range, in chunks, that the particles should be generated in from the player // The range, in chunks, that the particles should be generated in from the player
range: usize, range: usize,
// The spacing between sfx, per block, seconds
spacing: f32,
// The sound of the generated particle // The sound of the generated particle
sfx: SfxEvent, sfx: SfxEvent,
// The volume of the sfx // The volume of the sfx
@ -94,20 +92,18 @@ impl EventMapper for BlockEventMapper {
cond: fn(&State) -> bool, cond: fn(&State) -> bool,
} }
let sounds: &[BlockSounds] = &[ let sounds: &[BlockSounds] = &[
//BlockSounds { BlockSounds {
// blocks: |boi| &boi.leaves, blocks: |boi| &boi.leaves,
// range: 4, range: 1,
// spacing: 1.5, sfx: SfxEvent::Birdcall,
// sfx: SfxEvent::LevelUp, volume: 1.0,
// volume: 1.0 cond: |_| true,
// cond: |_| true, },
//},
BlockSounds { BlockSounds {
blocks: |boi| &boi.embers, blocks: |boi| &boi.embers,
range: 3, range: 1,
spacing: 1.2,
sfx: SfxEvent::Embers, sfx: SfxEvent::Embers,
volume: 0.5, volume: 0.05,
//volume: 0.05, //volume: 0.05,
cond: |_| true, cond: |_| true,
//cond: |st| st.get_day_period().is_dark(), //cond: |st| st.get_day_period().is_dark(),
@ -148,13 +144,13 @@ impl EventMapper for BlockEventMapper {
// cond: |_| true, // cond: |_| true,
//}, //},
]; ];
let mut rng = thread_rng();
// Iterate through each kind of block of interest // Iterate through each kind of block of interest
for sounds in sounds.iter() { for sounds in sounds.iter() {
if !(sounds.cond)(state) { if !(sounds.cond)(state) {
continue; continue;
} }
// For chunks surrounding the player position // For chunks surrounding the player position
for offset in Spiral2d::new().take((sounds.range * 2 + 1).pow(2)) { for offset in Spiral2d::new().take((sounds.range * 2 + 1).pow(2)) {
let chunk_pos = player_chunk + offset; let chunk_pos = player_chunk + offset;
@ -169,6 +165,11 @@ impl EventMapper for BlockEventMapper {
// Iterate through each individual block // Iterate through each individual block
for block in blocks { for block in blocks {
// Reduce the number of bird calls from trees
if sounds.sfx == SfxEvent::Birdcall && thread_rng().gen::<f32>() < 0.25 {
continue;
}
let block_pos: Vec3<i32> = absolute_pos + block; let block_pos: Vec3<i32> = absolute_pos + block;
let state = self.history.entry(block_pos).or_default(); let state = self.history.entry(block_pos).or_default();
@ -180,9 +181,12 @@ impl EventMapper for BlockEventMapper {
); );
if Self::should_emit(state, triggers.get_key_value(&sounds.sfx)) { if Self::should_emit(state, triggers.get_key_value(&sounds.sfx)) {
sfx_emitter.emit(SfxEventItem::new(sounds.sfx.clone(), Some(block_pos), Some(sounds.volume))); // If the camera is within SFX distance
state.time = Instant::now(); if (block_pos.distance_squared(cam_pos)) < SFX_DIST_LIMIT_SQR {
state.event = sounds.sfx.clone(); sfx_emitter.emit(SfxEventItem::new(sounds.sfx.clone(), Some(block_pos), Some(sounds.volume)));
state.time = Instant::now();
state.event = sounds.sfx.clone();
}
} }
} }

View File

@ -136,6 +136,7 @@ impl SfxEventItem {
#[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)] #[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)]
pub enum SfxEvent { pub enum SfxEvent {
Embers, Embers,
Birdcall,
Idle, Idle,
Run, Run,
Roll, Roll,

View File

@ -14,7 +14,7 @@ pub use self::{
terrain::Terrain, terrain::Terrain,
}; };
use crate::{ use crate::{
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend}, audio::{music::MusicMgr, sfx::SfxMgr, AudioFrontend},
render::{ render::{
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline, create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline,
Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals,
@ -103,7 +103,7 @@ pub struct Scene {
figure_mgr: FigureMgr, figure_mgr: FigureMgr,
sfx_mgr: SfxMgr, sfx_mgr: SfxMgr,
music_mgr: MusicMgr, music_mgr: MusicMgr,
ambient_mgr: AmbientMgr, //ambient_mgr: AmbientMgr,
} }
pub struct SceneData<'a> { pub struct SceneData<'a> {
@ -309,7 +309,7 @@ impl Scene {
figure_mgr: FigureMgr::new(renderer), figure_mgr: FigureMgr::new(renderer),
sfx_mgr: SfxMgr::new(), sfx_mgr: SfxMgr::new(),
music_mgr: MusicMgr::new(), music_mgr: MusicMgr::new(),
ambient_mgr: AmbientMgr::new(), //ambient_mgr: AmbientMgr::new(),
} }
} }
@ -999,7 +999,7 @@ impl Scene {
&self.terrain, &self.terrain,
); );
self.music_mgr.maintain(audio, scene_data.state, client); self.music_mgr.maintain(audio, scene_data.state, client);
self.ambient_mgr.maintain(audio, scene_data.state, client); //self.ambient_mgr.maintain(audio, scene_data.state, client);
} }
/// Render the scene using the provided `Renderer`. /// Render the scene using the provided `Renderer`.