mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-04 15:50:42 -07:00
audio: retain WASAPI clients only after initialization (#807)
## Link to GitHub Issue or related Pull Request, if one exists Fixes #782 ## Description of change This addresses an issue only seen on Linux + WINE. Defer retaining WASAPI clients until `Initialize` succeeds. Before this PR, temporary clients created during DirectShow device capability probing were retained as active audio clients, causing Wine/Linux crashes in DDR and popn. Also covers IAudioClient3, dummy, ASIO, WaveOut, and null-device initialization paths, for consistency. ## Testing WIP
This commit is contained in:
@@ -53,9 +53,39 @@ namespace hooks::audio {
|
||||
std::string ASIO_DRIVER_NAME = "";
|
||||
bool ASIO_FORCE_UNLOAD_ON_STOP = false;
|
||||
|
||||
// private globals
|
||||
IAudioClient *CLIENT = nullptr;
|
||||
std::mutex INITIALIZE_LOCK; // for asio
|
||||
|
||||
IAudioClient *CLIENT = nullptr;
|
||||
static std::mutex CLIENT_LOCK;
|
||||
static bool CLIENT_STOPPING = false;
|
||||
|
||||
void set_active_client(IAudioClient *client, const char *source) {
|
||||
IAudioClient *previous_client = nullptr;
|
||||
{
|
||||
std::lock_guard lock(CLIENT_LOCK);
|
||||
|
||||
if (CLIENT_STOPPING || CLIENT == client) {
|
||||
return;
|
||||
}
|
||||
if (client) {
|
||||
client->AddRef();
|
||||
}
|
||||
|
||||
previous_client = CLIENT;
|
||||
CLIENT = client;
|
||||
}
|
||||
|
||||
if (previous_client) {
|
||||
previous_client->Release();
|
||||
}
|
||||
|
||||
if (client) {
|
||||
log_info(
|
||||
"audio",
|
||||
"active client selected by {} after successful initialization",
|
||||
source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT STDAPICALLTYPE CoCreateInstance_hook(
|
||||
@@ -133,11 +163,17 @@ namespace hooks::audio {
|
||||
|
||||
void stop() {
|
||||
log_info("audio", "stopping");
|
||||
if (CLIENT) {
|
||||
CLIENT->Stop();
|
||||
CLIENT->Release();
|
||||
IAudioClient *client = nullptr;
|
||||
{
|
||||
std::lock_guard lock(CLIENT_LOCK);
|
||||
CLIENT_STOPPING = true;
|
||||
client = CLIENT;
|
||||
CLIENT = nullptr;
|
||||
}
|
||||
if (client) {
|
||||
client->Stop();
|
||||
client->Release();
|
||||
}
|
||||
stop_low_latency();
|
||||
|
||||
// release the ASIO drivers we kept pinned for the process lifetime now that we are
|
||||
|
||||
Reference in New Issue
Block a user