Address MR 2077 review comments.

This commit is contained in:
Avi Weinstock 2021-04-11 17:47:45 -04:00
parent d401d00d94
commit df4f44d946
4 changed files with 107 additions and 107 deletions

View File

@ -4,11 +4,12 @@
combat_nearby_high_thresh: 4,
combat_nearby_low_thresh: 1,
fade_timings: {
(TitleMusic, Explore): (2.0, 12.0),
(TitleMusic, Exploration): (2.0, 12.0),
(TitleMusic, Combat): (2.0, 3.0),
(Explore, TitleMusic): (2.0, 12.0),
(Explore, Combat): (5.0, 3.0),
(Combat, Explore): (5.0, 3.0),
(Exploration, TitleMusic): (2.0, 12.0),
(Exploration, Combat): (5.0, 3.0),
(Combat, Exploration): (5.0, 3.0),
(Combat, TitleMusic): (2.0, 12.0),
},
interrupt_delay: 5.0,
)

View File

@ -13,7 +13,7 @@
timing: None,
biomes: [],
site: Some(Dungeon),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -25,7 +25,7 @@
(Mountain, 1)
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Ultimafounding; mixed by Robotnik",
)),
Individual((
@ -37,7 +37,7 @@
(Desert, 1)
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic; mixed by Robotnik",
)),
Individual((
@ -47,7 +47,7 @@
timing: None,
biomes: [],
site: Some(Dungeon),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -57,7 +57,7 @@
timing: None,
biomes: [],
site: Some(Cave),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Flashbang",
)),
Individual((
@ -67,7 +67,7 @@
timing: None,
biomes: [],
site: Some(Dungeon),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -77,7 +77,7 @@
timing: None,
biomes: [],
site: Some(Dungeon),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -89,7 +89,7 @@
(Forest, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "DaforLynx",
)),
Individual((
@ -101,7 +101,7 @@
(Jungle, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -113,7 +113,7 @@
(Mountain, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -126,7 +126,7 @@
(Lake, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -139,7 +139,7 @@
(Mountain, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -151,7 +151,7 @@
(Grassland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -163,7 +163,7 @@
(Grassland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Ultimafounding",
)),
Individual((
@ -176,7 +176,7 @@
(Ocean, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "DaforLynx",
)),
Individual((
@ -188,7 +188,7 @@
(Snowland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "DaforLynx",
)),
Individual((
@ -201,7 +201,7 @@
(Mountain, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Ap1evideogame",
)),
Individual((
@ -214,7 +214,7 @@
(Ocean, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Eden",
)),
Individual((
@ -227,7 +227,7 @@
(Mountain, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Eden",
)),
Individual((
@ -240,7 +240,7 @@
(Jungle, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -253,7 +253,7 @@
(Forest, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -265,7 +265,7 @@
(Grassland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -277,7 +277,7 @@
(Snowland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -287,7 +287,7 @@
timing: None,
biomes: [],
site: Some(Cave),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -299,7 +299,7 @@
(Snowland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -312,7 +312,7 @@
(Desert, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "Aeronic",
)),
Individual((
@ -324,7 +324,7 @@
(Grassland, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -336,7 +336,7 @@
(Forest, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -348,7 +348,7 @@
(Mountain, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -358,7 +358,7 @@
timing: None,
biomes: [],
site: Some(Dungeon),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Individual((
@ -370,7 +370,7 @@
(Forest, 1),
],
site: Some(Void),
activity: State(Explore),
music_state: Activity(Explore),
artist: "badbbad",
)),
Segmented(
@ -381,10 +381,10 @@
site: Some(Dungeon),
segments: [
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-end", 6.0, Transition(Combat(High), Explore), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-loop", 54.0, State(Combat(High)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-loop", 54.0, Activity(Combat(High)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-start", 55.0, Transition(Explore, Combat(High)), Some(Combat(High))),
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-end", 3.0, Transition(Combat(Low), Explore), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-loop", 7.0, State(Combat(Low)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-loop", 7.0, Activity(Combat(Low)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-start", 10.0, Transition(Explore, Combat(Low)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-trans-hi-lo", 10.0, Transition(Combat(High), Combat(Low)), None),
("voxygen.audio.soundtrack.barred_paths.barred_paths-trans-lo-hi", 7.0, Transition(Combat(Low), Combat(High)), None),

View File

@ -9,13 +9,13 @@ pub mod soundcache;
use channel::{AmbientChannel, AmbientChannelTag, MusicChannel, MusicChannelTag, SfxChannel};
use fader::Fader;
use music::MUSIC_TRANSITION_MANIFEST;
use music::MusicTransitionManifest;
use sfx::{SfxEvent, SfxTriggerItem};
use soundcache::{OggSound, WavSound};
use std::time::Duration;
use tracing::{debug, error};
use common::assets::AssetExt;
use common::assets::{AssetExt, AssetHandle};
use rodio::{source::Source, OutputStream, OutputStreamHandle, StreamError};
use vek::*;
@ -46,6 +46,8 @@ pub struct AudioFrontend {
sfx_volume: f32,
music_volume: f32,
listener: Listener,
mtm: AssetHandle<MusicTransitionManifest>,
}
impl AudioFrontend {
@ -91,6 +93,7 @@ impl AudioFrontend {
sfx_volume: 1.0,
music_volume: 1.0,
listener: Listener::default(),
mtm: AssetExt::load_expect("voxygen.audio.music_transition_manifest"),
}
}
@ -109,6 +112,9 @@ impl AudioFrontend {
sfx_volume: 1.0,
music_volume: 1.0,
listener: Listener::default(),
// This expect should be fine, since `<MusicTransitionManifest as Asset>::default_value`
// is specified
mtm: AssetExt::load_expect("voxygen.audio.music_transition_manifest"),
}
}
@ -153,13 +159,13 @@ impl AudioFrontend {
let existing_channel = self.music_channels.last_mut()?;
if existing_channel.get_tag() != next_channel_tag {
let mtm = MUSIC_TRANSITION_MANIFEST.read();
let mtm = self.mtm.read();
let (fade_out, fade_in) = mtm
.fade_timings
.get(&(existing_channel.get_tag(), next_channel_tag))
.unwrap_or(&(1.0, 1.0));
let fade_out = Duration::from_millis((1000.0 * fade_out) as _);
let fade_in = Duration::from_millis((1000.0 * fade_in) as _);
let fade_out = Duration::from_secs_f32(*fade_out);
let fade_in = Duration::from_secs_f32(*fade_in);
// Fade the existing channel out. It will be removed when the fade completes.
existing_channel.set_fader(Fader::fade_out(fade_out, self.music_volume));

View File

@ -51,7 +51,6 @@ use common::{
};
use common_sys::state::State;
use hashbrown::HashMap;
use lazy_static::lazy_static;
use rand::{prelude::SliceRandom, thread_rng, Rng};
use serde::Deserialize;
use std::time::Instant;
@ -85,12 +84,12 @@ pub struct SoundtrackItem {
site: Option<SitesKind>,
/// What the player is doing when the track is played (i.e. exploring,
/// combat)
activity: MusicActivity,
music_state: MusicState,
/// What activity to override the activity state with, if any (e.g. to make
/// a long combat intro also act like the loop for the purposes of outro
/// transitions)
#[serde(default)]
activity_override: Option<MusicActivityState>,
activity_override: Option<MusicActivity>,
}
#[derive(Clone, Debug, Deserialize)]
@ -101,7 +100,7 @@ enum RawSoundtrackItem {
timing: Option<DayPeriod>,
biomes: Vec<(BiomeKind, u8)>,
site: Option<SitesKind>,
segments: Vec<(String, f32, MusicActivity, Option<MusicActivityState>)>,
segments: Vec<(String, f32, MusicState, Option<MusicActivity>)>,
},
}
@ -112,15 +111,15 @@ enum CombatIntensity {
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
enum MusicActivityState {
enum MusicActivity {
Explore,
Combat(CombatIntensity),
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
enum MusicActivity {
State(MusicActivityState),
Transition(MusicActivityState, MusicActivityState),
enum MusicState {
Activity(MusicActivity),
Transition(MusicActivity, MusicActivity),
}
/// Allows control over when a track should play based on in-game time of day
@ -152,8 +151,10 @@ pub struct MusicMgr {
/// The title of the last track played. Used to prevent a track
/// being played twice in a row
last_track: String,
/// Time of the last interrupt (to avoid rapid switching)
last_interrupt: Instant,
/// The previous track's activity kind, for transitions
last_activity: MusicActivity,
last_activity: MusicState,
}
#[derive(Deserialize)]
@ -169,6 +170,8 @@ pub struct MusicTransitionManifest {
combat_nearby_low_thresh: u32,
/// Fade in and fade out timings for transitions between channels
pub fade_timings: HashMap<(MusicChannelTag, MusicChannelTag), (f32, f32)>,
/// How many seconds between interrupt checks
pub interrupt_delay: f32,
}
impl Default for MusicTransitionManifest {
@ -179,6 +182,7 @@ impl Default for MusicTransitionManifest {
combat_nearby_high_thresh: 3,
combat_nearby_low_thresh: 1,
fade_timings: HashMap::new(),
interrupt_delay: 5.0,
}
}
}
@ -194,11 +198,6 @@ impl assets::Asset for MusicTransitionManifest {
}
}
lazy_static! {
pub static ref MUSIC_TRANSITION_MANIFEST: AssetHandle<MusicTransitionManifest> =
AssetExt::load_expect("voxygen.audio.music_transition_manifest");
}
impl Default for MusicMgr {
fn default() -> Self {
Self {
@ -206,7 +205,8 @@ impl Default for MusicMgr {
began_playing: Instant::now(),
next_track_change: 0.0,
last_track: String::from("None"),
last_activity: MusicActivity::State(MusicActivityState::Explore),
last_interrupt: Instant::now(),
last_activity: MusicState::Activity(MusicActivity::Explore),
}
}
}
@ -227,15 +227,17 @@ impl MusicMgr {
use common::comp::{group::ENEMY, Group, Health, Pos};
use specs::{Join, WorldExt};
use MusicActivityState::*;
let mut activity_state = Explore;
let mut activity_state = MusicActivity::Explore;
let player = client.entity();
let ecs = state.ecs();
let entities = ecs.entities();
let positions = ecs.read_component::<Pos>();
let healths = ecs.read_component::<Health>();
let groups = ecs.read_component::<Group>();
let mtm = MUSIC_TRANSITION_MANIFEST.read();
let mtm = audio.mtm.read();
if let Some(player_pos) = positions.get(player) {
// TODO: `group::ENEMY` will eventually be moved server-side with an
// alignment/faction rework, so this will need an alternative way to measure
@ -256,38 +258,45 @@ impl MusicMgr {
.sum();
if num_nearby_entities >= mtm.combat_nearby_high_thresh {
activity_state = Combat(CombatIntensity::High);
activity_state = MusicActivity::Combat(CombatIntensity::High);
} else if num_nearby_entities >= mtm.combat_nearby_low_thresh {
activity_state = Combat(CombatIntensity::Low);
activity_state = MusicActivity::Combat(CombatIntensity::Low);
}
}
// Override combat music with explore music if the player is dead
if let Some(health) = healths.get(player) {
if health.is_dead {
activity_state = Explore;
activity_state = MusicActivity::Explore;
}
}
let activity = match self.last_activity {
MusicActivity::State(prev) if prev != activity_state => {
MusicActivity::Transition(prev, activity_state)
let music_state = match self.last_activity {
MusicState::Activity(prev) => {
if prev != activity_state {
MusicState::Transition(prev, activity_state)
} else {
MusicState::Activity(activity_state)
}
},
MusicActivity::Transition(_, next) => MusicActivity::State(next),
_ => MusicActivity::State(activity_state),
MusicState::Transition(_, next) => MusicState::Activity(next),
};
let interrupt = matches!(activity, MusicActivity::Transition(_, _));
let interrupt = matches!(music_state, MusicState::Transition(_, _))
&& self.last_interrupt.elapsed().as_secs_f32() > mtm.interrupt_delay;
if audio.music_enabled()
&& !self.soundtrack.read().tracks.is_empty()
&& (self.began_playing.elapsed().as_secs_f32() > self.next_track_change || interrupt)
{
if interrupt {
self.last_interrupt = Instant::now();
}
debug!(
"pre-play_random_track: {:?} {:?}",
self.last_activity, activity
self.last_activity, music_state
);
if let Ok(next_activity) = self.play_random_track(audio, state, client, &activity) {
if let Ok(next_activity) = self.play_random_track(audio, state, client, &music_state) {
self.last_activity = next_activity;
}
}
@ -298,13 +307,13 @@ impl MusicMgr {
audio: &mut AudioFrontend,
state: &State,
client: &Client,
activity: &MusicActivity,
) -> Result<MusicActivity, ()> {
music_state: &MusicState,
) -> Result<MusicState, ()> {
let mut rng = thread_rng();
// Adds a bit of randomness between plays
let silence_between_tracks_seconds: f32 =
if matches!(activity, MusicActivity::State(MusicActivityState::Explore)) {
if matches!(music_state, MusicState::Activity(MusicActivity::Explore)) {
rng.gen_range(60.0..120.0)
} else {
0.0
@ -335,19 +344,9 @@ impl MusicMgr {
}
})
.filter(|track| {
let mut result = false;
if !track.biomes.is_empty() {
for biome in track.biomes.iter() {
if biome.0 == current_biome {
result = true;
}
}
} else {
result = true;
}
result
track.biomes.is_empty() || track.biomes.iter().any(|b| b.0 == current_biome)
})
.filter(|track| &track.activity == activity)
.filter(|track| &track.music_state == music_state)
.collect::<Vec<&SoundtrackItem>>();
if maybe_tracks.is_empty() {
return Err(());
@ -357,7 +356,7 @@ impl MusicMgr {
let filtered_tracks: Vec<_> = maybe_tracks
.iter()
.filter(|track| !track.title.eq(&self.last_track))
.cloned()
.copied()
.collect();
if !filtered_tracks.is_empty() {
maybe_tracks = filtered_tracks;
@ -366,24 +365,18 @@ impl MusicMgr {
// Randomly selects a track from the remaining tracks weighted based
// on the biome
let new_maybe_track = maybe_tracks.choose_weighted(&mut rng, |track| {
let mut chance = 0;
if !track.biomes.is_empty() {
for biome in track.biomes.iter() {
if biome.0 == current_biome {
chance = biome.1;
}
}
} else {
// If no biome is listed, the song is still added to the
// rotation to allow for site specific songs to play
// in any biome
chance = 1;
}
chance
// If no biome is listed, the song is still added to the
// rotation to allow for site specific songs to play
// in any biome
track
.biomes
.iter()
.find(|b| b.0 == current_biome)
.map_or(1, |b| b.1)
});
debug!(
"selecting new track for {:?}: {:?}",
activity, new_maybe_track
music_state, new_maybe_track
);
if let Ok(track) = new_maybe_track {
@ -392,7 +385,7 @@ impl MusicMgr {
self.began_playing = Instant::now();
self.next_track_change = track.length + silence_between_tracks_seconds;
let tag = if matches!(activity, MusicActivity::State(MusicActivityState::Explore)) {
let tag = if matches!(music_state, MusicState::Activity(MusicActivity::Explore)) {
MusicChannelTag::Exploration
} else {
MusicChannelTag::Combat
@ -400,9 +393,9 @@ impl MusicMgr {
audio.play_music(&track.path, tag);
if let Some(state) = track.activity_override {
Ok(MusicActivity::State(state))
Ok(MusicState::Activity(state))
} else {
Ok(*activity)
Ok(*music_state)
}
} else {
Err(())
@ -447,7 +440,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
site,
segments,
} => {
for (path, length, activity, activity_override) in segments.into_iter() {
for (path, length, music_state, activity_override) in segments.into_iter() {
soundtracks.tracks.push(SoundtrackItem {
title: title.clone(),
path,
@ -455,7 +448,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
timing: timing.clone(),
biomes: biomes.clone(),
site,
activity,
music_state,
activity_override,
});
}