From efe7af2b8b54f4090148e3592e489acfea24e8ff Mon Sep 17 00:00:00 2001 From: geneotech Date: Fri, 15 Mar 2024 19:45:01 +0100 Subject: [PATCH] Web: Periodic audio updates (10 Hz default) --- CMakeLists.txt | 8 +- src/application/gui/settings_gui.cpp | 8 +- src/game/stateless_systems/item_system.cpp | 6 +- .../audiovisual_state/audiovisual_state.cpp | 153 ++++++++++++------ .../audiovisual_state/audiovisual_state.h | 4 + .../systems/sound_system.cpp | 142 +++++++++------- .../audiovisual_state/systems/sound_system.h | 2 + .../systems/sound_system_settings.h | 2 + src/work.cpp | 1 + 9 files changed, 210 insertions(+), 116 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94f3ff5e9..bc0faeec6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1353,11 +1353,13 @@ if(BUILD_FOR_WEB) endif() if(GENERATE_DEBUG_INFORMATION) - set(ADDITIONAL_WEB_FLAGS "${ADDITIONAL_WEB_FLAGS} -g") + set(ADDITIONAL_WEB_FLAGS "${ADDITIONAL_WEB_FLAGS} -g -gsource-map") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sSAFE_HEAP=1 -sSTACK_OVERFLOW_CHECK=2 -Wno-limited-postlink-optimizations") - set(STACK_SIZE "64MB") + set(STACK_SIZE "32MB") + set(INITIAL_MEMORY "1800MB") else() set(STACK_SIZE "16MB") + set(INITIAL_MEMORY "1024MB") endif() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=1") @@ -1366,7 +1368,7 @@ if(BUILD_FOR_WEB) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STACK_SIZE=${STACK_SIZE}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread -s USE_PTHREADS=1 -sPTHREAD_POOL_SIZE=navigator.hardwareConcurrency") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s INITIAL_MEMORY=1500MB") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s INITIAL_MEMORY=${INITIAL_MEMORY}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mbulk-memory") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ADDITIONAL_WEB_FLAGS}") diff --git a/src/application/gui/settings_gui.cpp b/src/application/gui/settings_gui.cpp index 1207fa84e..6a86202bb 100644 --- a/src/application/gui/settings_gui.cpp +++ b/src/application/gui/settings_gui.cpp @@ -767,9 +767,13 @@ void settings_gui_state::perform( { auto& scope_cfg = config.sound; -#if !IS_PRODUCTION_BUILD revertable_enum_radio(SCOPE_CFG_NVP(processing_frequency)); -#endif + + if (scope_cfg.processing_frequency == sound_processing_frequency::PERIODIC) { + auto indent = scoped_indent(); + + revertable_slider("Hz", scope_cfg.custom_processing_frequency, 1, 60); + } revertable_slider(SCOPE_CFG_NVP(max_simultaneous_bullet_trace_sounds), 0, 20); revertable_slider(SCOPE_CFG_NVP(max_short_sounds), 0, static_cast(SOUNDS_SOURCES_IN_POOL)); diff --git a/src/game/stateless_systems/item_system.cpp b/src/game/stateless_systems/item_system.cpp index 4f8b51fd9..d6fbee384 100644 --- a/src/game/stateless_systems/item_system.cpp +++ b/src/game/stateless_systems/item_system.cpp @@ -105,7 +105,7 @@ void maybe_reload_akimbo(components::item_slot_transfers& transfers, const T& ca auto& cosm = capability.get_cosmos(); - LOG("Resetting akimbo in maybe_reload_akimbo"); + RLD_LOG("Resetting akimbo in maybe_reload_akimbo"); akimbo = {}; if (ctx.alive(cosm)) { @@ -123,11 +123,11 @@ void maybe_reload_akimbo(components::item_slot_transfers& transfers, const T& ca LOG_NVPS(next_to_reload_idx, akimbo.next); } else { - LOG("No two guns found to consider for akimbo"); + RLD_LOG("No two guns found to consider for akimbo"); } } else { - LOG("No context found to consider for akimbo extension"); + RLD_LOG("No context found to consider for akimbo extension"); } } diff --git a/src/view/audiovisual_state/audiovisual_state.cpp b/src/view/audiovisual_state/audiovisual_state.cpp index 2ca05bb7d..fc5a99d75 100644 --- a/src/view/audiovisual_state/audiovisual_state.cpp +++ b/src/view/audiovisual_state/audiovisual_state.cpp @@ -31,6 +31,7 @@ #include "game/detail/visible_entities.hpp" #include "game/detail/sentience/sentience_getters.h" #include "view/damage_indication_settings.h" +//#include "augs/log.h" template void interpolation_system::set_updated_interpolated_transform( @@ -70,8 +71,8 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { auto scaled_state_dt = state_dt; - auto dt = frame_dt; - dt *= input.speed_multiplier; + auto scaled_frame_dt = frame_dt; + scaled_frame_dt *= input.speed_multiplier; if (scaled_state_dt) { *scaled_state_dt *= input.speed_multiplier; @@ -102,14 +103,14 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { cone_for_explosion_particles, cosm.get_common_assets(), input.particle_effects, - dt, + scaled_frame_dt, input.performance.special_effects.explosions, particles ); }; auto advance_attenuation_variations = [&]() { - get().advance_attenuation_variations(rng, cosm, dt); + get().advance_attenuation_variations(rng, cosm, scaled_frame_dt); }; auto advance_world_hover_highlighter = [&]() { @@ -118,15 +119,15 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { }; auto advance_thunders = [&]() { - thunders.advance(rng, cosm, queried_cone, input.particle_effects, dt, particles); + thunders.advance(rng, cosm, queried_cone, input.particle_effects, scaled_frame_dt, particles); }; auto advance_damage_indication = [&]() { - damage_indication.advance(input.damage_indication, dt); + damage_indication.advance(input.damage_indication, scaled_frame_dt); }; auto advance_highlights = [&]() { - highlights.advance(dt); + highlights.advance(scaled_frame_dt); }; auto advance_visible_particle_streams = [&]() { @@ -139,7 +140,7 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { cosm, input.particle_effects, anims, - dt, + scaled_frame_dt, interp ); }; @@ -158,7 +159,7 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { advance_damage_indication(); - randomizing.advance(dt); + randomizing.advance(scaled_frame_dt); }; auto launch_particle_jobs = [&]() { @@ -166,7 +167,7 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { particles.integrate_and_draw_all_particles({ cosm, - dt, + scaled_frame_dt, interp, input.game_images, anims, @@ -218,10 +219,10 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { [&](const auto typed_wandering_pixels) { const auto wandering_id = typed_wandering_pixels.get_id(); - auto job = [&cosm, &triangles, current_index, &wandering_pixels, &game_images, wandering_id, dt]() { + auto job = [&cosm, &triangles, current_index, &wandering_pixels, &game_images, wandering_id, scaled_frame_dt]() { auto handle = cosm[wandering_id]; - wandering_pixels.advance_for(handle, dt); + wandering_pixels.advance_for(handle, scaled_frame_dt); draw_wandering_pixels_as_sprites(triangles, current_index, wandering_pixels, handle, game_images); }; @@ -255,10 +256,10 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { [&](const auto typed_wandering_pixels) { const auto wandering_id = typed_wandering_pixels.get_id(); - auto job = [&cosm, &triangles, current_index, &wandering_pixels, &game_images, wandering_id, dt]() { + auto job = [&cosm, &triangles, current_index, &wandering_pixels, &game_images, wandering_id, scaled_frame_dt]() { auto handle = cosm[wandering_id]; - wandering_pixels.advance_for(handle, dt); + wandering_pixels.advance_for(handle, scaled_frame_dt); draw_wandering_pixels_as_sprites(triangles, current_index, wandering_pixels, handle, game_images); }; @@ -274,49 +275,38 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { const auto& sound_freq = input.sound_settings.processing_frequency; const bool sound_every_step = sound_freq == sound_processing_frequency::EVERY_SIMULATION_STEP; + const bool sound_periodic = sound_freq == sound_processing_frequency::PERIODIC; + const auto sound_processing_frequency = std::max(1, input.sound_settings.custom_processing_frequency); - const auto chosen_update_dt = sound_every_step ? *scaled_state_dt : dt; + const auto periodic_dt = augs::delta::steps_per_second(sound_processing_frequency); + auto scaled_periodic_dt = periodic_dt; + scaled_periodic_dt *= input.speed_multiplier; - /* Fading should take the same amount of time regardless of audiovisual speed multiplier */ - const auto chosen_fade_dt = sound_every_step ? *state_dt : frame_dt; - - auto audio_job = [this, input, chosen_update_dt, chosen_fade_dt]() { - auto scope = measure_scope(performance.sound_logic); + const auto chosen_update_dt = [&]() { + if (sound_every_step) { + return *scaled_state_dt; + } - const auto viewed_character = input.camera.viewed_character; - auto& interpol = this->get(); + if (sound_periodic) { + return scaled_periodic_dt; + } - auto& command_buffers = input.command_buffers; + return scaled_frame_dt; + }(); - { - auto ear = input.camera; + /* Fading should take the same amount of time regardless of audiovisual speed multiplier */ - if (viewed_character) { - ear.cone.eye.transform = viewed_character.get_viewing_transform(interpol); - } - - this->get().update_sound_properties( - { - *input.audio_renderer, - this->get(), - input.audio_volume, - input.sound_settings, - input.sounds, - interpol, - ear, - ear.cone, - chosen_update_dt, - input.speed_multiplier, - input.inv_tickrate, - input.interpolation_ratio - } - ); + const auto chosen_fade_dt = [&]() { + if (sound_every_step) { + return *state_dt; } - this->get().fade_sources(*input.audio_renderer, chosen_fade_dt); + if (sound_periodic) { + return periodic_dt; + } - command_buffers.submit_write_buffer(); - }; + return frame_dt; + }(); synchronous_facade(); @@ -332,6 +322,22 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { return true; } + if (sound_freq == sound_processing_frequency::PERIODIC) { + if (input.sound_settings.custom_processing_frequency <= 0) { + return false; + } + + const auto interval = 1.0f / input.sound_settings.custom_processing_frequency; + + if (periodic_audio_update_timer.get() >= interval) { + periodic_audio_update_timer.reset(); + + return true; + } + + return false; + } + if (sound_every_step) { return input.new_state_delta.has_value(); } @@ -339,9 +345,51 @@ void audiovisual_state::advance(const audiovisual_advance_input input) { return false; }(); - if (should_update_audio) { - input.pool.enqueue(audio_job); - } + auto audio_job = [this, should_update_audio, input, chosen_update_dt, chosen_fade_dt, scaled_frame_dt]() { + auto scope = measure_scope(performance.sound_logic); + + if (should_update_audio) { + const auto viewed_character = input.camera.viewed_character; + auto& interpol = this->get(); + + { + auto ear = input.camera; + + if (viewed_character) { + ear.cone.eye.transform = viewed_character.get_viewing_transform(interpol); + } + + this->get().update_sound_properties( + { + *input.audio_renderer, + this->get(), + input.audio_volume, + input.sound_settings, + input.sounds, + interpol, + ear, + ear.cone, + chosen_update_dt, + input.speed_multiplier, + input.inv_tickrate, + input.interpolation_ratio + } + ); + } + + this->get().fade_sources(*input.audio_renderer, chosen_fade_dt); + } + + this->get().update_elapsed_times( + scaled_frame_dt + ); + + if (input.audio_renderer != nullptr) { + input.command_buffers.submit_write_buffer(); + } + }; + + input.pool.enqueue(audio_job); } void audiovisual_state::spread_past_infection(const const_logic_step step) { @@ -481,6 +529,9 @@ void audiovisual_state::standard_post_solve( } ); } + else { + //LOG("NO AUDIO RENDERER!"); + } } diff --git a/src/view/audiovisual_state/audiovisual_state.h b/src/view/audiovisual_state/audiovisual_state.h index b9a1257a4..e0d1bf9aa 100644 --- a/src/view/audiovisual_state/audiovisual_state.h +++ b/src/view/audiovisual_state/audiovisual_state.h @@ -25,6 +25,7 @@ #include "view/audiovisual_state/particle_triangle_buffers.h" #include "application/performance_settings.h" #include "view/character_camera.h" +#include "augs/misc/timing/timer.h" class cosmos; class visible_entities; @@ -103,6 +104,9 @@ struct audiovisual_state { void reserve_caches_for_entities(const std::size_t); private: + + augs::timer periodic_audio_update_timer; + randomization& get_rng() { return randomizing.rng; } diff --git a/src/view/audiovisual_state/systems/sound_system.cpp b/src/view/audiovisual_state/systems/sound_system.cpp index 71d59c860..11817fcfb 100644 --- a/src/view/audiovisual_state/systems/sound_system.cpp +++ b/src/view/audiovisual_state/systems/sound_system.cpp @@ -243,6 +243,17 @@ void sound_system::generic_sound_cache::eat_followup() { followup_inputs.erase(followup_inputs.begin()); } +void sound_system::generic_sound_cache::update_elapsed(const augs::delta dt) { + const auto& input = original.input; + const auto& m = input.modifier; + const auto dt_this_frame = dt.in_seconds() * m.pitch; + const bool gain_dependent_lifetime = original.start.silent_trace_like; + + if (!gain_dependent_lifetime) { + elapsed_secs += dt_this_frame; + } +} + void sound_system::generic_sound_cache::update_properties(const update_properties_input in) { const auto listening_character = in.get_listener(); @@ -252,10 +263,6 @@ void sound_system::generic_sound_cache::update_properties(const update_propertie const auto dt_this_frame = in.dt.in_seconds() * m.pitch; const bool gain_dependent_lifetime = original.start.silent_trace_like; - if (!gain_dependent_lifetime) { - elapsed_secs += dt_this_frame; - } - const auto listening_faction = (listening_character ? listening_character.get_official_faction() : faction_type::SPECTATOR); const auto target_faction = original.start.listener_faction; @@ -637,6 +644,80 @@ void sound_system::advance_flash(const const_entity_handle listener, const augs: } } +void sound_system::update_elapsed_times(const augs::delta dt) { + silent_trace_cooldown += dt.in_milliseconds(); + + if (silent_trace_cooldown > 150.f) { + silent_trace_cooldown = 0.f; + + --current_num_silent_traces; + + if (current_num_silent_traces < 0) { + current_num_silent_traces = 0; + } + } + + auto update_facade = [&](auto& cache) { + cache.update_elapsed(dt); + }; + + for (auto& it : firearm_engine_caches) { + auto& cache = it.second.cache; + update_facade(cache); + } + + for (auto& it : continuous_sound_caches) { + auto& cache = it.second.cache; + update_facade(cache); + } + + for (auto& it : short_sounds) { + update_facade(it); + } + + erase_if (collision_sound_successions, [&](auto& it) { + auto& c = it.second; + + c.remaining_ms -= dt.in_milliseconds(); + + if (c.remaining_ms <= 0.f) { + return true; + } + + return false; + }); + + erase_if (collision_sound_cooldowns, [&](auto& it) { + auto& c = it.second; + + c -= dt.in_milliseconds(); + + if (c <= 0.f) { + return true; + } + + return false; + }); + + erase_if (damage_sound_successions, [&](auto& it) { + auto& c = it.second; + + c.current_ms += dt.in_milliseconds(); + + if (c.current_ms > c.max_ms) { + c.current_ms = 0.f; + --c.consecutive_occurences; + + if (0 == c.consecutive_occurences) { + return true; + } + } + + return false; + }); + +} + void sound_system::update_sound_properties(const update_properties_input in) { const auto& renderer = in.renderer; @@ -650,18 +731,6 @@ void sound_system::update_sound_properties(const update_properties_input in) { screen_center ); - silent_trace_cooldown += in.dt.in_milliseconds(); - - if (silent_trace_cooldown > 150.f) { - silent_trace_cooldown = 0.f; - - --current_num_silent_traces; - - if (current_num_silent_traces < 0) { - current_num_silent_traces = 0; - } - } - const auto& cosm = in.get_cosmos(); { @@ -971,47 +1040,6 @@ void sound_system::fade_sources( const augs::audio_renderer& renderer, const augs::delta dt ) { - erase_if (collision_sound_successions, [&](auto& it) { - auto& c = it.second; - - c.remaining_ms -= dt.in_milliseconds(); - - if (c.remaining_ms <= 0.f) { - return true; - } - - return false; - }); - - erase_if (collision_sound_cooldowns, [&](auto& it) { - auto& c = it.second; - - c -= dt.in_milliseconds(); - - if (c <= 0.f) { - return true; - } - - return false; - }); - - erase_if (damage_sound_successions, [&](auto& it) { - auto& c = it.second; - - c.current_ms += dt.in_milliseconds(); - - if (c.current_ms > c.max_ms) { - c.current_ms = 0.f; - --c.consecutive_occurences; - - if (0 == c.consecutive_occurences) { - return true; - } - } - - return false; - }); - erase_if(fading_sources, [this, dt, &renderer](fading_source& f) { const auto proxy = augs::sound_source_proxy { renderer, f.source }; diff --git a/src/view/audiovisual_state/systems/sound_system.h b/src/view/audiovisual_state/systems/sound_system.h index 87d84dd28..c092cc6bb 100644 --- a/src/view/audiovisual_state/systems/sound_system.h +++ b/src/view/audiovisual_state/systems/sound_system.h @@ -104,6 +104,7 @@ class sound_system { bool should_play(update_properties_input in) const; bool rebind_buffer(update_properties_input in); void update_properties(update_properties_input in); + void update_elapsed(augs::delta dt); augs::sound_source_proxy get_proxy(const update_properties_input& in); void stop_and_free(const update_properties_input& in); @@ -189,6 +190,7 @@ class sound_system { void update_effects_from_messages(const_logic_step, update_properties_input); void update_sound_properties(update_properties_input); + void update_elapsed_times(const augs::delta scaled_frame_dt); void fade_sources( const augs::audio_renderer& renderer, diff --git a/src/view/audiovisual_state/systems/sound_system_settings.h b/src/view/audiovisual_state/systems/sound_system_settings.h index 18d639a39..9165bdd26 100644 --- a/src/view/audiovisual_state/systems/sound_system_settings.h +++ b/src/view/audiovisual_state/systems/sound_system_settings.h @@ -4,6 +4,7 @@ enum class sound_processing_frequency { // GEN INTROSPECTOR enum class sound_processing_frequency EVERY_SINGLE_FRAME, EVERY_SIMULATION_STEP, + PERIODIC, COUNT // END GEN INTROSPECTOR @@ -36,5 +37,6 @@ struct sound_system_settings { int max_short_sounds = 64; sound_processing_frequency processing_frequency = sound_processing_frequency::EVERY_SIMULATION_STEP; + int custom_processing_frequency = 10; // END GEN INTROSPECTOR }; diff --git a/src/work.cpp b/src/work.cpp index fefaa27c1..e11bb358e 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -392,6 +392,7 @@ work_result work( #if PLATFORM_WEB result.window.fullscreen = false; + result.sound.processing_frequency = sound_processing_frequency::PERIODIC; #endif return result_ptr;