From 59e5b1918f80994a65887fe84715204720c65ab3 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Dec 2021 21:50:38 +1000 Subject: [PATCH] SPU2/XAudio: Get rid of exceptions --- pcsx2/SPU2/Windows/SndOut_XAudio2.cpp | 226 ++++++++++++-------------- 1 file changed, 103 insertions(+), 123 deletions(-) diff --git a/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp b/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp index b8d413351d..885f46e49e 100644 --- a/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp +++ b/pcsx2/SPU2/Windows/SndOut_XAudio2.cpp @@ -16,6 +16,7 @@ #include "PrecompiledHeader.h" #include "SPU2/Global.h" #include "Dialogs.h" +#include "common/Console.h" #include #include @@ -29,38 +30,6 @@ //#define XAUDIO2_DEBUG -namespace Exception -{ - class XAudio2Error final : public std::runtime_error - { - private: - static std::string CreateErrorMessage(const HRESULT result, const std::string_view msg) - { - std::stringstream ss; - ss << msg << " (code 0x" << std::hex << result << ")\n\n"; - switch (result) - { - case XAUDIO2_E_INVALID_CALL: - ss << "Invalid call for the XA2 object state."; - break; - case XAUDIO2_E_DEVICE_INVALIDATED: - ss << "Device is unavailable, unplugged, unsupported, or has been consumed by The Nothing."; - break; - default: - ss << "Unknown error code!"; - break; - } - return ss.str(); - } - - public: - explicit XAudio2Error(const HRESULT result, const std::string_view msg) - : std::runtime_error(CreateErrorMessage(result, msg)) - { - } - }; -} // namespace Exception - class XAudio2Mod final : public SndOutModule { private: @@ -96,7 +65,7 @@ private: { } - void Init(IXAudio2* pXAudio2) + bool Init(IXAudio2* pXAudio2) { DWORD chanMask = 0; switch (m_nChannels) @@ -140,7 +109,8 @@ private: const HRESULT hr = pXAudio2->CreateSourceVoice(&pSourceVoice, reinterpret_cast(&wfx), XAUDIO2_VOICE_NOSRC, 1.0f, this); if (FAILED(hr)) { - throw Exception::XAudio2Error(hr, "XAudio2 CreateSourceVoice failure: "); + Console.Error("XAudio2 CreateSourceVoice failure: %08X", hr); + return false; } m_buffer = std::make_unique(m_nBuffers * m_BufferSize); @@ -156,6 +126,7 @@ private: } pSourceVoice->Start(0, 0); + return true; } protected: @@ -222,104 +193,113 @@ public: { xaudio2CoInitialize = wil::CoInitializeEx_failfast(COINIT_MULTITHREADED); - try + xAudio2DLL.reset(LoadLibraryEx(XAUDIO2_DLL, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)); + if (xAudio2DLL == nullptr) { - HRESULT hr; + Console.Error("Could not load %s. Error code: %d" XAUDIO2_DLL_A, GetLastError()); + Close(); + return false; + } - xAudio2DLL.reset(LoadLibraryEx(XAUDIO2_DLL, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)); - if (xAudio2DLL == nullptr) - throw std::runtime_error("Could not load " XAUDIO2_DLL_A ". Error code:" + std::to_string(GetLastError())); + auto pXAudio2Create = GetProcAddressByFunctionDeclaration(xAudio2DLL.get(), XAudio2Create); + if (pXAudio2Create == nullptr) + { + Console.Error("XAudio2Create not found. Error code: %d", GetLastError()); + Close(); + return false; + } - auto pXAudio2Create = GetProcAddressByFunctionDeclaration(xAudio2DLL.get(), XAudio2Create); - if (pXAudio2Create == nullptr) - throw std::runtime_error("XAudio2Create not found. Error code: " + std::to_string(GetLastError())); - - hr = pXAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); - if (FAILED(hr)) - throw Exception::XAudio2Error(hr, "Failed to init XAudio2 engine. Error Details:"); + HRESULT hr = pXAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); + if (FAILED(hr)) + { + Console.Error("Failed to init XAudio2 engine. Error Details: %08X", hr); + Close(); + return false; + } #ifdef XAUDIO2_DEBUG - XAUDIO2_DEBUG_CONFIGURATION debugConfig{}; - debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; - pXAudio2->SetDebugConfiguration(&debugConfig, nullptr); + XAUDIO2_DEBUG_CONFIGURATION debugConfig{}; + debugConfig.BreakMask = XAUDIO2_LOG_ERRORS; + pXAudio2->SetDebugConfiguration(&debugConfig, nullptr); #endif - // Stereo Expansion was planned to grab the currently configured number of - // Speakers from Windows's audio config. - // This doesn't always work though, so let it be a user configurable option. + // Stereo Expansion was planned to grab the currently configured number of + // Speakers from Windows's audio config. + // This doesn't always work though, so let it be a user configurable option. - int speakers; - // speakers = (numSpeakers + 1) *2; ? - switch (numSpeakers) - { - case 0: // Stereo - speakers = 2; - break; - case 1: // Quadrafonic - speakers = 4; - break; - case 2: // Surround 5.1 - speakers = 6; - break; - case 3: // Surround 7.1 - speakers = 8; - break; - default: - speakers = 2; - break; - } - - hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice, speakers, SampleRate); - if (FAILED(hr)) - throw Exception::XAudio2Error(hr, "Failed creating mastering voice: "); - - switch (speakers) - { - case 2: - ConLog("* SPU2 > Using normal 2 speaker stereo output.\n"); - m_voiceContext = std::make_unique>(); - break; - case 3: - ConLog("* SPU2 > 2.1 speaker expansion enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - case 4: - ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n"); - m_voiceContext = std::make_unique>(); - break; - case 5: - ConLog("* SPU2 > 4.1 speaker expansion enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - case 6: - case 7: - switch (dplLevel) - { - case 0: // "normal" stereo upmix - ConLog("* SPU2 > 5.1 speaker expansion enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - case 1: // basic Dpl decoder without rear stereo balancing - ConLog("* SPU2 > 5.1 speaker expansion with basic ProLogic dematrixing enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - case 2: // gigas PLII - ConLog("* SPU2 > 5.1 speaker expansion with experimental ProLogicII dematrixing enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - } - break; - default: // anything 8 or more gets the 7.1 treatment! - ConLog("* SPU2 > 7.1 speaker expansion enabled.\n"); - m_voiceContext = std::make_unique>(); - break; - } - - m_voiceContext->Init(pXAudio2.get()); - } - catch (std::runtime_error& ex) + int speakers; + // speakers = (numSpeakers + 1) *2; ? + switch (numSpeakers) + { + case 0: // Stereo + speakers = 2; + break; + case 1: // Quadrafonic + speakers = 4; + break; + case 2: // Surround 5.1 + speakers = 6; + break; + case 3: // Surround 7.1 + speakers = 8; + break; + default: + speakers = 2; + break; + } + + hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice, speakers, SampleRate); + if (FAILED(hr)) + { + Console.Error("Failed creating mastering voice: %08X", hr); + Close(); + return false; + } + + switch (speakers) + { + case 2: + ConLog("* SPU2 > Using normal 2 speaker stereo output.\n"); + m_voiceContext = std::make_unique>(); + break; + case 3: + ConLog("* SPU2 > 2.1 speaker expansion enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + case 4: + ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n"); + m_voiceContext = std::make_unique>(); + break; + case 5: + ConLog("* SPU2 > 4.1 speaker expansion enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + case 6: + case 7: + switch (dplLevel) + { + case 0: // "normal" stereo upmix + ConLog("* SPU2 > 5.1 speaker expansion enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + case 1: // basic Dpl decoder without rear stereo balancing + ConLog("* SPU2 > 5.1 speaker expansion with basic ProLogic dematrixing enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + case 2: // gigas PLII + ConLog("* SPU2 > 5.1 speaker expansion with experimental ProLogicII dematrixing enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + } + break; + default: // anything 8 or more gets the 7.1 treatment! + ConLog("* SPU2 > 7.1 speaker expansion enabled.\n"); + m_voiceContext = std::make_unique>(); + break; + } + + if (!m_voiceContext->Init(pXAudio2.get())) { - SysMessage(ex.what()); Close(); return false; }