From c9cd0d20ef01edafde3b1d758097af402fff1364 Mon Sep 17 00:00:00 2001 From: DS Date: Wed, 3 Jan 2024 21:57:00 +0100 Subject: [PATCH] Use AL_SOFT_direct_channels_remix extension for non-positional stereo sounds (#14195) --- builtin/settingtypes.txt | 5 ++ src/client/CMakeLists.txt | 1 + src/client/sound/al_extensions.cpp | 58 +++++++++++++++++++++++ src/client/sound/al_extensions.h | 38 +++++++++++++++ src/client/sound/al_helpers.cpp | 2 +- src/client/sound/al_helpers.h | 2 +- src/client/sound/ogg_file.cpp | 2 +- src/client/sound/ogg_file.h | 2 +- src/client/sound/playing_sound.cpp | 15 +++++- src/client/sound/playing_sound.h | 6 ++- src/client/sound/proxy_sound_manager.cpp | 2 +- src/client/sound/proxy_sound_manager.h | 2 +- src/client/sound/sound_constants.h | 2 +- src/client/sound/sound_data.cpp | 2 +- src/client/sound/sound_data.h | 2 +- src/client/sound/sound_manager.cpp | 7 +-- src/client/sound/sound_manager.h | 9 ++-- src/client/sound/sound_manager_messages.h | 2 +- src/client/sound/sound_openal.cpp | 2 +- src/client/sound/sound_singleton.cpp | 2 +- src/client/sound/sound_singleton.h | 2 +- src/defaultsettings.cpp | 1 + 22 files changed, 143 insertions(+), 23 deletions(-) create mode 100644 src/client/sound/al_extensions.cpp create mode 100644 src/client/sound/al_extensions.h diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 0af96cc33..fbc18e318 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1870,6 +1870,11 @@ texture_min_size (Base texture size) int 64 1 32768 # Systems with a low-end GPU (or no GPU) would benefit from smaller values. client_mesh_chunk (Client Mesh Chunksize) int 1 1 16 +[**Sound] +# Comma-separated list of AL and ALC extensions that should not be used. +# Useful for testing. See al_extensions.[h,cpp] for details. +sound_extensions_blacklist (Sound Extensions Blacklist) string + [**Font] font_bold (Font bold by default) bool false diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 5ec61795a..846a5b782 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -2,6 +2,7 @@ set(sound_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/sound.cpp) if(USE_SOUND) set(sound_SRCS ${sound_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/sound/al_extensions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sound/al_helpers.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sound/ogg_file.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sound/playing_sound.cpp diff --git a/src/client/sound/al_extensions.cpp b/src/client/sound/al_extensions.cpp new file mode 100644 index 000000000..bc696be35 --- /dev/null +++ b/src/client/sound/al_extensions.cpp @@ -0,0 +1,58 @@ +/* +Minetest +Copyright (C) 2023 DS + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "al_extensions.h" + +#include "settings.h" +#include "util/string.h" +#include + +namespace sound { + +ALExtensions::ALExtensions(const ALCdevice *deviceHandle [[maybe_unused]]) +{ + auto blacklist_vec = str_split(g_settings->get("sound_extensions_blacklist"), ','); + for (auto &s : blacklist_vec) { + s = trim(s); + } + std::unordered_set blacklist; + blacklist.insert(blacklist_vec.begin(), blacklist_vec.end()); + + { + constexpr const char *ext_name = "AL_SOFT_direct_channels_remix"; + bool blacklisted = blacklist.find(ext_name) != blacklist.end(); + if (blacklisted) + infostream << "ALExtensions: Blacklisted: " << ext_name << std::endl; +#ifndef AL_SOFT_direct_channels_remix + infostream << "ALExtensions: Not compiled with: " << ext_name << std::endl; +#else + bool found = alIsExtensionPresent(ext_name); + if (found) + infostream << "ALExtensions: Found: " << ext_name << std::endl; + else + infostream << "ALExtensions: Not found: " << ext_name << std::endl; + + if (found && !blacklisted) { + have_ext_AL_SOFT_direct_channels_remix = true; + } +#endif + } +} + +} diff --git a/src/client/sound/al_extensions.h b/src/client/sound/al_extensions.h new file mode 100644 index 000000000..cfa270d06 --- /dev/null +++ b/src/client/sound/al_extensions.h @@ -0,0 +1,38 @@ +/* +Minetest +Copyright (C) 2023 DS + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "al_helpers.h" + +namespace sound { + +/** + * Struct for AL and ALC extensions + */ +struct ALExtensions +{ + explicit ALExtensions(const ALCdevice *deviceHandle [[maybe_unused]]); + +#ifdef AL_SOFT_direct_channels_remix + bool have_ext_AL_SOFT_direct_channels_remix = false; +#endif +}; + +} diff --git a/src/client/sound/al_helpers.cpp b/src/client/sound/al_helpers.cpp index 3db3c6f61..e3b7bda94 100644 --- a/src/client/sound/al_helpers.cpp +++ b/src/client/sound/al_helpers.cpp @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/al_helpers.h b/src/client/sound/al_helpers.h index 5f0ba0089..566d9deeb 100644 --- a/src/client/sound/al_helpers.h +++ b/src/client/sound/al_helpers.h @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/ogg_file.cpp b/src/client/sound/ogg_file.cpp index 46c3427de..62cc71327 100644 --- a/src/client/sound/ogg_file.cpp +++ b/src/client/sound/ogg_file.cpp @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/ogg_file.h b/src/client/sound/ogg_file.h index 177357337..5054a6e64 100644 --- a/src/client/sound/ogg_file.h +++ b/src/client/sound/ogg_file.h @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/playing_sound.cpp b/src/client/sound/playing_sound.cpp index a1570d42f..3cc41fc50 100644 --- a/src/client/sound/playing_sound.cpp +++ b/src/client/sound/playing_sound.cpp @@ -18,12 +18,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "playing_sound.h" +#include "al_extensions.h" #include "debug.h" #include #include @@ -32,7 +33,8 @@ namespace sound { PlayingSound::PlayingSound(ALuint source_id, std::shared_ptr data, bool loop, f32 volume, f32 pitch, f32 start_time, - const std::optional> &pos_vel_opt) + const std::optional> &pos_vel_opt, + const ALExtensions &exts [[maybe_unused]]) : m_source_id(source_id), m_data(std::move(data)), m_looping(loop), m_is_positional(pos_vel_opt.has_value()) { @@ -113,6 +115,15 @@ PlayingSound::PlayingSound(ALuint source_id, std::shared_ptr dat alSource3f(m_source_id, AL_POSITION, 0.0f, 0.0f, 0.0f); alSource3f(m_source_id, AL_VELOCITY, 0.0f, 0.0f, 0.0f); warn_if_al_error("PlayingSound::PlayingSound at making position-less"); + +#ifdef AL_SOFT_direct_channels_remix + // Play directly on stereo output channels if possible. Improves sound quality. + if (exts.have_ext_AL_SOFT_direct_channels_remix + && m_data->m_decode_info.is_stereo) { + alSourcei(m_source_id, AL_DIRECT_CHANNELS_SOFT, AL_REMIX_UNMATCHED_SOFT); + warn_if_al_error("PlayingSound::PlayingSound at setting AL_DIRECT_CHANNELS_SOFT"); + } +#endif } setGain(volume); setPitch(pitch); diff --git a/src/client/sound/playing_sound.h b/src/client/sound/playing_sound.h index 1fbf37e3e..dcc680e09 100644 --- a/src/client/sound/playing_sound.h +++ b/src/client/sound/playing_sound.h @@ -18,13 +18,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include "sound_data.h" +namespace sound { struct ALExtensions; } namespace sound { @@ -51,7 +52,8 @@ class PlayingSound final public: PlayingSound(ALuint source_id, std::shared_ptr data, bool loop, f32 volume, f32 pitch, f32 start_time, - const std::optional> &pos_vel_opt); + const std::optional> &pos_vel_opt, + const ALExtensions &exts [[maybe_unused]]); ~PlayingSound() noexcept { diff --git a/src/client/sound/proxy_sound_manager.cpp b/src/client/sound/proxy_sound_manager.cpp index ede603e67..266e68e00 100644 --- a/src/client/sound/proxy_sound_manager.cpp +++ b/src/client/sound/proxy_sound_manager.cpp @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/proxy_sound_manager.h b/src/client/sound/proxy_sound_manager.h index 53299e045..edad70baa 100644 --- a/src/client/sound/proxy_sound_manager.h +++ b/src/client/sound/proxy_sound_manager.h @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_constants.h b/src/client/sound/sound_constants.h index 94d74b86c..d55575320 100644 --- a/src/client/sound/sound_constants.h +++ b/src/client/sound/sound_constants.h @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_data.cpp b/src/client/sound/sound_data.cpp index d2d626e2c..261549d38 100644 --- a/src/client/sound/sound_data.cpp +++ b/src/client/sound/sound_data.cpp @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_data.h b/src/client/sound/sound_data.h index 36052c161..67fcd7756 100644 --- a/src/client/sound/sound_data.h +++ b/src/client/sound/sound_data.h @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_manager.cpp b/src/client/sound/sound_manager.cpp index 97537cc0f..679d3a155 100644 --- a/src/client/sound/sound_manager.cpp +++ b/src/client/sound/sound_manager.cpp @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -181,7 +181,7 @@ std::shared_ptr OpenALSoundManager::createPlayingSound( } auto sound = std::make_shared(source_id, std::move(lsnd), loop, - volume, pitch, start_time, pos_vel_opt); + volume, pitch, start_time, pos_vel_opt, m_exts); sound->play(); @@ -271,7 +271,8 @@ OpenALSoundManager::OpenALSoundManager(SoundManagerSingleton *smg, Thread("OpenALSoundManager"), m_fallback_path_provider(std::move(fallback_path_provider)), m_device(smg->m_device.get()), - m_context(smg->m_context.get()) + m_context(smg->m_context.get()), + m_exts(m_device) { SANITY_CHECK(!!m_fallback_path_provider); diff --git a/src/client/sound/sound_manager.h b/src/client/sound/sound_manager.h index 8d0ccf837..2a631db02 100644 --- a/src/client/sound/sound_manager.h +++ b/src/client/sound/sound_manager.h @@ -18,13 +18,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include "playing_sound.h" +#include "al_extensions.h" #include "sound_constants.h" #include "sound_manager_messages.h" #include "../sound.h" @@ -51,8 +52,10 @@ class OpenALSoundManager final : public Thread private: std::unique_ptr m_fallback_path_provider; - ALCdevice *m_device; - ALCcontext *m_context; + ALCdevice *const m_device; + ALCcontext *const m_context; + + const ALExtensions m_exts; // time in seconds until which removeDeadSounds will be called again f32 m_time_until_dead_removal = REMOVE_DEAD_SOUNDS_INTERVAL; diff --git a/src/client/sound/sound_manager_messages.h b/src/client/sound/sound_manager_messages.h index 41f4ffac1..e33729705 100644 --- a/src/client/sound/sound_manager_messages.h +++ b/src/client/sound/sound_manager_messages.h @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_openal.cpp b/src/client/sound/sound_openal.cpp index 89f4b57ad..d44a1fbe2 100644 --- a/src/client/sound/sound_openal.cpp +++ b/src/client/sound/sound_openal.cpp @@ -17,7 +17,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_singleton.cpp b/src/client/sound/sound_singleton.cpp index 4a600243c..dff339be0 100644 --- a/src/client/sound/sound_singleton.cpp +++ b/src/client/sound/sound_singleton.cpp @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/client/sound/sound_singleton.h b/src/client/sound/sound_singleton.h index 5168c1c9b..32cd2d4f8 100644 --- a/src/client/sound/sound_singleton.h +++ b/src/client/sound/sound_singleton.h @@ -18,7 +18,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along -with this program; ifnot, write to the Free Software Foundation, Inc., +with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 4505bdc2c..48bc76fdb 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -42,6 +42,7 @@ void set_default_settings() settings->setDefault("sound_volume", "0.8"); settings->setDefault("sound_volume_unfocused", "0.3"); settings->setDefault("mute_sound", "false"); + settings->setDefault("sound_extensions_blacklist", ""); settings->setDefault("enable_mesh_cache", "false"); settings->setDefault("mesh_generation_interval", "0"); settings->setDefault("mesh_generation_threads", "0");