SPU2/XAudio: Get rid of exceptions

This commit is contained in:
Connor McLaughlin 2021-12-18 21:50:38 +10:00 committed by refractionpcsx2
parent ab4b7b8ee6
commit 59e5b1918f
1 changed files with 103 additions and 123 deletions

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "SPU2/Global.h"
#include "Dialogs.h"
#include "common/Console.h"
#include <xaudio2.h>
#include <memory>
@ -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<WAVEFORMATEX*>(&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<s16[]>(m_nBuffers * m_BufferSize);
@ -156,6 +126,7 @@ private:
}
pSourceVoice->Start(0, 0);
return true;
}
protected:
@ -222,21 +193,29 @@ public:
{
xaudio2CoInitialize = wil::CoInitializeEx_failfast(COINIT_MULTITHREADED);
try
{
HRESULT hr;
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()));
{
Console.Error("Could not load %s. Error code: %d" XAUDIO2_DLL_A, 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()));
{
Console.Error("XAudio2Create not found. Error code: %d", GetLastError());
Close();
return false;
}
hr = pXAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
HRESULT hr = pXAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (FAILED(hr))
throw Exception::XAudio2Error(hr, "Failed to init XAudio2 engine. Error Details:");
{
Console.Error("Failed to init XAudio2 engine. Error Details: %08X", hr);
Close();
return false;
}
#ifdef XAUDIO2_DEBUG
XAUDIO2_DEBUG_CONFIGURATION debugConfig{};
@ -271,7 +250,11 @@ public:
hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice, speakers, SampleRate);
if (FAILED(hr))
throw Exception::XAudio2Error(hr, "Failed creating mastering voice: ");
{
Console.Error("Failed creating mastering voice: %08X", hr);
Close();
return false;
}
switch (speakers)
{
@ -315,11 +298,8 @@ public:
break;
}
m_voiceContext->Init(pXAudio2.get());
}
catch (std::runtime_error& ex)
if (!m_voiceContext->Init(pXAudio2.get()))
{
SysMessage(ex.what());
Close();
return false;
}