From bbd0cf9178d816f1e8fff75258d88723ccf8a1c5 Mon Sep 17 00:00:00 2001 From: geneotech Date: Mon, 11 Mar 2024 22:33:53 +0100 Subject: [PATCH] Web audio: slight refactor, don't set pending_new_state_sample every frame in editor --- CMakeLists.txt | 4 +- src/application/gui/settings_gui.cpp | 2 +- src/augs/audio/OpenAL_error.h | 2 +- src/augs/audio/audio_command_buffers.h | 8 ++-- src/augs/audio/audio_context.cpp | 20 ++++++++-- src/augs/audio/sound_source.cpp | 14 +------ src/augs/audio/sound_source.h | 2 - .../systems/sound_system.cpp | 6 +-- .../audiovisual_state/systems/sound_system.h | 2 +- src/work.cpp | 38 +++++++++---------- 10 files changed, 48 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b6dd1f532..94f3ff5e96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1185,7 +1185,7 @@ if(CLANG) # -Wall and -Wextra cover everything already set(WARNINGS_FOR_OUR_CODE_ONLY " ") - set(DISABLED_WARNINGS "-Wno-error=unused-command-line-argument -Wno-error=missing-braces") + set(DISABLED_WARNINGS "-Wno-error=unused-command-line-argument -Wno-error=missing-braces -Wno-deprecated-enum-enum-conversion") if (APPLE) set(DISABLED_WARNINGS "${DISABLED_WARNINGS} -Wno-error=deprecated-declarations") @@ -1357,10 +1357,10 @@ if(BUILD_FOR_WEB) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sSAFE_HEAP=1 -sSTACK_OVERFLOW_CHECK=2 -Wno-limited-postlink-optimizations") set(STACK_SIZE "64MB") else() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=1") set(STACK_SIZE "16MB") endif() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=1") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ASSERTIONS=1") # There are some huge functions that can cause us to overflow with debug symbols set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s STACK_SIZE=${STACK_SIZE}") diff --git a/src/application/gui/settings_gui.cpp b/src/application/gui/settings_gui.cpp index b7677ac01f..1207fa84ea 100644 --- a/src/application/gui/settings_gui.cpp +++ b/src/application/gui/settings_gui.cpp @@ -767,7 +767,7 @@ void settings_gui_state::perform( { auto& scope_cfg = config.sound; -#if 0 +#if !IS_PRODUCTION_BUILD revertable_enum_radio(SCOPE_CFG_NVP(processing_frequency)); #endif diff --git a/src/augs/audio/OpenAL_error.h b/src/augs/audio/OpenAL_error.h index 22ddb05d5e..8d7da42064 100644 --- a/src/augs/audio/OpenAL_error.h +++ b/src/augs/audio/OpenAL_error.h @@ -1,6 +1,6 @@ #pragma once #if BUILD_OPENAL - #if IS_PRODUCTION_BUILD || PLATFORM_WEB + #if IS_PRODUCTION_BUILD #define AL_CHECK(stmt) (void)(stmt); #else void check_OpenAL_error(const char* stmt, const char* fname, int line); diff --git a/src/augs/audio/audio_command_buffers.h b/src/augs/audio/audio_command_buffers.h index 9ae6fda5be..ba4e362be7 100644 --- a/src/augs/audio/audio_command_buffers.h +++ b/src/augs/audio/audio_command_buffers.h @@ -8,11 +8,11 @@ #include "augs/audio/audio_command.h" #include "augs/audio/audio_backend.h" -static constexpr int num_audio_buffers_v = 2; +static constexpr int num_audio_buffers_v = 4; namespace augs { class audio_command_buffers { - thread_pool& pool_to_help; + thread_pool& pool_to_help_when_idle; audio_backend backend; std::optional audio_thread; @@ -78,7 +78,7 @@ namespace augs { if (has_finished()) { for_completion.notify_all(); - pool_to_help.help_until_no_tasks(); + pool_to_help_when_idle.help_until_no_tasks(); } } @@ -114,7 +114,7 @@ namespace augs { } public: - audio_command_buffers(thread_pool& pool_to_help) : pool_to_help(pool_to_help) { + audio_command_buffers(thread_pool& pool_to_help_when_idle) : pool_to_help_when_idle(pool_to_help_when_idle) { audio_thread.emplace(make_worker_lambda()); } diff --git a/src/augs/audio/audio_context.cpp b/src/augs/audio/audio_context.cpp index f779e51ba7..78c3635f5b 100644 --- a/src/augs/audio/audio_context.cpp +++ b/src/augs/audio/audio_context.cpp @@ -17,6 +17,11 @@ #define ALC_HRTF_REQUIRED_SOFT 0x0003 #define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004 #define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005 + +typedef ALCboolean (*ALC_RESET_DEVICE_SOFT)(ALCdevice *, const ALCint *attribs); + +ALC_RESET_DEVICE_SOFT alcResetDeviceSOFT; + #else #include #include @@ -177,10 +182,13 @@ namespace augs { #endif void audio_device::reset_device(audio_settings settings) { -#if BUILD_OPENAL && !PLATFORM_WEB +#if BUILD_OPENAL auto attrs = make_attrs(settings); - alcResetDeviceSOFT(device, &attrs[0]); + if ((bool)alcResetDeviceSOFT) { + alcResetDeviceSOFT(device, &attrs[0]); + } + AL_CHECK_DEVICE(device); log_hrtf_status(); #else @@ -206,6 +214,10 @@ namespace augs { ); } +#if PLATFORM_WEB + alcResetDeviceSOFT = reinterpret_cast(alcGetProcAddress(device, "alcResetDeviceSOFT")); +#endif + AL_CHECK(alEnable(AL_SOURCE_DISTANCE_MODEL)); device.log_hrtf_status(); @@ -277,8 +289,8 @@ namespace augs { return !(field == augs::get_corresponding_field(field, settings, current_settings)); }; - if (force - || changed(settings.enable_hrtf) + if (// force // don't have to force it since we're setting it on alcCreateContext + changed(settings.enable_hrtf) || changed(settings.max_number_of_sound_sources) ) { device.reset_device(settings); diff --git a/src/augs/audio/sound_source.cpp b/src/augs/audio/sound_source.cpp index 6829afed47..04c3c1d296 100644 --- a/src/augs/audio/sound_source.cpp +++ b/src/augs/audio/sound_source.cpp @@ -166,7 +166,9 @@ namespace augs { void sound_source::set_doppler_factor(const float factor) const { (void)factor; +#if !PLATFORM_WEB AL_CHECK(alSourcef(id, AL_DOPPLER_FACTOR, std::clamp(factor, 0.f, 1.f))); +#endif } void sound_source::set_spatialize(const bool f) const { @@ -282,18 +284,6 @@ namespace augs { #endif } - float sound_source::get_gain() const { - float gain = 0.f; - AL_CHECK(alGetSourcef(id, AL_GAIN, &gain)); - return gain; - } - - float sound_source::get_pitch() const { - float pitch = 0.f; - AL_CHECK(alGetSourcef(id, AL_PITCH, &pitch)); - return pitch; - } - bool sound_source::is_playing() const { #if BUILD_OPENAL if (stopped) { diff --git a/src/augs/audio/sound_source.h b/src/augs/audio/sound_source.h index 16a2781729..e11232f6b0 100644 --- a/src/augs/audio/sound_source.h +++ b/src/augs/audio/sound_source.h @@ -63,8 +63,6 @@ namespace augs { void set_spatialize(bool) const; float get_time_in_seconds() const; - float get_gain() const; - float get_pitch() const; bool is_playing() const; void bind_buffer(const single_sound_buffer&); diff --git a/src/view/audiovisual_state/systems/sound_system.cpp b/src/view/audiovisual_state/systems/sound_system.cpp index 22120562dd..71d59c860d 100644 --- a/src/view/audiovisual_state/systems/sound_system.cpp +++ b/src/view/audiovisual_state/systems/sound_system.cpp @@ -42,8 +42,8 @@ const cosmos& sound_system::update_properties_input::get_cosmos() const { return ear.viewed_character.get_cosmos(); } -bool sound_system::update_properties_input::under_short_sound_limit() const { - return static_cast(owner.short_sounds.size()) < settings.max_short_sounds; +bool sound_system::update_properties_input::short_sound_limit_exceeded() const { + return static_cast(owner.short_sounds.size()) >= settings.max_short_sounds; } void sound_system::clear() { @@ -571,7 +571,7 @@ void sound_system::update_effects_from_messages(const const_logic_step step, con } if (in.settings.max_short_sounds > 0 && !id_pool.full() && short_sounds.size() < short_sounds.max_size()) { - if (!in.under_short_sound_limit()) { + if (in.short_sound_limit_exceeded()) { if (short_sounds.size() > 0) { short_sounds[0].stop_and_free(in); short_sounds.erase(short_sounds.begin()); diff --git a/src/view/audiovisual_state/systems/sound_system.h b/src/view/audiovisual_state/systems/sound_system.h index 18d43e5389..87d84dd286 100644 --- a/src/view/audiovisual_state/systems/sound_system.h +++ b/src/view/audiovisual_state/systems/sound_system.h @@ -69,7 +69,7 @@ class sound_system { const_entity_handle get_listener() const; std::optional find_transform(const absolute_or_local&) const; - bool under_short_sound_limit() const; + bool short_sound_limit_exceeded() const; }; struct effect_not_found {}; diff --git a/src/work.cpp b/src/work.cpp index cbf09664e0..fefaa27c15 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -3033,11 +3033,6 @@ work_result work( DEBUG_LOGIC_STEP_LINES.clear(); }; - /* - The audiovisual_step, advance_setup and advance_current_setup lambdas - are separated only because MSVC outputs ICEs if they become nested. - */ - WEBSTATIC visible_entities all_visible; WEBSTATIC auto get_character_camera = [&](const config_lua_table& viewing_config) -> character_camera { @@ -3376,7 +3371,9 @@ work_result work( #endif if constexpr(std::is_same_v) { - pending_new_state_sample = true; + if (!setup.is_playtesting()) { + pending_new_state_sample = true; + } } setup.advance( @@ -3421,6 +3418,16 @@ work_result work( const augs::delta frame_delta, const input_pass_result& result ) { + /* + Advance the current setup's logic, + and let the audiovisual_state sample the game world + that it chooses via get_viewed_cosmos. + + This also advances the audiovisual state, based on the cosmos returned by the setup. + */ + + auto scope = measure_scope(game_thread_performance.advance_setup); + visit_current_setup( [&](auto& setup) { advance_setup(audio_renderer, frame_delta, setup, result); @@ -4032,19 +4039,6 @@ work_result work( }); }; - auto do_advance_setup = [&](const augs::audio_renderer* const audio_renderer, auto& with_result) { - /* - Advance the current setup's logic, - and let the audiovisual_state sample the game world - that it chooses via get_viewed_cosmos. - - This also advances the audiovisual state, based on the cosmos returned by the setup. - */ - - auto scope = measure_scope(game_thread_performance.advance_setup); - advance_current_setup(audio_renderer, frame_delta, with_result); - }; - auto create_viewing_game_gui_context = [&](augs::renderer& chosen_renderer, const config_lua_table& viewing_config) { return viewing_game_gui_context { make_create_game_gui_context(viewing_config)(), @@ -4416,7 +4410,11 @@ work_result work( audio_renderer.emplace(augs::audio_renderer { *audio_buffer }); } - do_advance_setup(audio_renderer ? std::addressof(audio_renderer.value()) : nullptr, input_result); + advance_current_setup( + audio_renderer ? std::addressof(audio_renderer.value()) : nullptr, + frame_delta, + input_result + ); auto create_menu_context = make_create_menu_context(new_viewing_config); auto create_game_gui_context = make_create_game_gui_context(new_viewing_config);