mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
added sound for rain
This commit is contained in:
parent
502145a6f9
commit
99c76be297
@ -2,8 +2,12 @@
|
||||
tracks: [
|
||||
(
|
||||
path: "voxygen.audio.ambient.wind",
|
||||
length: 14.2,
|
||||
length: 14.203,
|
||||
tag: Wind,
|
||||
),
|
||||
), (
|
||||
path: "voxygen.audio.ambient.rain",
|
||||
length: 17.0,
|
||||
tag: Rain,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
BIN
assets/voxygen/audio/ambient/rain.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/ambient/rain.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/sfx/ambient/rain_sfx.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/ambient/rain_sfx.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -29,18 +29,26 @@ pub struct AmbientItem {
|
||||
tag: AmbientChannelTag,
|
||||
}
|
||||
|
||||
pub struct AmbientMgr {
|
||||
soundtrack: AssetHandle<AmbientCollection>,
|
||||
pub struct AmbientWindMgr {
|
||||
ambience: AssetHandle<AmbientCollection>,
|
||||
began_playing: Instant,
|
||||
next_track_change: f32,
|
||||
volume: f32,
|
||||
tree_multiplier: f32,
|
||||
}
|
||||
|
||||
impl Default for AmbientMgr {
|
||||
pub struct AmbientRainMgr {
|
||||
ambience: AssetHandle<AmbientCollection>,
|
||||
began_playing: Instant,
|
||||
next_track_change: f32,
|
||||
volume: f32,
|
||||
rain_intensity: f32,
|
||||
}
|
||||
|
||||
impl Default for AmbientWindMgr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
soundtrack: Self::load_soundtrack_items(),
|
||||
ambience: load_ambience_items(),
|
||||
began_playing: Instant::now(),
|
||||
next_track_change: 0.0,
|
||||
volume: 0.0,
|
||||
@ -49,7 +57,19 @@ impl Default for AmbientMgr {
|
||||
}
|
||||
}
|
||||
|
||||
impl AmbientMgr {
|
||||
impl Default for AmbientRainMgr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ambience: load_ambience_items(),
|
||||
began_playing: Instant::now(),
|
||||
next_track_change: 0.0,
|
||||
volume: 0.0,
|
||||
rain_intensity: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AmbientWindMgr {
|
||||
/// Checks whether the previous track has completed. If so, sends a
|
||||
/// request to play the next (random) track
|
||||
pub fn maintain(
|
||||
@ -59,7 +79,7 @@ impl AmbientMgr {
|
||||
client: &Client,
|
||||
camera: &Camera,
|
||||
) {
|
||||
if audio.sfx_enabled() && !self.soundtrack.read().tracks.is_empty() {
|
||||
if audio.sfx_enabled() && !self.ambience.read().tracks.is_empty() {
|
||||
let focus_off = camera.get_focus_pos().map(f32::trunc);
|
||||
let cam_pos = camera.dependents().cam_pos + focus_off;
|
||||
|
||||
@ -95,6 +115,7 @@ impl AmbientMgr {
|
||||
{
|
||||
volume_multiplier *= 0.1;
|
||||
}
|
||||
// Is the camera roughly under the terrain?
|
||||
if cam_pos.z < terrain_alt - 10.0 {
|
||||
volume_multiplier = 0.0;
|
||||
}
|
||||
@ -103,40 +124,121 @@ impl AmbientMgr {
|
||||
};
|
||||
|
||||
// Transitions the ambient sounds (more) smoothly
|
||||
self.volume = audio.get_ambient_volume();
|
||||
audio.set_ambient_volume(Lerp::lerp(self.volume, target_volume, 0.01));
|
||||
if audio.get_ambient_channel(AmbientChannelTag::Wind).is_none() {
|
||||
audio.new_ambient_channel(AmbientChannelTag::Wind);
|
||||
} else {
|
||||
self.volume = audio.get_ambient_volume(AmbientChannelTag::Wind);
|
||||
audio.set_ambient_volume(
|
||||
AmbientChannelTag::Wind,
|
||||
Lerp::lerp(self.volume, target_volume, 0.01),
|
||||
);
|
||||
}
|
||||
|
||||
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change {
|
||||
// Right now there is only wind non-positional sfx so it is always
|
||||
// selected. Modify this variable assignment when adding other non-
|
||||
// positional sfx
|
||||
let soundtrack = self.soundtrack.read();
|
||||
let track = &soundtrack
|
||||
let ambience = self.ambience.read();
|
||||
let wind_track = &ambience
|
||||
.tracks
|
||||
.iter()
|
||||
.find(|track| track.tag == AmbientChannelTag::Wind);
|
||||
|
||||
if let Some(track) = track {
|
||||
self.began_playing = Instant::now();
|
||||
self.next_track_change = track.length;
|
||||
|
||||
audio.play_ambient(AmbientChannelTag::Wind, &track.path, target_volume);
|
||||
self.began_playing = Instant::now();
|
||||
if let Some(wind_track) = wind_track {
|
||||
self.next_track_change = wind_track.length;
|
||||
audio.play_ambient(AmbientChannelTag::Wind, &wind_track.path, target_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_soundtrack_items() -> AssetHandle<AmbientCollection> {
|
||||
AmbientCollection::load_or_insert_with("voxygen.audio.ambient", |error| {
|
||||
warn!(
|
||||
"Error reading ambience config file, ambience will not be available: {:#?}",
|
||||
error
|
||||
);
|
||||
AmbientCollection::default()
|
||||
})
|
||||
impl AmbientRainMgr {
|
||||
/// Checks whether the previous track has completed. If so, sends a
|
||||
/// request to play the next (random) track
|
||||
pub fn maintain(
|
||||
&mut self,
|
||||
audio: &mut AudioFrontend,
|
||||
state: &State,
|
||||
client: &Client,
|
||||
camera: &Camera,
|
||||
) {
|
||||
if audio.sfx_enabled() && !self.ambience.read().tracks.is_empty() {
|
||||
let focus_off = camera.get_focus_pos().map(f32::trunc);
|
||||
let cam_pos = camera.dependents().cam_pos + focus_off;
|
||||
|
||||
let terrain_alt = if let Some(chunk) = client.current_chunk() {
|
||||
chunk.meta().alt()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
// multipler at end will have to change depending on how intense rain normally
|
||||
// is
|
||||
self.rain_intensity = client.current_weather().rain * 5.0;
|
||||
|
||||
let mut volume_multiplier = self.rain_intensity;
|
||||
|
||||
// TODO: make rain diminish with distance above terrain
|
||||
let target_volume = {
|
||||
// Checks if the camera is underwater to stop ambient sounds
|
||||
if state
|
||||
.terrain()
|
||||
.get((cam_pos).map(|e| e.floor() as i32))
|
||||
.map(|b| b.is_liquid())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
volume_multiplier *= 0.1;
|
||||
}
|
||||
// Is the camera roughly under the terrain?
|
||||
if cam_pos.z < terrain_alt - 10.0 {
|
||||
volume_multiplier = 0.0;
|
||||
}
|
||||
|
||||
volume_multiplier = volume_multiplier.clamped(0.0, 1.0);
|
||||
|
||||
// possibly remove noise
|
||||
if volume_multiplier < 0.05 {
|
||||
0.0
|
||||
} else {
|
||||
volume_multiplier
|
||||
}
|
||||
};
|
||||
|
||||
// Transitions the ambient sounds (more) smoothly
|
||||
if audio.get_ambient_channel(AmbientChannelTag::Rain).is_none() {
|
||||
audio.new_ambient_channel(AmbientChannelTag::Rain);
|
||||
} else {
|
||||
self.volume = audio.get_ambient_volume(AmbientChannelTag::Rain);
|
||||
audio.set_ambient_volume(
|
||||
AmbientChannelTag::Rain,
|
||||
Lerp::lerp(self.volume, target_volume, 0.01),
|
||||
);
|
||||
}
|
||||
|
||||
if self.began_playing.elapsed().as_secs_f32() > self.next_track_change {
|
||||
let ambience = self.ambience.read();
|
||||
let rain_track = &ambience
|
||||
.tracks
|
||||
.iter()
|
||||
.find(|track| track.tag == AmbientChannelTag::Rain);
|
||||
self.began_playing = Instant::now();
|
||||
if let Some(rain_track) = rain_track {
|
||||
self.next_track_change = rain_track.length;
|
||||
audio.play_ambient(AmbientChannelTag::Rain, &rain_track.path, target_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_ambience_items() -> AssetHandle<AmbientCollection> {
|
||||
AmbientCollection::load_or_insert_with("voxygen.audio.ambient", |error| {
|
||||
warn!(
|
||||
"Error reading ambience config file, ambience will not be available: {:#?}",
|
||||
error
|
||||
);
|
||||
AmbientCollection::default()
|
||||
})
|
||||
}
|
||||
|
||||
impl assets::Asset for AmbientCollection {
|
||||
type Loader = assets::RonLoader;
|
||||
|
||||
|
@ -160,6 +160,7 @@ impl MusicChannel {
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
|
||||
pub enum AmbientChannelTag {
|
||||
Wind,
|
||||
Rain,
|
||||
}
|
||||
/// A AmbientChannel uses a non-positional audio sink designed to play sounds
|
||||
/// which are always heard at the camera's position.
|
||||
@ -179,7 +180,7 @@ impl AmbientChannel {
|
||||
sink,
|
||||
},
|
||||
Err(_) => {
|
||||
warn!("Failed to create rodio sink. May not play wind sounds.");
|
||||
warn!("Failed to create rodio sink. May not play ambient sounds.");
|
||||
Self {
|
||||
tag,
|
||||
multiplier,
|
||||
@ -207,6 +208,8 @@ impl AmbientChannel {
|
||||
|
||||
pub fn get_volume(&mut self) -> f32 { self.sink.volume() }
|
||||
|
||||
pub fn get_multiplier(&mut self) -> f32 { self.multiplier }
|
||||
|
||||
pub fn get_tag(&self) -> AmbientChannelTag { self.tag }
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,7 @@ impl AudioFrontend {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// plays a file at a given volume in the channel with a given tag
|
||||
fn play_ambient(
|
||||
&mut self,
|
||||
channel_tag: AmbientChannelTag,
|
||||
@ -294,52 +295,63 @@ impl AudioFrontend {
|
||||
volume_multiplier: f32,
|
||||
) {
|
||||
if self.audio_stream.is_some() {
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag, volume_multiplier) {
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
channel.set_volume(volume_multiplier);
|
||||
channel.play(load_ogg(sound));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adds a new ambient channel of the given tag at zero volume
|
||||
fn new_ambient_channel(&mut self, channel_tag: AmbientChannelTag) {
|
||||
if let Some(audio_stream) = &self.audio_stream {
|
||||
let ambient_channel = AmbientChannel::new(audio_stream, channel_tag, 0.0);
|
||||
self.ambient_channels.push(ambient_channel);
|
||||
}
|
||||
}
|
||||
|
||||
// retrieves the channel currently having the given tag
|
||||
fn get_ambient_channel(
|
||||
&mut self,
|
||||
channel_tag: AmbientChannelTag,
|
||||
volume_multiplier: f32,
|
||||
) -> Option<&mut AmbientChannel> {
|
||||
if let Some(audio_stream) = &self.audio_stream {
|
||||
if self.ambient_channels.is_empty() {
|
||||
let mut ambient_channel =
|
||||
AmbientChannel::new(audio_stream, channel_tag, volume_multiplier);
|
||||
ambient_channel.set_volume(self.get_sfx_volume());
|
||||
self.ambient_channels.push(ambient_channel);
|
||||
} else {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
for channel in self.ambient_channels.iter_mut() {
|
||||
if channel.get_tag() == channel_tag {
|
||||
channel.set_multiplier(volume_multiplier);
|
||||
channel.set_volume(sfx_volume);
|
||||
return Some(channel);
|
||||
}
|
||||
if self.audio_stream.is_some() {
|
||||
let mut tag_match = false;
|
||||
let mut found_channel = None;
|
||||
for channel in self.ambient_channels.iter_mut() {
|
||||
if channel.get_tag() == channel_tag {
|
||||
tag_match = true;
|
||||
found_channel = Some(channel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if tag_match {
|
||||
return found_channel;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn set_ambient_volume(&mut self, volume_multiplier: f32) {
|
||||
// sets the volume of the channel with the given tag to the given volume
|
||||
fn set_ambient_volume(&mut self, channel_tag: AmbientChannelTag, volume_multiplier: f32) {
|
||||
if self.audio_stream.is_some() {
|
||||
let sfx_volume = self.get_sfx_volume();
|
||||
if let Some(channel) = self.ambient_channels.iter_mut().last() {
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
channel.set_multiplier(volume_multiplier);
|
||||
channel.set_volume(sfx_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ambient_volume(&mut self) -> f32 {
|
||||
// retrieves volume (pre-sfx-setting) of the channel with a given tag
|
||||
fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 {
|
||||
if self.audio_stream.is_some() {
|
||||
if let Some(channel) = self.ambient_channels.iter_mut().last() {
|
||||
channel.get_volume() / self.get_sfx_volume()
|
||||
if let Some(channel) = self.get_ambient_channel(channel_tag) {
|
||||
let channel_multiplier = channel.get_multiplier();
|
||||
channel_multiplier
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
@ -406,8 +418,10 @@ impl AudioFrontend {
|
||||
}
|
||||
}
|
||||
|
||||
// this retrieves the current setting for sfx volume
|
||||
pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume * self.master_volume }
|
||||
|
||||
// this retrieves the current setting for music volume
|
||||
pub fn get_music_volume(&self) -> f32 { self.music_volume * self.master_volume }
|
||||
|
||||
pub fn sfx_enabled(&self) -> bool { self.get_sfx_volume() > 0.0 }
|
||||
|
@ -19,7 +19,12 @@ pub use self::{
|
||||
trail::TrailMgr,
|
||||
};
|
||||
use crate::{
|
||||
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
||||
audio::{
|
||||
ambient::{AmbientRainMgr, AmbientWindMgr},
|
||||
music::MusicMgr,
|
||||
sfx::SfxMgr,
|
||||
AudioFrontend,
|
||||
},
|
||||
render::{
|
||||
create_skybox_mesh, CloudsLocals, Consts, Drawer, GlobalModel, Globals, GlobalsBindGroup,
|
||||
Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow, ShadowLocals,
|
||||
@ -102,7 +107,8 @@ pub struct Scene {
|
||||
figure_mgr: FigureMgr,
|
||||
pub sfx_mgr: SfxMgr,
|
||||
music_mgr: MusicMgr,
|
||||
ambient_mgr: AmbientMgr,
|
||||
ambient_wind_mgr: AmbientWindMgr,
|
||||
ambient_rain_mgr: AmbientRainMgr,
|
||||
}
|
||||
|
||||
pub struct SceneData<'a> {
|
||||
@ -314,7 +320,8 @@ impl Scene {
|
||||
figure_mgr: FigureMgr::new(renderer),
|
||||
sfx_mgr: SfxMgr::default(),
|
||||
music_mgr: MusicMgr::default(),
|
||||
ambient_mgr: AmbientMgr::default(),
|
||||
ambient_wind_mgr: AmbientWindMgr::default(),
|
||||
ambient_rain_mgr: AmbientRainMgr::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1066,7 +1073,9 @@ impl Scene {
|
||||
client,
|
||||
);
|
||||
self.music_mgr.maintain(audio, scene_data.state, client);
|
||||
self.ambient_mgr
|
||||
self.ambient_wind_mgr
|
||||
.maintain(audio, scene_data.state, client, &self.camera);
|
||||
self.ambient_rain_mgr
|
||||
.maintain(audio, scene_data.state, client, &self.camera);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user