mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
CubebAudioStream: Call CoInitializeEx before creating cubeb
This commit is contained in:
parent
baa00e4d38
commit
190b525ca6
@ -18,6 +18,8 @@
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include <objbase.h>
|
||||
|
||||
#include "wil/resource.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
@ -26,7 +28,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
CubebAudioStream(u32 sample_rate, const AudioStreamParameters& parameters);
|
||||
~CubebAudioStream();
|
||||
~CubebAudioStream() override;
|
||||
|
||||
void SetPaused(bool paused) override;
|
||||
|
||||
@ -40,6 +42,11 @@ namespace
|
||||
|
||||
void DestroyContextAndStream();
|
||||
|
||||
#ifdef _WIN32
|
||||
// Keep it as the first field, as COM must uninitialize last.
|
||||
wil::unique_couninitialize_call m_coUninit{false};
|
||||
#endif
|
||||
|
||||
cubeb* m_context = nullptr;
|
||||
cubeb_stream* stream = nullptr;
|
||||
};
|
||||
@ -105,12 +112,25 @@ void CubebAudioStream::DestroyContextAndStream()
|
||||
cubeb_destroy(m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
m_coUninit.reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CubebAudioStream::Initialize(const char* driver_name, const char* device_name, bool stretch_enabled, Error* error)
|
||||
{
|
||||
cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback);
|
||||
|
||||
#ifdef _WIN32
|
||||
const HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Error::SetHResult(error, "CoInitializeEx() failed: ", hr);
|
||||
return false;
|
||||
}
|
||||
wil::unique_couninitialize_call uninit;
|
||||
#endif
|
||||
|
||||
int rv = cubeb_init(&m_context, "PCSX2", (driver_name && *driver_name) ? driver_name : nullptr);
|
||||
if (rv != CUBEB_OK)
|
||||
{
|
||||
@ -244,6 +264,9 @@ bool CubebAudioStream::Initialize(const char* driver_name, const char* device_na
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
m_coUninit = std::move(uninit);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -300,6 +323,23 @@ std::vector<AudioStream::DeviceInfo> AudioStream::GetCubebOutputDevices(const ch
|
||||
std::vector<AudioStream::DeviceInfo> ret;
|
||||
ret.emplace_back(std::string(), TRANSLATE_STR("AudioStream", "Default"), 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
// For enumeration, we need *any* COM context. multi- or single-threaded.
|
||||
// Cubeb theoretically wants an MTA context, but this is only relevant when creating streams,
|
||||
// which enumerating devices does not do.
|
||||
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
if (hr == RPC_E_CHANGED_MODE)
|
||||
{
|
||||
hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERROR_LOG("CoInitializeEx failed: {}", Error::CreateHResult(hr).GetDescription());
|
||||
return ret;
|
||||
}
|
||||
wil::unique_couninitialize_call uninit;
|
||||
#endif
|
||||
|
||||
cubeb* context;
|
||||
int rv = cubeb_init(&context, "PCSX2", (driver && *driver) ? driver : nullptr);
|
||||
if (rv != CUBEB_OK)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user