Use AL_SOFT_direct_channels_remix extension for non-positional stereo sounds (#14195)

This commit is contained in:
DS 2024-01-03 21:57:00 +01:00 committed by GitHub
parent 3eab5e9002
commit c9cd0d20ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 143 additions and 23 deletions

@ -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

@ -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

@ -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 <unordered_set>
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<std::string> 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
}
}
}

@ -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
};
}

@ -24,6 +24,7 @@ with this program; ifnot, write to the Free Software Foundation, Inc.,
#include "playing_sound.h"
#include "al_extensions.h"
#include "debug.h"
#include <cassert>
#include <cmath>
@ -32,7 +33,8 @@ namespace sound {
PlayingSound::PlayingSound(ALuint source_id, std::shared_ptr<ISoundDataOpen> data,
bool loop, f32 volume, f32 pitch, f32 start_time,
const std::optional<std::pair<v3f, v3f>> &pos_vel_opt)
const std::optional<std::pair<v3f, v3f>> &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<ISoundDataOpen> 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);

@ -25,6 +25,7 @@ with this program; ifnot, write to the Free Software Foundation, Inc.,
#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<ISoundDataOpen> data, bool loop,
f32 volume, f32 pitch, f32 start_time,
const std::optional<std::pair<v3f, v3f>> &pos_vel_opt);
const std::optional<std::pair<v3f, v3f>> &pos_vel_opt,
const ALExtensions &exts [[maybe_unused]]);
~PlayingSound() noexcept
{

@ -181,7 +181,7 @@ std::shared_ptr<PlayingSound> OpenALSoundManager::createPlayingSound(
}
auto sound = std::make_shared<PlayingSound>(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);

@ -25,6 +25,7 @@ with this program; ifnot, write to the Free Software Foundation, Inc.,
#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<SoundFallbackPathProvider> 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;

@ -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");