audio: stereo downmix, volume boost options (#722)

## Link to GitHub Issue or related Pull Request, if one exists
Fixes #717, fixes #647

## Description of change
Adds an option to downmix surround sound (5.1, 7.1, etc) down to stereo
(2 speakers). This can be used in most WASAPI games, including Gitadora
and FTT.

How it works: when the game tries to open surround format (say, 7.1) we
create a fake buffer and tell the game that it is supported. In reality
we open a 2-channel stream with the real sound card. When the stream
begins, we downmix the channels down to two (using one of many
algorithms) and output to the sound card.

While we're here, implement an option to boost the game volume by some
decibel value, which is a feature often requested by SDVX players. This
was needed since downmixing can sometimes result in quieter audio.

## Testing
Tested GW Delta and FTT.

Downmix doesn't work on IIDX (32 bits) but volume boost works.
This commit is contained in:
bicarus
2026-05-31 20:49:22 -07:00
committed by GitHub
parent 6bb6b0a301
commit 84ea3f9e8e
13 changed files with 768 additions and 34 deletions
+25 -15
View File
@@ -3,6 +3,10 @@
#include "handle.h"
#include "bi2x_hook.h"
#include <unordered_map>
#include <ks.h>
#include <ksmedia.h>
#include "cfg/configurator.h"
#include "hooks/audio/mme.h"
#include "hooks/graphics/graphics.h"
@@ -659,26 +663,32 @@ namespace games::gitadora {
}
// two channel mod
if (TWOCHANNEL) {
if (is_arena_model()) {
log_warning("gitadora", "two channel audio (-2ch) is not supported on Arena Model - use a patch instead");
deferredlogs::defer_error_messages({
"two channel audio (-2ch) is not supported on Arena Model - use a patch instead",
});
if (TWOCHANNEL && !is_arena_model()) {
HMODULE bmsd_engine_module = libutils::try_module("libbmsd-engine.dll");
HMODULE bmsd_module = libutils::try_module("libbmsd.dll");
} else {
HMODULE bmsd_engine_module = libutils::try_module("libbmsd-engine.dll");
HMODULE bmsd_module = libutils::try_module("libbmsd.dll");
bmsd2_boot_orig = detour::iat_try("bmsd2_boot", bmsd2_boot_hook, bmsd_module);
if (!(replace_pattern(bmsd_engine_module, "33000000488D", "03??????????", 0, 0) ||
replace_pattern(bmsd_engine_module, "330000000F10", "03??????????", 0, 0))) {
log_warning("gitadora", "two channel mode failed");
}
bmsd2_boot_orig = detour::iat_try("bmsd2_boot", bmsd2_boot_hook, bmsd_module);
if (!(replace_pattern(bmsd_engine_module, "33000000488D", "03??????????", 0, 0) ||
replace_pattern(bmsd_engine_module, "330000000F10", "03??????????", 0, 0))) {
log_warning("gitadora", "two channel mode failed");
}
}
#endif
}
void fix_audio_channel_mask(WAVEFORMATEX *format) {
if (!format || format->wFormatTag != WAVE_FORMAT_EXTENSIBLE) {
return;
}
auto ext = reinterpret_cast<WAVEFORMATEXTENSIBLE *>(format);
// fix the legacy 7.1 channel mask to the modern surround layout
// makes it more compatible with modern audio cards
if (ext->dwChannelMask == KSAUDIO_SPEAKER_7POINT1) {
ext->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
}
}
}
+5
View File
@@ -2,6 +2,9 @@
#include <optional>
#include <windows.h>
#include <mmreg.h>
#include "avs/game.h"
#include "games/game.h"
#include "util/socd_cleaner.h"
@@ -25,6 +28,8 @@ namespace games::gitadora {
virtual void attach() override;
};
void fix_audio_channel_mask(WAVEFORMATEX *format);
static inline bool is_drum() {
return (
avs::game::is_model({ "J32", "K32", "L32" }) ||