WIP: New music, "now playing" line in debug overlay, and music frequency slider

This commit is contained in:
DaforLynx 2022-08-01 17:41:44 +00:00 committed by Marcel
parent d059eefcc8
commit bf4a582cf7
13 changed files with 161 additions and 24 deletions

View File

@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Currently playing music track and artist now shows in the debug menu.
- Added a setting to influence the gap between music track plays.
### Changed

View File

@ -12,6 +12,31 @@
[
// Overworld exploration tracks
Individual((
title: "The Undergrowth",
path: "voxygen.audio.soundtrack.overworld.the_undergrowth",
length: 165.0,
timing: None,
biomes: [
(Jungle, 1),
],
site: Some(Void),
music_state: Activity(Explore),
artist: "Oolnokk",
)),
Individual((
title: "Moonlit Canopy",
path: "voxygen.audio.soundtrack.overworld.moonlit_canopy",
length: 170.0,
timing: Some(Night),
biomes: [
(Forest, 2),
(Taiga, 1),
],
site: Some(Void),
music_state: Activity(Explore),
artist: "GeekyGami",
)),
Individual((
title: "Adventurous Soul",
path: "voxygen.audio.soundtrack.overworld.adventurous_soul",
@ -129,7 +154,7 @@
title: "Jungle Ambient",
path: "voxygen.audio.soundtrack.overworld.jungle_ambient",
length: 218.0,
timing: Some(Day),
timing: None,
weather: None,
biomes: [
(Jungle, 1),
@ -283,8 +308,6 @@
weather: None,
biomes: [
(Forest, 2),
(Jungle, 1),
(Taiga, 1),
],
site: Some(Void),
music_state: Activity(Explore),
@ -649,28 +672,29 @@
Segmented(
title: "Barred Paths",
author: "DaforLynx",
timing: None,
weather: None,
biomes: [],
site: Some(Dungeon),
segments: [
("voxygen.audio.soundtrack.combat.barred_paths.barred_paths-start", 55.97, Transition(Explore, Combat(High)), Some(Combat(High))),
("voxygen.audio.soundtrack.combat.barred_paths.barred_paths-loop", 53.97, Activity(Combat(High)), None),
("voxygen.audio.soundtrack.combat.barred_paths.barred_paths-start", 56.0, Transition(Explore, Combat(High)), Some(Combat(High))),
("voxygen.audio.soundtrack.combat.barred_paths.barred_paths-loop", 54.0, Activity(Combat(High)), None),
("voxygen.audio.soundtrack.combat.barred_paths.barred_paths-end", 6.0, Transition(Combat(High), Explore), None),
],
artist: "DaforLynx",
),
Segmented(
title: "Reversal",
author: "DaforLynx",
timing: None,
weather: None,
biomes: [],
site: Some(Dungeon),
segments: [
("voxygen.audio.soundtrack.combat.reversal.reversal-start", 59.97, Transition(Explore, Combat(High)), Some(Combat(High))),
("voxygen.audio.soundtrack.combat.reversal.reversal-loop", 59.97, Activity(Combat(High)), None),
("voxygen.audio.soundtrack.combat.reversal.reversal-start", 60.0, Transition(Explore, Combat(High)), Some(Combat(High))),
("voxygen.audio.soundtrack.combat.reversal.reversal-loop", 60.0, Activity(Combat(High)), None),
("voxygen.audio.soundtrack.combat.reversal.reversal-end", 4.0, Transition(Combat(High), Explore), None),
],
artist: "DaforLynx",
),
]
)

BIN
assets/voxygen/audio/soundtrack/overworld/moonlit_canopy.ogg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -120,6 +120,7 @@
"hud.settings.music_volume": "Music Volume",
"hud.settings.sound_effect_volume": "Sound Effects Volume",
"hud.settings.ambience_volume": "Ambience Volume",
"hud.settings.music_frequency": "Gap Between Songs",
"hud.settings.audio_device": "Audio Device",
"hud.settings.reset_sound": "Reset to Defaults",

View File

@ -55,6 +55,7 @@ pub struct AudioFrontend {
ambience_volume: f32,
music_volume: f32,
master_volume: f32,
music_frequency: f32,
listener: Listener,
mtm: AssetHandle<MusicTransitionManifest>,
@ -107,6 +108,7 @@ impl AudioFrontend {
ambience_volume: 1.0,
music_volume: 1.0,
master_volume: 1.0,
music_frequency: 1.0,
listener: Listener::default(),
mtm: AssetExt::load_expect("voxygen.audio.music_transition_manifest"),
}
@ -138,6 +140,7 @@ impl AudioFrontend {
ambience_volume: 1.0,
music_volume: 1.0,
master_volume: 1.0,
music_frequency: 1.0,
listener: Listener::default(),
mtm,
}
@ -179,6 +182,14 @@ impl AudioFrontend {
None
}
fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) {
if self.music_enabled() {
if let Some(channel) = self.get_music_channel(channel_tag) {
channel.play(load_ogg(sound), channel_tag);
}
}
}
/// Retrieve a music channel from the channel list. This inspects the
/// MusicChannelTag to determine whether we are transitioning between
/// music types and acts accordingly. For example transitioning between
@ -373,14 +384,6 @@ impl AudioFrontend {
// }
// }
fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) {
if self.music_enabled() {
if let Some(channel) = self.get_music_channel(channel_tag) {
channel.play(load_ogg(sound), channel_tag);
}
}
}
/* These functions are saved for if we want music playback control at some
* point. They are not used currently but may be useful for later work.
*
@ -476,6 +479,8 @@ impl AudioFrontend {
}
}
pub fn set_music_frequency(&mut self, multiplier: f32) { self.music_frequency = multiplier }
/// Updates master volume in all channels
pub fn set_master_volume(&mut self, master_volume: f32) {
self.master_volume = master_volume;

View File

@ -93,6 +93,8 @@ pub struct SoundtrackItem {
/// transitions)
#[serde(default)]
activity_override: Option<MusicActivity>,
/// Song artist
artist: String,
}
#[derive(Clone, Debug, Deserialize)]
@ -105,6 +107,7 @@ enum RawSoundtrackItem {
biomes: Vec<(BiomeKind, u8)>,
site: Option<SitesKind>,
segments: Vec<(String, f32, MusicState, Option<MusicActivity>)>,
artist: String,
},
}
@ -159,6 +162,10 @@ pub struct MusicMgr {
last_interrupt: Instant,
/// The previous track's activity kind, for transitions
last_activity: MusicState,
// For debug menu
pub current_track: String,
pub current_artist: String,
track_length: f32,
}
#[derive(Deserialize)]
@ -206,6 +213,9 @@ impl Default for MusicMgr {
last_track: String::from("None"),
last_interrupt: Instant::now(),
last_activity: MusicState::Activity(MusicActivity::Explore),
current_track: String::from("None"),
current_artist: String::from("None"),
track_length: 0.0,
}
}
}
@ -294,6 +304,12 @@ impl MusicMgr {
let interrupt = matches!(music_state, MusicState::Transition(_, _))
&& self.last_interrupt.elapsed().as_secs_f32() > mtm.interrupt_delay;
// When the current track ends, clear the debug values
if self.began_playing.elapsed().as_secs_f32() > self.track_length {
self.current_track = String::from("None");
self.current_artist = String::from("None");
}
if audio.music_enabled()
&& !self.soundtrack.read().tracks.is_empty()
&& (self.began_playing.elapsed().as_secs_f32() > self.next_track_change || interrupt)
@ -325,20 +341,29 @@ impl MusicMgr {
// a town, or exploring.
// TODO: make this something that is decided when a song ends, instead of when
// it begins
let frequency_multipler = audio.music_frequency;
let silence_between_tracks_seconds: f32 =
if matches!(music_state, MusicState::Activity(MusicActivity::Explore))
&& matches!(client.current_site(), SitesKind::Settlement)
{
rng.gen_range(100.0..130.0)
rng.gen_range(120.0 * frequency_multipler..180.0 * frequency_multipler)
} else if matches!(music_state, MusicState::Activity(MusicActivity::Explore))
&& matches!(client.current_site(), SitesKind::Dungeon)
{
rng.gen_range(10.0 * frequency_multipler..20.0 * frequency_multipler)
} else if matches!(music_state, MusicState::Activity(MusicActivity::Explore))
&& matches!(client.current_site(), SitesKind::Cave)
{
rng.gen_range(20.0 * frequency_multipler..40.0 * frequency_multipler)
} else if matches!(music_state, MusicState::Activity(MusicActivity::Explore)) {
rng.gen_range(90.0..180.0)
rng.gen_range(120.0 * frequency_multipler..240.0 * frequency_multipler)
} else if matches!(
music_state,
MusicState::Activity(MusicActivity::Combat(_)) | MusicState::Transition(_, _)
) {
0.0
} else {
rng.gen_range(30.0..60.0)
rng.gen_range(30.0 * frequency_multipler..60.0 * frequency_multipler)
};
let is_dark = (state.get_day_period().is_dark()) as bool;
@ -427,7 +452,15 @@ impl MusicMgr {
// println!("Now playing {:?}", track.title);
self.last_track = String::from(&track.title);
self.began_playing = Instant::now();
self.track_length = track.length;
self.next_track_change = track.length + silence_between_tracks_seconds;
if audio.music_enabled() {
self.current_track = String::from(&track.title);
self.current_artist = String::from(&track.artist);
} else {
self.current_track = String::from("None");
self.current_artist = String::from("None");
}
let tag = if matches!(music_state, MusicState::Activity(MusicActivity::Explore)) {
MusicChannelTag::Exploration
@ -481,6 +514,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
biomes,
site,
segments,
artist,
} => {
for (path, length, music_state, activity_override) in segments.into_iter() {
soundtracks.tracks.push(SoundtrackItem {
@ -493,6 +527,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
site,
music_state,
activity_override,
artist: artist.clone(),
});
}
},

View File

@ -265,6 +265,7 @@ widget_ids! {
graphics_backend,
gpu_timings[],
weather,
song_info,
// Game Version
version,
@ -493,6 +494,8 @@ pub struct DebugInfo {
pub num_figures_visible: u32,
pub num_particles: u32,
pub num_particles_visible: u32,
pub current_track: String,
pub current_artist: String,
}
pub struct HudInfo {
@ -2443,10 +2446,21 @@ impl Hud {
.font_size(self.fonts.cyri.scale(14))
.set(self.ids.current_site, ui_widgets);
// Current song info
Text::new(&format!(
"Currently playing: {} [{}]",
debug_info.current_track, debug_info.current_artist,
))
.color(TEXT_COLOR)
.down_from(self.ids.current_site, V_PAD)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(14))
.set(self.ids.song_info, ui_widgets);
// Number of lights
Text::new(&format!("Lights: {}", debug_info.num_lights,))
.color(TEXT_COLOR)
.down_from(self.ids.current_site, V_PAD)
.down_from(self.ids.song_info, V_PAD)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(14))
.set(self.ids.num_lights, ui_widgets);
@ -2525,7 +2539,7 @@ impl Hud {
// Set debug box dimensions, only timings height is dynamic
// TODO: Make the background box size fully dynamic
let debug_bg_size = [320.0, 385.0 + timings_height];
let debug_bg_size = [375.0, 405.0 + timings_height];
Rectangle::fill(debug_bg_size)
.rgba(0.0, 0.0, 0.0, global_state.settings.chat.chat_opacity)

View File

@ -34,6 +34,9 @@ widget_ids! {
ambience_volume_text,
ambience_volume_slider,
ambience_volume_number,
music_frequency_text,
music_frequency_slider,
music_frequency_number,
//audio_device_list,
//audio_device_text,
reset_sound_button,
@ -284,6 +287,41 @@ impl<'a> Widget for Sound<'a> {
.color(TEXT_COLOR)
.set(state.ids.ambience_volume_number, ui);
// Music frequency (actually gap between songs)
Text::new(self.localized_strings.get("hud.settings.music_frequency"))
.down_from(state.ids.ambience_volume_slider, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.music_frequency_text, ui);
// Music frequency Slider
if let Some(new_val) = ImageSlider::continuous(
self.global_state.settings.audio.music_frequency,
0.0,
2.0,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(104.0, 22.0)
.down_from(state.ids.music_frequency_text, 10.0)
.track_breadth(12.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.music_frequency_slider, ui)
{
events.push(AdjustMusicFrequency(new_val));
}
// Music frequency Number
Text::new(&format!(
"{:1.2}x",
self.global_state.settings.audio.music_frequency
))
.right_from(state.ids.music_frequency_slider, 8.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.music_frequency_number, ui);
// Audio Device Selector
// --------------------------------------------
// let device = &self.global_state.audio.device;
@ -316,7 +354,7 @@ impl<'a> Widget for Sound<'a> {
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
.hover_image(self.imgs.button_hover)
.press_image(self.imgs.button_press)
.down_from(state.ids.ambience_volume_slider, 12.0)
.down_from(state.ids.music_frequency_slider, 12.0)
.label(self.localized_strings.get("hud.settings.reset_sound"))
.label_font_size(self.fonts.cyri.scale(14))
.label_color(TEXT_COLOR)

View File

@ -104,7 +104,7 @@ pub struct Scene {
trail_mgr: TrailMgr,
figure_mgr: FigureMgr,
pub sfx_mgr: SfxMgr,
music_mgr: MusicMgr,
pub music_mgr: MusicMgr,
ambient_mgr: AmbientMgr,
integrated_rain_vel: f32,
@ -352,6 +352,8 @@ impl Scene {
/// Get a reference to the scene's figure manager.
pub fn figure_mgr(&self) -> &FigureMgr { &self.figure_mgr }
pub fn music_mgr(&self) -> &MusicMgr { &self.music_mgr }
/// Get a mutable reference to the scene's camera.
pub fn camera_mut(&mut self) -> &mut Camera { &mut self.camera }

View File

@ -1132,6 +1132,8 @@ impl PlayState for SessionState {
num_particles: self.scene.particle_mgr().particle_count() as u32,
num_particles_visible: self.scene.particle_mgr().particle_count_visible()
as u32,
current_track: self.scene.music_mgr().current_track.clone(),
current_artist: self.scene.music_mgr().current_artist.clone(),
}
});

View File

@ -23,6 +23,7 @@ pub enum Audio {
AdjustMusicVolume(f32),
AdjustSfxVolume(f32),
AdjustAmbienceVolume(f32),
AdjustMusicFrequency(f32),
//ChangeAudioDevice(String),
ResetAudioSettings,
}
@ -208,6 +209,11 @@ impl SettingsChange {
settings.audio.ambience_volume = ambience_volume;
},
Audio::AdjustMusicFrequency(multiplier) => {
global_state.audio.set_music_frequency(multiplier);
settings.audio.music_frequency = multiplier;
},
//Audio::ChangeAudioDevice(name) => {
// global_state.audio.set_device(name.clone());

View File

@ -28,6 +28,7 @@ pub struct AudioSettings {
pub ambience_volume: f32,
pub num_sfx_channels: usize,
pub num_ui_channels: usize,
pub music_frequency: f32,
/// Audio Device that Voxygen will use to play audio.
pub output: AudioOutput,
@ -43,6 +44,7 @@ impl Default for AudioSettings {
ambience_volume: 0.6,
num_sfx_channels: 60,
num_ui_channels: 10,
music_frequency: 1.0,
output: AudioOutput::Automatic,
}
}