diff --git a/rpcs3/Emu/Audio/XAudio2/XAudio27Thread.cpp b/rpcs3/Emu/Audio/XAudio2/XAudio27Thread.cpp index 2f16e00233..aa1b8f89e6 100644 --- a/rpcs3/Emu/Audio/XAudio2/XAudio27Thread.cpp +++ b/rpcs3/Emu/Audio/XAudio2/XAudio27Thread.cpp @@ -10,12 +10,15 @@ extern cfg::bool_entry g_cfg_audio_convert_to_u16; +static thread_local HMODULE s_tls_xaudio2_lib{}; static thread_local IXAudio2* s_tls_xaudio2_instance{}; static thread_local IXAudio2MasteringVoice* s_tls_master_voice{}; static thread_local IXAudio2SourceVoice* s_tls_source_voice{}; -void XAudio2Thread::xa27_init() +void XAudio2Thread::xa27_init(void* lib2_7) { + s_tls_xaudio2_lib = (HMODULE)lib2_7; + HRESULT hr = S_OK; hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); @@ -41,8 +44,6 @@ void XAudio2Thread::xa27_init() s_tls_xaudio2_instance->Release(); Emu.Pause(); } - - LOG_SUCCESS(GENERAL, "XAudio 2.7 initialized"); } void XAudio2Thread::xa27_destroy() @@ -65,6 +66,8 @@ void XAudio2Thread::xa27_destroy() } CoUninitialize(); + + FreeLibrary(s_tls_xaudio2_lib); } void XAudio2Thread::xa27_play() diff --git a/rpcs3/Emu/Audio/XAudio2/XAudio28Thread.cpp b/rpcs3/Emu/Audio/XAudio2/XAudio28Thread.cpp index 0e54cc35d6..3f4325ab9d 100644 --- a/rpcs3/Emu/Audio/XAudio2/XAudio28Thread.cpp +++ b/rpcs3/Emu/Audio/XAudio2/XAudio28Thread.cpp @@ -10,13 +10,16 @@ extern cfg::bool_entry g_cfg_audio_convert_to_u16; +static thread_local HMODULE s_tls_xaudio2_lib{}; static thread_local IXAudio2* s_tls_xaudio2_instance{}; static thread_local IXAudio2MasteringVoice* s_tls_master_voice{}; static thread_local IXAudio2SourceVoice* s_tls_source_voice{}; -void XAudio2Thread::xa28_init(void* module) +void XAudio2Thread::xa28_init(void* lib) { - auto create = (XAudio2Create)GetProcAddress((HMODULE)module, "XAudio2Create"); + s_tls_xaudio2_lib = (HMODULE)lib; + + const auto create = (XAudio2Create)GetProcAddress(s_tls_xaudio2_lib, "XAudio2Create"); HRESULT hr = S_OK; @@ -43,8 +46,6 @@ void XAudio2Thread::xa28_init(void* module) s_tls_xaudio2_instance->Release(); Emu.Pause(); } - - LOG_SUCCESS(GENERAL, "XAudio 2.8 initialized"); } void XAudio2Thread::xa28_destroy() @@ -67,6 +68,8 @@ void XAudio2Thread::xa28_destroy() } CoUninitialize(); + + FreeLibrary(s_tls_xaudio2_lib); } void XAudio2Thread::xa28_play() diff --git a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.cpp b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.cpp index 0f7dc8a16d..894b91c6eb 100644 --- a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.cpp +++ b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.cpp @@ -2,53 +2,92 @@ #include "Utilities/Log.h" #include "Utilities/StrFmt.h" -#include "Utilities/Config.h" -#include "Emu/System.h" #include "XAudio2Thread.h" #include -extern cfg::bool_entry g_cfg_audio_convert_to_u16; - XAudio2Thread::XAudio2Thread() - : m_xaudio(LoadLibraryA("xaudio2_8.dll")) { - m_xaudio ? xa28_init(m_xaudio) : xa27_init(); + if (auto lib2_7 = LoadLibraryExW(L"XAudio2_7.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)) + { + xa27_init(lib2_7); + + m_funcs.destroy = &xa27_destroy; + m_funcs.play = &xa27_play; + m_funcs.flush = &xa27_flush; + m_funcs.stop = &xa27_stop; + m_funcs.open = &xa27_open; + m_funcs.add = &xa27_add; + + LOG_SUCCESS(GENERAL, "XAudio 2.7 initialized"); + return; + } + + if (auto lib2_9 = LoadLibraryExW(L"XAudio2_9.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)) + { + // xa28* implementation is fully compatible with library 2.9 + xa28_init(lib2_9); + + m_funcs.destroy = &xa28_destroy; + m_funcs.play = &xa28_play; + m_funcs.flush = &xa28_flush; + m_funcs.stop = &xa28_stop; + m_funcs.open = &xa28_open; + m_funcs.add = &xa28_add; + + LOG_SUCCESS(GENERAL, "XAudio 2.9 initialized"); + return; + } + + if (auto lib2_8 = LoadLibraryExW(L"XAudio2_8.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)) + { + xa28_init(lib2_8); + + m_funcs.destroy = &xa28_destroy; + m_funcs.play = &xa28_play; + m_funcs.flush = &xa28_flush; + m_funcs.stop = &xa28_stop; + m_funcs.open = &xa28_open; + m_funcs.add = &xa28_add; + + LOG_SUCCESS(GENERAL, "XAudio 2.8 initialized"); + return; + } + + throw fmt::exception("No supported XAudio2 library found"); } XAudio2Thread::~XAudio2Thread() { - m_xaudio ? xa28_destroy() : xa27_destroy(); - - FreeLibrary((HMODULE)m_xaudio); + m_funcs.destroy(); } void XAudio2Thread::Play() { - m_xaudio ? xa28_play() : xa27_play(); + m_funcs.play(); } void XAudio2Thread::Close() { - Stop(); - m_xaudio ? xa28_flush() : xa27_flush(); + m_funcs.stop(); + m_funcs.flush(); } void XAudio2Thread::Stop() { - m_xaudio ? xa28_stop() : xa27_stop(); + m_funcs.stop(); } void XAudio2Thread::Open(const void* src, int size) { - m_xaudio ? xa28_open() : xa27_open(); - AddData(src, size); - Play(); + m_funcs.open(); + m_funcs.add(src, size); + m_funcs.play(); } void XAudio2Thread::AddData(const void* src, int size) { - m_xaudio ? xa28_add(src, size) : xa27_add(src, size); + m_funcs.add(src, size); } #endif diff --git a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h index 3a354c4e08..99f80b98c8 100644 --- a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h +++ b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h @@ -6,9 +6,19 @@ class XAudio2Thread : public AudioThread { - void* const m_xaudio; + struct vtable + { + void(*destroy)(); + void(*play)(); + void(*flush)(); + void(*stop)(); + void(*open)(); + void(*add)(const void*, int); + }; - static void xa27_init(); + vtable m_funcs; + + static void xa27_init(void*); static void xa27_destroy(); static void xa27_play(); static void xa27_flush();