mirror of https://github.com/PCSX2/pcsx2.git
SPU2/XAudio: Get rid of exceptions
This commit is contained in:
parent
ab4b7b8ee6
commit
59e5b1918f
|
@ -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,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<StreamingVoice<StereoOut16>>();
|
||||
break;
|
||||
case 3:
|
||||
ConLog("* SPU2 > 2.1 speaker expansion enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo21Out16>>();
|
||||
break;
|
||||
case 4:
|
||||
ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo40Out16>>();
|
||||
break;
|
||||
case 5:
|
||||
ConLog("* SPU2 > 4.1 speaker expansion enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo41Out16>>();
|
||||
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<StreamingVoice<Stereo51Out16>>();
|
||||
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<StreamingVoice<Stereo51Out16Dpl>>();
|
||||
break;
|
||||
case 2: // gigas PLII
|
||||
ConLog("* SPU2 > 5.1 speaker expansion with experimental ProLogicII dematrixing enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo51Out16DplII>>();
|
||||
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<StreamingVoice<Stereo51Out16>>();
|
||||
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<StreamingVoice<StereoOut16>>();
|
||||
break;
|
||||
case 3:
|
||||
ConLog("* SPU2 > 2.1 speaker expansion enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo21Out16>>();
|
||||
break;
|
||||
case 4:
|
||||
ConLog("* SPU2 > 4 speaker expansion enabled [quadraphenia]\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo40Out16>>();
|
||||
break;
|
||||
case 5:
|
||||
ConLog("* SPU2 > 4.1 speaker expansion enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo41Out16>>();
|
||||
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<StreamingVoice<Stereo51Out16>>();
|
||||
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<StreamingVoice<Stereo51Out16Dpl>>();
|
||||
break;
|
||||
case 2: // gigas PLII
|
||||
ConLog("* SPU2 > 5.1 speaker expansion with experimental ProLogicII dematrixing enabled.\n");
|
||||
m_voiceContext = std::make_unique<StreamingVoice<Stereo51Out16DplII>>();
|
||||
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<StreamingVoice<Stereo51Out16>>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_voiceContext->Init(pXAudio2.get()))
|
||||
{
|
||||
SysMessage(ex.what());
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue