mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'DaforLynx/music-additions' into 'master'
WIP: New music, "now playing" line in debug overlay, and music frequency slider See merge request veloren/veloren!3501
This commit is contained in:
commit
0f3eb6cb3f
@ -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
|
||||
|
||||
|
@ -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
BIN
assets/voxygen/audio/soundtrack/overworld/moonlit_canopy.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/overworld/the_undergrowth.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/overworld/the_undergrowth.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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",
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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(),
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user