audio: simplify ASIO backend conversion (#560)

## Link to GitHub Issue or related Pull Request, if one exists

## Description of change
Deprecate backend conversion options and replace with one unified option
for enabling WASAPI exclusive conversion to ASIO.

The new option takes in a string (ASIO driver name) and when filled out,
it automatically enables the ASIO backend.

This is to avoid confusion that was caused by the previous option - the
fact that it was split into two (one to enable the conversion, another
to optionally pick which ASIO driver to use) and that user needed to
specify an integer as opposed to the driver name.

## Testing
Tested on IIDX33. Old options should continue to work.
This commit is contained in:
bicarus
2026-03-01 13:06:18 -08:00
committed by GitHub
parent 884d665c1c
commit 2d623e179b
6 changed files with 64 additions and 10 deletions
+2 -1
View File
@@ -42,7 +42,8 @@ namespace hooks::audio {
bool USE_DUMMY = false;
WAVEFORMATEXTENSIBLE FORMAT {};
std::optional<Backend> BACKEND = std::nullopt;
size_t ASIO_DRIVER_ID = 0;
std::optional<size_t> ASIO_DRIVER_ID = std::nullopt;
std::string ASIO_DRIVER_NAME = "";
bool ASIO_FORCE_UNLOAD_ON_STOP = false;
// private globals
+3 -1
View File
@@ -1,6 +1,7 @@
#pragma once
#include <optional>
#include <string>
#include <windows.h>
#include <mmreg.h>
@@ -20,7 +21,8 @@ namespace hooks::audio {
extern bool USE_DUMMY;
extern WAVEFORMATEXTENSIBLE FORMAT;
extern std::optional<Backend> BACKEND;
extern size_t ASIO_DRIVER_ID;
extern std::optional<size_t> ASIO_DRIVER_ID;
extern std::string ASIO_DRIVER_NAME;
extern bool ASIO_FORCE_UNLOAD_ON_STOP;
extern bool LOW_LATENCY_SHARED_WASAPI;
@@ -218,13 +218,40 @@ void AsioBackend::set_thread_state(AsioThreadState state) {
bool AsioBackend::load_driver() {
AsioDriverList asio_driver_list;
for (const auto &driver : asio_driver_list.driver_list) {
log_info("audio::asio", "Driver {}", driver.id);
log_info("audio::asio", "... Name : {}", driver.name);
log_info("audio::asio", "... Path : {}", driver.dll_path);
size_t driver_id = 0;
std::string driver_name = "";
if (hooks::audio::ASIO_DRIVER_ID.has_value()) {
driver_id = hooks::audio::ASIO_DRIVER_ID.value();
}
const auto driver_id = hooks::audio::ASIO_DRIVER_ID;
for (const auto &driver : asio_driver_list.driver_list) {
log_info("audio::asio", " Driver ID : {}", driver.id);
log_info("audio::asio", " ... Name : {}", driver.name);
log_info("audio::asio", " ... Path : {}", driver.dll_path);
if (!hooks::audio::ASIO_DRIVER_NAME.empty()) {
// match on driver name
if (driver.name == hooks::audio::ASIO_DRIVER_NAME) {
driver_id = driver.id;
driver_name = driver.name;
}
} else if (driver.id == driver_id) {
// match on driver index (0 for default or user-specified)
driver_name = driver.name;
}
}
if (driver_name.empty()) {
if (!hooks::audio::ASIO_DRIVER_NAME.empty()) {
log_warning(
"audio::asio",
"tried to look for ASIO driver but failed: {}", hooks::audio::ASIO_DRIVER_NAME);
}
log_fatal(
"audio::asio",
"could not find ASIO driver to use for conversion, fix your audio options and try again");
}
log_info("audio::asio", "will attempt to use the following ASIO driver: ID = {}, Name = {}", driver_id, driver_name);
IAsio *driver = nullptr;
auto ret = asio_driver_list.open_driver(driver_id, reinterpret_cast<void **>(&driver));
+9 -1
View File
@@ -1011,18 +1011,26 @@ int main_implementation(int argc, char *argv[]) {
if (options[launcher::Options::spice2x_DisableVolumeHook].value_bool()) {
hooks::audio::VOLUME_HOOK_ENABLED = false;
}
if (options[launcher::Options::AudioBackend].is_active()) {
auto &name = options[launcher::Options::AudioBackend].value_text();
auto backend = hooks::audio::name_to_backend(name.c_str());
if (!backend.has_value() && !cfg::CONFIGURATOR_STANDALONE) {
log_fatal("launcher", "invalid audio backend: {}", name);
}
hooks::audio::BACKEND = backend;
}
if (options[launcher::Options::AsioDriverId].is_active()) {
hooks::audio::ASIO_DRIVER_ID = options[launcher::Options::AsioDriverId].value_uint32();
}
if (options[launcher::Options::AsioDriverName].is_active()) {
hooks::audio::BACKEND = hooks::audio::name_to_backend("asio");
hooks::audio::ASIO_DRIVER_NAME = options[launcher::Options::AsioDriverName].value_text();
// this new option overrides the old one
hooks::audio::ASIO_DRIVER_ID.reset();
}
if (options[launcher::Options::AudioDummy].value_bool()) {
hooks::audio::USE_DUMMY = true;
}
+17 -2
View File
@@ -1742,11 +1742,13 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.category = "Audio (Hacks)",
},
{
.title = "Spice Audio Hook Backend",
// AudioBackend
.title = "Spice Audio Hook Backend (DEPRECATED - use -asioconvert instead)",
.name = "audiobackend",
.desc = "Selects the audio backend to use when spice audio hook is enabled, overriding exclusive WASAPI. "
"Does nothing for games that do not output to exclusive WASAPI.",
.type = OptionType::Enum,
.hidden = true,
.category = "Audio",
.elements = {
{"asio", "ASIO"},
@@ -1754,10 +1756,23 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
},
},
{
.title = "Spice Audio Hook ASIO Driver ID",
// AsioDriverId
.title = "Spice Audio Hook ASIO Driver ID (DEPRECATED - use -asioconvert instead)",
.name = "asiodriverid",
.desc = "Selects the ASIO driver id to use when Spice Audio Backend is set to ASIO.",
.type = OptionType::Integer,
.hidden = true,
.category = "Audio",
},
{
// AsioDriverName
.title = "WASAPI Exclusive to ASIO Conversion",
.name = "asioconvert",
.desc = "Converts WASAPI Exclusive audio output to ASIO. Value here should match registry key under HKLM\\SOFTWARE\\ASIO\\\n\n"
"Use this if the game is configured to use WASAPI Exclusive but you want to use your ASIO driver instead.\n\n"
"This should only be used as last resort if your audio device does not support WASAPI Exclusive.\n\n"
"Does nothing for games that do not output to exclusive WASAPI.",
.type = OptionType::Text,
.category = "Audio",
},
{
+1
View File
@@ -187,6 +187,7 @@ namespace launcher {
spice2x_DisableVolumeHook,
AudioBackend,
AsioDriverId,
AsioDriverName,
AudioDummy,
DelayBy5Seconds,
spice2x_DelayByNSeconds,