aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-01 23:52:53 -0700
committerChris Robinson <[email protected]>2018-11-01 23:52:53 -0700
commit66df771d96d98acdf7c31d0ca5729b06502ae7d0 (patch)
treebec7b19faf2bd574c715a348cde6641e5e1ec007 /Alc/backends
parent7307c2d5aa4a5cae73f05451ddbc1c4dcc9fad20 (diff)
Make the polymorphism macros less hacky in C++
In particular, it relies on derived structs using C++-style inheritence. Any implementation's source that's converted to C++ will consequently need to make that change.
Diffstat (limited to 'Alc/backends')
-rw-r--r--Alc/backends/pulseaudio.cpp69
-rw-r--r--Alc/backends/wasapi.cpp594
2 files changed, 319 insertions, 344 deletions
diff --git a/Alc/backends/pulseaudio.cpp b/Alc/backends/pulseaudio.cpp
index b6f7940b..719205c4 100644
--- a/Alc/backends/pulseaudio.cpp
+++ b/Alc/backends/pulseaudio.cpp
@@ -532,9 +532,7 @@ std::vector<DevMap> CaptureDevices;
} // namespace
-struct PulsePlayback {
- DERIVE_FROM_TYPE(ALCbackend);
-
+struct PulsePlayback final : public ALCbackend {
std::string device_name;
pa_buffer_attr attr;
@@ -1241,9 +1239,7 @@ static void PulsePlayback_unlock(PulsePlayback *self)
}
-struct PulseCapture {
- DERIVE_FROM_TYPE(ALCbackend);
-
+struct PulseCapture final : public ALCbackend {
std::string device_name;
const void *cap_store{nullptr};
@@ -1744,20 +1740,25 @@ static void PulseCapture_unlock(PulseCapture *self)
}
-typedef struct ALCpulseBackendFactory {
- DERIVE_FROM_TYPE(ALCbackendFactory);
-} ALCpulseBackendFactory;
-#define ALCPULSEBACKENDFACTORY_INITIALIZER { GET_VTABLE2(ALCpulseBackendFactory, ALCbackendFactory) }
+struct PulseBackendFactory final : public ALCbackendFactory {
+ PulseBackendFactory() noexcept;
+};
+#define ALCPULSEBACKENDFACTORY_INITIALIZER GET_VTABLE2(PulseBackendFactory, ALCbackendFactory)
+
+static ALCboolean PulseBackendFactory_init(PulseBackendFactory *self);
+static void PulseBackendFactory_deinit(PulseBackendFactory *self);
+static ALCboolean PulseBackendFactory_querySupport(PulseBackendFactory *self, ALCbackend_Type type);
+static void PulseBackendFactory_probe(PulseBackendFactory *self, enum DevProbe type, al_string *outnames);
+static ALCbackend* PulseBackendFactory_createBackend(PulseBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
+DEFINE_ALCBACKENDFACTORY_VTABLE(PulseBackendFactory);
-static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory *self);
-static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory *self);
-static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory *self, ALCbackend_Type type);
-static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory *self, enum DevProbe type, al_string *outnames);
-static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
-DEFINE_ALCBACKENDFACTORY_VTABLE(ALCpulseBackendFactory);
+PulseBackendFactory::PulseBackendFactory() noexcept
+ : ALCbackendFactory{ALCPULSEBACKENDFACTORY_INITIALIZER}
+{
+}
-static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory* UNUSED(self))
+static ALCboolean PulseBackendFactory_init(PulseBackendFactory* UNUSED(self))
{
ALCboolean ret{ALC_FALSE};
@@ -1797,7 +1798,7 @@ static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory* UNUSED(sel
return ret;
}
-static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory* UNUSED(self))
+static void PulseBackendFactory_deinit(PulseBackendFactory* UNUSED(self))
{
PlaybackDevices.clear();
CaptureDevices.clear();
@@ -1809,14 +1810,14 @@ static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory* UNUSED(self))
/* PulseAudio doesn't like being CloseLib'd sometimes */
}
-static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UNUSED(self), ALCbackend_Type type)
+static ALCboolean PulseBackendFactory_querySupport(PulseBackendFactory* UNUSED(self), ALCbackend_Type type)
{
if(type == ALCbackend_Playback || type == ALCbackend_Capture)
return ALC_TRUE;
return ALC_FALSE;
}
-static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
+static void PulseBackendFactory_probe(PulseBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
auto add_device = [outnames](const DevMap &entry) -> void
{
@@ -1841,7 +1842,7 @@ static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), e
}
}
-static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
+static ALCbackend* PulseBackendFactory_createBackend(PulseBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
{
@@ -1866,40 +1867,44 @@ static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory*
#warning "Unsupported API version, backend will be unavailable!"
-typedef struct ALCpulseBackendFactory {
- DERIVE_FROM_TYPE(ALCbackendFactory);
-} ALCpulseBackendFactory;
-#define ALCPULSEBACKENDFACTORY_INITIALIZER { GET_VTABLE2(ALCpulseBackendFactory, ALCbackendFactory) }
+struct PulseBackendFactory final : public ALCbackendFactory {
+ PulseBackendFactory() noexcept;
+};
+#define ALCPULSEBACKENDFACTORY_INITIALIZER GET_VTABLE2(PulseBackendFactory, ALCbackendFactory)
-static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory* UNUSED(self))
+static ALCboolean PulseBackendFactory_init(PulseBackendFactory* UNUSED(self))
{
return ALC_FALSE;
}
-static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory* UNUSED(self))
+static void PulseBackendFactory_deinit(PulseBackendFactory* UNUSED(self))
{
}
-static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UNUSED(self), ALCbackend_Type UNUSED(type))
+static ALCboolean PulseBackendFactory_querySupport(PulseBackendFactory* UNUSED(self), ALCbackend_Type UNUSED(type))
{
return ALC_FALSE;
}
-static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe UNUSED(type), al_string* UNUSED(outnames))
+static void PulseBackendFactory_probe(PulseBackendFactory* UNUSED(self), enum DevProbe UNUSED(type), al_string* UNUSED(outnames))
{
}
-static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory* UNUSED(self), ALCdevice* UNUSED(device), ALCbackend_Type UNUSED(type))
+static ALCbackend* PulseBackendFactory_createBackend(PulseBackendFactory* UNUSED(self), ALCdevice* UNUSED(device), ALCbackend_Type UNUSED(type))
{
return nullptr;
}
-DEFINE_ALCBACKENDFACTORY_VTABLE(ALCpulseBackendFactory);
+DEFINE_ALCBACKENDFACTORY_VTABLE(PulseBackendFactory);
+
+PulseBackendFactory::PulseBackendFactory() noexcept
+ : ALCbackendFactory{ALCPULSEBACKENDFACTORY_INITIALIZER}
+{ }
#endif /* PA_API_VERSION == 12 */
ALCbackendFactory *ALCpulseBackendFactory_getFactory(void)
{
- static ALCpulseBackendFactory factory{ALCPULSEBACKENDFACTORY_INITIALIZER};
+ static PulseBackendFactory factory{};
return STATIC_CAST(ALCbackendFactory, &factory);
}
diff --git a/Alc/backends/wasapi.cpp b/Alc/backends/wasapi.cpp
index 35d67a90..ddb3ced0 100644
--- a/Alc/backends/wasapi.cpp
+++ b/Alc/backends/wasapi.cpp
@@ -341,40 +341,16 @@ static HRESULT probe_devices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, st
/* Proxy interface used by the message handler. */
-struct ALCwasapiProxyVtable;
+struct WasapiProxy {
+ virtual HRESULT openProxy() = 0;
+ virtual void closeProxy() = 0;
-typedef struct ALCwasapiProxy {
- const struct ALCwasapiProxyVtable *vtbl;
-} ALCwasapiProxy;
-
-struct ALCwasapiProxyVtable {
- HRESULT (*const openProxy)(ALCwasapiProxy*);
- void (*const closeProxy)(ALCwasapiProxy*);
-
- HRESULT (*const resetProxy)(ALCwasapiProxy*);
- HRESULT (*const startProxy)(ALCwasapiProxy*);
- void (*const stopProxy)(ALCwasapiProxy*);
+ virtual HRESULT resetProxy() = 0;
+ virtual HRESULT startProxy() = 0;
+ virtual void stopProxy() = 0;
};
-#define DEFINE_ALCWASAPIPROXY_VTABLE(T) \
-DECLARE_THUNK(T, ALCwasapiProxy, HRESULT, openProxy) \
-DECLARE_THUNK(T, ALCwasapiProxy, void, closeProxy) \
-DECLARE_THUNK(T, ALCwasapiProxy, HRESULT, resetProxy) \
-DECLARE_THUNK(T, ALCwasapiProxy, HRESULT, startProxy) \
-DECLARE_THUNK(T, ALCwasapiProxy, void, stopProxy) \
- \
-static const struct ALCwasapiProxyVtable T##_ALCwasapiProxy_vtable = { \
- T##_ALCwasapiProxy_openProxy, \
- T##_ALCwasapiProxy_closeProxy, \
- T##_ALCwasapiProxy_resetProxy, \
- T##_ALCwasapiProxy_startProxy, \
- T##_ALCwasapiProxy_stopProxy, \
-}
-
-static void ALCwasapiProxy_Construct(ALCwasapiProxy* UNUSED(self)) { }
-static void ALCwasapiProxy_Destruct(ALCwasapiProxy* UNUSED(self)) { }
-
-static DWORD CALLBACK ALCwasapiProxy_messageHandler(void *ptr)
+static DWORD CALLBACK WasapiProxy_messageHandler(void *ptr)
{
auto req = reinterpret_cast<ThreadRequest*>(ptr);
@@ -423,18 +399,18 @@ static DWORD CALLBACK ALCwasapiProxy_messageHandler(void *ptr)
msg.message, (void*)msg.lParam, (void*)msg.wParam
);
- ALCwasapiProxy *proxy{nullptr};
+ WasapiProxy *proxy{nullptr};
switch(msg.message)
{
case WM_USER_OpenDevice:
req = reinterpret_cast<ThreadRequest*>(msg.wParam);
- proxy = reinterpret_cast<ALCwasapiProxy*>(msg.lParam);
+ proxy = reinterpret_cast<WasapiProxy*>(msg.lParam);
hr = cohr = S_OK;
if(++deviceCount == 1)
hr = cohr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if(SUCCEEDED(hr))
- hr = V0(proxy,openProxy)();
+ hr = proxy->openProxy();
if(FAILED(hr))
{
if(--deviceCount == 0 && SUCCEEDED(cohr))
@@ -446,33 +422,33 @@ static DWORD CALLBACK ALCwasapiProxy_messageHandler(void *ptr)
case WM_USER_ResetDevice:
req = reinterpret_cast<ThreadRequest*>(msg.wParam);
- proxy = reinterpret_cast<ALCwasapiProxy*>(msg.lParam);
+ proxy = reinterpret_cast<WasapiProxy*>(msg.lParam);
- hr = V0(proxy,resetProxy)();
+ hr = proxy->resetProxy();
ReturnMsgResponse(req, hr);
continue;
case WM_USER_StartDevice:
req = reinterpret_cast<ThreadRequest*>(msg.wParam);
- proxy = reinterpret_cast<ALCwasapiProxy*>(msg.lParam);
+ proxy = reinterpret_cast<WasapiProxy*>(msg.lParam);
- hr = V0(proxy,startProxy)();
+ hr = proxy->startProxy();
ReturnMsgResponse(req, hr);
continue;
case WM_USER_StopDevice:
req = reinterpret_cast<ThreadRequest*>(msg.wParam);
- proxy = reinterpret_cast<ALCwasapiProxy*>(msg.lParam);
+ proxy = reinterpret_cast<WasapiProxy*>(msg.lParam);
- V0(proxy,stopProxy)();
+ proxy->stopProxy();
ReturnMsgResponse(req, S_OK);
continue;
case WM_USER_CloseDevice:
req = reinterpret_cast<ThreadRequest*>(msg.wParam);
- proxy = reinterpret_cast<ALCwasapiProxy*>(msg.lParam);
+ proxy = reinterpret_cast<WasapiProxy*>(msg.lParam);
- V0(proxy,closeProxy)();
+ proxy->closeProxy();
if(--deviceCount == 0)
CoUninitialize();
@@ -517,38 +493,37 @@ static DWORD CALLBACK ALCwasapiProxy_messageHandler(void *ptr)
}
-typedef struct ALCwasapiPlayback {
- DERIVE_FROM_TYPE(ALCbackend);
- DERIVE_FROM_TYPE(ALCwasapiProxy);
+struct ALCwasapiPlayback final : public ALCbackend, WasapiProxy {
+ HRESULT openProxy() override;
+ void closeProxy() override;
- std::wstring devid;
+ HRESULT resetProxy() override;
+ HRESULT startProxy() override;
+ void stopProxy() override;
+
+ std::wstring mDevId;
- IMMDevice *mmdev{nullptr};
- IAudioClient *client{nullptr};
- IAudioRenderClient *render{nullptr};
- HANDLE NotifyEvent{nullptr};
+ IMMDevice *mMMDev{nullptr};
+ IAudioClient *mClient{nullptr};
+ IAudioRenderClient *mRender{nullptr};
+ HANDLE mNotifyEvent{nullptr};
- HANDLE MsgEvent{nullptr};
+ HANDLE mMsgEvent{nullptr};
- std::atomic<UINT32> Padding{0u};
+ std::atomic<UINT32> mPadding{0u};
- std::atomic<ALenum> killNow{AL_TRUE};
- std::thread thread;
-} ALCwasapiPlayback;
+ std::atomic<ALenum> mKillNow{AL_TRUE};
+ std::thread mThread;
+};
static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self);
static void ALCwasapiPlayback_Construct(ALCwasapiPlayback *self, ALCdevice *device);
static void ALCwasapiPlayback_Destruct(ALCwasapiPlayback *self);
static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *name);
-static HRESULT ALCwasapiPlayback_openProxy(ALCwasapiPlayback *self);
-static void ALCwasapiPlayback_closeProxy(ALCwasapiPlayback *self);
static ALCboolean ALCwasapiPlayback_reset(ALCwasapiPlayback *self);
-static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self);
static ALCboolean ALCwasapiPlayback_start(ALCwasapiPlayback *self);
-static HRESULT ALCwasapiPlayback_startProxy(ALCwasapiPlayback *self);
static void ALCwasapiPlayback_stop(ALCwasapiPlayback *self);
-static void ALCwasapiPlayback_stopProxy(ALCwasapiPlayback *self);
static DECLARE_FORWARD2(ALCwasapiPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
static DECLARE_FORWARD(ALCwasapiPlayback, ALCbackend, ALCuint, availableSamples)
static ClockLatency ALCwasapiPlayback_getClockLatency(ALCwasapiPlayback *self);
@@ -556,7 +531,6 @@ static DECLARE_FORWARD(ALCwasapiPlayback, ALCbackend, void, lock)
static DECLARE_FORWARD(ALCwasapiPlayback, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(ALCwasapiPlayback)
-DEFINE_ALCWASAPIPROXY_VTABLE(ALCwasapiPlayback);
DEFINE_ALCBACKEND_VTABLE(ALCwasapiPlayback);
@@ -564,35 +538,29 @@ static void ALCwasapiPlayback_Construct(ALCwasapiPlayback *self, ALCdevice *devi
{
new (self) ALCwasapiPlayback{};
SET_VTABLE2(ALCwasapiPlayback, ALCbackend, self);
- SET_VTABLE2(ALCwasapiPlayback, ALCwasapiProxy, self);
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
- ALCwasapiProxy_Construct(STATIC_CAST(ALCwasapiProxy, self));
}
static void ALCwasapiPlayback_Destruct(ALCwasapiPlayback *self)
{
- if(self->MsgEvent)
+ if(self->mMsgEvent)
{
- ThreadRequest req = { self->MsgEvent, 0 };
- if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ ThreadRequest req = { self->mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
- CloseHandle(self->MsgEvent);
- self->MsgEvent = nullptr;
+ CloseHandle(self->mMsgEvent);
+ self->mMsgEvent = nullptr;
}
- if(self->NotifyEvent)
- CloseHandle(self->NotifyEvent);
- self->NotifyEvent = nullptr;
+ if(self->mNotifyEvent != nullptr)
+ CloseHandle(self->mNotifyEvent);
+ self->mNotifyEvent = nullptr;
+ if(self->mMsgEvent != nullptr)
+ CloseHandle(self->mMsgEvent);
+ self->mMsgEvent = nullptr;
- if(self->NotifyEvent != nullptr)
- CloseHandle(self->NotifyEvent);
- self->NotifyEvent = nullptr;
- if(self->MsgEvent != nullptr)
- CloseHandle(self->MsgEvent);
- self->MsgEvent = nullptr;
-
- ALCwasapiProxy_Destruct(STATIC_CAST(ALCwasapiProxy, self));
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCwasapiPlayback();
}
@@ -601,8 +569,8 @@ static void ALCwasapiPlayback_Destruct(ALCwasapiPlayback *self)
FORCE_ALIGN static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self)
{
ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
- IAudioClient *client{self->client};
- IAudioRenderClient *render{self->render};
+ IAudioClient *client{self->mClient};
+ IAudioRenderClient *render{self->mRender};
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if(FAILED(hr))
@@ -619,7 +587,7 @@ FORCE_ALIGN static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self)
ALuint update_size{device->UpdateSize};
UINT32 buffer_len{update_size * device->NumUpdates};
- while(!self->killNow.load(std::memory_order_relaxed))
+ while(!self->mKillNow.load(std::memory_order_relaxed))
{
UINT32 written;
hr = client->GetCurrentPadding(&written);
@@ -631,13 +599,13 @@ FORCE_ALIGN static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self)
V0(device->Backend,unlock)();
break;
}
- self->Padding.store(written, std::memory_order_relaxed);
+ self->mPadding.store(written, std::memory_order_relaxed);
ALuint len{buffer_len - written};
if(len < update_size)
{
DWORD res;
- res = WaitForSingleObjectEx(self->NotifyEvent, 2000, FALSE);
+ res = WaitForSingleObjectEx(self->mNotifyEvent, 2000, FALSE);
if(res != WAIT_OBJECT_0)
ERR("WaitForSingleObjectEx error: 0x%lx\n", res);
continue;
@@ -650,7 +618,7 @@ FORCE_ALIGN static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self)
{
ALCwasapiPlayback_lock(self);
aluMixData(device, buffer, len);
- self->Padding.store(written + len, std::memory_order_relaxed);
+ self->mPadding.store(written + len, std::memory_order_relaxed);
ALCwasapiPlayback_unlock(self);
hr = render->ReleaseBuffer(len, 0);
}
@@ -663,7 +631,7 @@ FORCE_ALIGN static int ALCwasapiPlayback_mixerProc(ALCwasapiPlayback *self)
break;
}
}
- self->Padding.store(0u, std::memory_order_release);
+ self->mPadding.store(0u, std::memory_order_release);
CoUninitialize();
return 0;
@@ -713,9 +681,9 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
{
HRESULT hr = S_OK;
- self->NotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- self->MsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- if(self->NotifyEvent == nullptr || self->MsgEvent == nullptr)
+ self->mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ self->mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ if(self->mNotifyEvent == nullptr || self->mMsgEvent == nullptr)
{
ERR("Failed to create message events: %lu\n", GetLastError());
hr = E_FAIL;
@@ -727,7 +695,7 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
{
if(PlaybackDevices.empty())
{
- ThreadRequest req = { self->MsgEvent, 0 };
+ ThreadRequest req = { self->mMsgEvent, 0 };
if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, ALL_DEVICE_PROBE))
(void)WaitForResponse(&req);
}
@@ -755,7 +723,7 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
else
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
- self->devid = iter->devid;
+ self->mDevId = iter->devid;
alstr_copy_range(&device->DeviceName, &*iter->name.cbegin(), &*iter->name.cend());
hr = S_OK;
}
@@ -764,10 +732,11 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
if(SUCCEEDED(hr))
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(self);
hr = E_FAIL;
- if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
else
ERR("Failed to post thread message: %lu\n", GetLastError());
@@ -775,14 +744,14 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
if(FAILED(hr))
{
- if(self->NotifyEvent != nullptr)
- CloseHandle(self->NotifyEvent);
- self->NotifyEvent = nullptr;
- if(self->MsgEvent != nullptr)
- CloseHandle(self->MsgEvent);
- self->MsgEvent = nullptr;
+ if(self->mNotifyEvent != nullptr)
+ CloseHandle(self->mNotifyEvent);
+ self->mNotifyEvent = nullptr;
+ if(self->mMsgEvent != nullptr)
+ CloseHandle(self->mMsgEvent);
+ self->mMsgEvent = nullptr;
- self->devid.clear();
+ self->mDevId.clear();
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
@@ -791,99 +760,94 @@ static ALCenum ALCwasapiPlayback_open(ALCwasapiPlayback *self, const ALCchar *de
return ALC_NO_ERROR;
}
-static HRESULT ALCwasapiPlayback_openProxy(ALCwasapiPlayback *self)
+HRESULT ALCwasapiPlayback::openProxy()
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- void *ptr;
- HRESULT hr;
+ ALCdevice *device = STATIC_CAST(ALCbackend, this)->mDevice;
- hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, &ptr);
+ void *ptr;
+ HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, &ptr);
if(SUCCEEDED(hr))
{
auto Enumerator = reinterpret_cast<IMMDeviceEnumerator*>(ptr);
- if(self->devid.empty())
- hr = Enumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &self->mmdev);
+ if(mDevId.empty())
+ hr = Enumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &mMMDev);
else
- hr = Enumerator->GetDevice(self->devid.c_str(), &self->mmdev);
+ hr = Enumerator->GetDevice(mDevId.c_str(), &mMMDev);
Enumerator->Release();
}
if(SUCCEEDED(hr))
- hr = self->mmdev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
+ hr = mMMDev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
if(SUCCEEDED(hr))
{
- self->client = reinterpret_cast<IAudioClient*>(ptr);
+ mClient = reinterpret_cast<IAudioClient*>(ptr);
if(alstr_empty(device->DeviceName))
{
std::string devname;
- std::tie(devname, std::ignore) = get_device_name_and_guid(self->mmdev);
+ std::tie(devname, std::ignore) = get_device_name_and_guid(mMMDev);
alstr_copy_range(&device->DeviceName, &*devname.cbegin(), &*devname.cend());
}
}
if(FAILED(hr))
{
- if(self->mmdev)
- self->mmdev->Release();
- self->mmdev = nullptr;
+ if(mMMDev)
+ mMMDev->Release();
+ mMMDev = nullptr;
}
return hr;
}
-
-static void ALCwasapiPlayback_closeProxy(ALCwasapiPlayback *self)
+void ALCwasapiPlayback::closeProxy()
{
- if(self->client)
- self->client->Release();
- self->client = nullptr;
+ if(mClient)
+ mClient->Release();
+ mClient = nullptr;
- if(self->mmdev)
- self->mmdev->Release();
- self->mmdev = nullptr;
+ if(mMMDev)
+ mMMDev->Release();
+ mMMDev = nullptr;
}
static ALCboolean ALCwasapiPlayback_reset(ALCwasapiPlayback *self)
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
HRESULT hr{E_FAIL};
- if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE;
}
-static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
+HRESULT ALCwasapiPlayback::resetProxy()
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- EndpointFormFactor formfactor = UnknownFormFactor;
- WAVEFORMATEXTENSIBLE OutputType;
- WAVEFORMATEX *wfx = nullptr;
- REFERENCE_TIME min_per, buf_time;
- UINT32 buffer_len, min_len;
- void *ptr = nullptr;
- HRESULT hr;
+ ALCdevice *device{STATIC_CAST(ALCbackend, this)->mDevice};
- if(self->client)
- self->client->Release();
- self->client = nullptr;
+ if(mClient)
+ mClient->Release();
+ mClient = nullptr;
- hr = self->mmdev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
+ void *ptr;
+ HRESULT hr = mMMDev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
if(FAILED(hr))
{
ERR("Failed to reactivate audio client: 0x%08lx\n", hr);
return hr;
}
- self->client = reinterpret_cast<IAudioClient*>(ptr);
+ mClient = reinterpret_cast<IAudioClient*>(ptr);
- hr = self->client->GetMixFormat(&wfx);
+ WAVEFORMATEX *wfx;
+ hr = mClient->GetMixFormat(&wfx);
if(FAILED(hr))
{
ERR("Failed to get mix format: 0x%08lx\n", hr);
return hr;
}
+ WAVEFORMATEXTENSIBLE OutputType;
if(!MakeExtensible(&OutputType, wfx))
{
CoTaskMemFree(wfx);
@@ -892,8 +856,8 @@ static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
CoTaskMemFree(wfx);
wfx = nullptr;
- buf_time = ScaleCeil(device->UpdateSize*device->NumUpdates, REFTIME_PER_SEC,
- device->Frequency);
+ REFERENCE_TIME buf_time{ScaleCeil(device->UpdateSize*device->NumUpdates, REFTIME_PER_SEC,
+ device->Frequency)};
if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
device->Frequency = OutputType.Format.nSamplesPerSec;
@@ -990,11 +954,11 @@ static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec *
OutputType.Format.nBlockAlign;
- hr = self->client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
+ hr = mClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
if(FAILED(hr))
{
ERR("Failed to check format support: 0x%08lx\n", hr);
- hr = self->client->GetMixFormat(&wfx);
+ hr = mClient->GetMixFormat(&wfx);
}
if(FAILED(hr))
{
@@ -1063,29 +1027,33 @@ static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
}
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
}
- get_device_formfactor(self->mmdev, &formfactor);
+
+ EndpointFormFactor formfactor = UnknownFormFactor;
+ get_device_formfactor(mMMDev, &formfactor);
device->IsHeadphones = (device->FmtChans == DevFmtStereo &&
(formfactor == Headphones || formfactor == Headset)
);
SetDefaultWFXChannelOrder(device);
- hr = self->client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
- buf_time, 0, &OutputType.Format, nullptr);
+ hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
+ buf_time, 0, &OutputType.Format, nullptr);
if(FAILED(hr))
{
ERR("Failed to initialize audio client: 0x%08lx\n", hr);
return hr;
}
- hr = self->client->GetDevicePeriod(&min_per, nullptr);
+ UINT32 buffer_len, min_len;
+ REFERENCE_TIME min_per;
+ hr = mClient->GetDevicePeriod(&min_per, nullptr);
if(SUCCEEDED(hr))
{
min_len = (UINT32)ScaleCeil(min_per, device->Frequency, REFTIME_PER_SEC);
/* Find the nearest multiple of the period size to the update size */
if(min_len < device->UpdateSize)
min_len *= (device->UpdateSize + min_len/2)/min_len;
- hr = self->client->GetBufferSize(&buffer_len);
+ hr = mClient->GetBufferSize(&buffer_len);
}
if(FAILED(hr))
{
@@ -1102,7 +1070,7 @@ static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
device->UpdateSize = buffer_len / device->NumUpdates;
}
- hr = self->client->SetEventHandle(self->NotifyEvent);
+ hr = mClient->SetEventHandle(mNotifyEvent);
if(FAILED(hr))
{
ERR("Failed to set event handle: 0x%08lx\n", hr);
@@ -1115,46 +1083,46 @@ static HRESULT ALCwasapiPlayback_resetProxy(ALCwasapiPlayback *self)
static ALCboolean ALCwasapiPlayback_start(ALCwasapiPlayback *self)
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
HRESULT hr{E_FAIL};
- if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE;
}
-static HRESULT ALCwasapiPlayback_startProxy(ALCwasapiPlayback *self)
+HRESULT ALCwasapiPlayback::startProxy()
{
- HRESULT hr;
- void *ptr;
+ ResetEvent(mNotifyEvent);
- ResetEvent(self->NotifyEvent);
- hr = self->client->Start();
+ HRESULT hr = mClient->Start();
if(FAILED(hr))
{
ERR("Failed to start audio client: 0x%08lx\n", hr);
return hr;
}
- hr = self->client->GetService(IID_IAudioRenderClient, &ptr);
+ void *ptr;
+ hr = mClient->GetService(IID_IAudioRenderClient, &ptr);
if(SUCCEEDED(hr))
{
- self->render = reinterpret_cast<IAudioRenderClient*>(ptr);
+ mRender = reinterpret_cast<IAudioRenderClient*>(ptr);
try {
- self->killNow.store(AL_FALSE, std::memory_order_release);
- self->thread = std::thread(ALCwasapiPlayback_mixerProc, self);
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread(ALCwasapiPlayback_mixerProc, this);
}
catch(...) {
- self->render->Release();
- self->render = nullptr;
+ mRender->Release();
+ mRender = nullptr;
ERR("Failed to start thread\n");
hr = E_FAIL;
}
}
if(FAILED(hr))
- self->client->Stop();
+ mClient->Stop();
return hr;
}
@@ -1162,33 +1130,34 @@ static HRESULT ALCwasapiPlayback_startProxy(ALCwasapiPlayback *self)
static void ALCwasapiPlayback_stop(ALCwasapiPlayback *self)
{
- ThreadRequest req{ self->MsgEvent, 0 };
- if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ ThreadRequest req{ self->mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
}
-static void ALCwasapiPlayback_stopProxy(ALCwasapiPlayback *self)
+void ALCwasapiPlayback::stopProxy()
{
- if(!self->render || !self->thread.joinable())
+ if(!mRender || !mThread.joinable())
return;
- self->killNow.store(AL_TRUE);
- self->thread.join();
+ mKillNow.store(AL_TRUE);
+ mThread.join();
- self->render->Release();
- self->render = nullptr;
- self->client->Stop();
+ mRender->Release();
+ mRender = nullptr;
+ mClient->Stop();
}
static ClockLatency ALCwasapiPlayback_getClockLatency(ALCwasapiPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
ClockLatency ret;
ALCwasapiPlayback_lock(self);
+ ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = self->Padding.load(std::memory_order_relaxed) * DEVICE_CLOCK_RES /
+ ret.Latency = self->mPadding.load(std::memory_order_relaxed) * DEVICE_CLOCK_RES /
device->Frequency;
ALCwasapiPlayback_unlock(self);
@@ -1196,40 +1165,39 @@ static ClockLatency ALCwasapiPlayback_getClockLatency(ALCwasapiPlayback *self)
}
-typedef struct ALCwasapiCapture {
- DERIVE_FROM_TYPE(ALCbackend);
- DERIVE_FROM_TYPE(ALCwasapiProxy);
+struct ALCwasapiCapture final : public ALCbackend, WasapiProxy {
+ HRESULT openProxy() override;
+ void closeProxy() override;
- std::wstring devid;
+ HRESULT resetProxy() override;
+ HRESULT startProxy() override;
+ void stopProxy() override;
+
+ std::wstring mDevId;
- IMMDevice *mmdev{nullptr};
- IAudioClient *client{nullptr};
- IAudioCaptureClient *capture{nullptr};
- HANDLE NotifyEvent{nullptr};
+ IMMDevice *mMMDev{nullptr};
+ IAudioClient *mClient{nullptr};
+ IAudioCaptureClient *mCapture{nullptr};
+ HANDLE mNotifyEvent{nullptr};
- HANDLE MsgEvent{nullptr};
+ HANDLE mMsgEvent{nullptr};
- ChannelConverter *ChannelConv{nullptr};
- SampleConverter *SampleConv{nullptr};
- ll_ringbuffer_t *Ring{nullptr};
+ ChannelConverter *mChannelConv{nullptr};
+ SampleConverter *mSampleConv{nullptr};
+ ll_ringbuffer_t *mRing{nullptr};
- std::atomic<int> killNow{AL_TRUE};
- std::thread thread;
-} ALCwasapiCapture;
+ std::atomic<int> mKillNow{AL_TRUE};
+ std::thread mThread;
+};
static int ALCwasapiCapture_recordProc(ALCwasapiCapture *self);
static void ALCwasapiCapture_Construct(ALCwasapiCapture *self, ALCdevice *device);
static void ALCwasapiCapture_Destruct(ALCwasapiCapture *self);
static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *name);
-static HRESULT ALCwasapiCapture_openProxy(ALCwasapiCapture *self);
-static void ALCwasapiCapture_closeProxy(ALCwasapiCapture *self);
static DECLARE_FORWARD(ALCwasapiCapture, ALCbackend, ALCboolean, reset)
-static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self);
static ALCboolean ALCwasapiCapture_start(ALCwasapiCapture *self);
-static HRESULT ALCwasapiCapture_startProxy(ALCwasapiCapture *self);
static void ALCwasapiCapture_stop(ALCwasapiCapture *self);
-static void ALCwasapiCapture_stopProxy(ALCwasapiCapture *self);
static ALCenum ALCwasapiCapture_captureSamples(ALCwasapiCapture *self, ALCvoid *buffer, ALCuint samples);
static ALuint ALCwasapiCapture_availableSamples(ALCwasapiCapture *self);
static DECLARE_FORWARD(ALCwasapiCapture, ALCbackend, ClockLatency, getClockLatency)
@@ -1237,7 +1205,6 @@ static DECLARE_FORWARD(ALCwasapiCapture, ALCbackend, void, lock)
static DECLARE_FORWARD(ALCwasapiCapture, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(ALCwasapiCapture)
-DEFINE_ALCWASAPIPROXY_VTABLE(ALCwasapiCapture);
DEFINE_ALCBACKEND_VTABLE(ALCwasapiCapture);
@@ -1245,34 +1212,32 @@ static void ALCwasapiCapture_Construct(ALCwasapiCapture *self, ALCdevice *device
{
new (self) ALCwasapiCapture{};
SET_VTABLE2(ALCwasapiCapture, ALCbackend, self);
- SET_VTABLE2(ALCwasapiCapture, ALCwasapiProxy, self);
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
- ALCwasapiProxy_Construct(STATIC_CAST(ALCwasapiProxy, self));
}
static void ALCwasapiCapture_Destruct(ALCwasapiCapture *self)
{
- if(self->MsgEvent)
+ if(self->mMsgEvent)
{
- ThreadRequest req{ self->MsgEvent, 0 };
- if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ ThreadRequest req{ self->mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_CloseDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
- CloseHandle(self->MsgEvent);
- self->MsgEvent = nullptr;
+ CloseHandle(self->mMsgEvent);
+ self->mMsgEvent = nullptr;
}
- if(self->NotifyEvent != nullptr)
- CloseHandle(self->NotifyEvent);
- self->NotifyEvent = nullptr;
+ if(self->mNotifyEvent != nullptr)
+ CloseHandle(self->mNotifyEvent);
+ self->mNotifyEvent = nullptr;
- ll_ringbuffer_free(self->Ring);
- self->Ring = nullptr;
+ ll_ringbuffer_free(self->mRing);
+ self->mRing = nullptr;
- DestroySampleConverter(&self->SampleConv);
- DestroyChannelConverter(&self->ChannelConv);
+ DestroySampleConverter(&self->mSampleConv);
+ DestroyChannelConverter(&self->mChannelConv);
- ALCwasapiProxy_Destruct(STATIC_CAST(ALCwasapiProxy, self));
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCwasapiCapture();
}
@@ -1281,7 +1246,7 @@ static void ALCwasapiCapture_Destruct(ALCwasapiCapture *self)
FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
{
ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
- IAudioCaptureClient *capture{self->capture};
+ IAudioCaptureClient *capture{self->mCapture};
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if(FAILED(hr))
@@ -1296,7 +1261,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
althrd_setname(althrd_current(), RECORD_THREAD_NAME);
std::vector<float> samples;
- while(!self->killNow.load(std::memory_order_relaxed))
+ while(!self->mKillNow.load(std::memory_order_relaxed))
{
UINT32 avail;
DWORD res;
@@ -1315,23 +1280,23 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
ERR("Failed to get capture buffer: 0x%08lx\n", hr);
else
{
- if(self->ChannelConv)
+ if(self->mChannelConv)
{
samples.resize(numsamples*2);
- ChannelConverterInput(self->ChannelConv, rdata, samples.data(), numsamples);
+ ChannelConverterInput(self->mChannelConv, rdata, samples.data(), numsamples);
rdata = reinterpret_cast<BYTE*>(samples.data());
}
ll_ringbuffer_data_t data[2];
- ll_ringbuffer_get_write_vector(self->Ring, data);
+ ll_ringbuffer_get_write_vector(self->mRing, data);
size_t dstframes;
- if(self->SampleConv)
+ if(self->mSampleConv)
{
const ALvoid *srcdata = rdata;
ALsizei srcframes = numsamples;
- dstframes = SampleConverterInput(self->SampleConv,
+ dstframes = SampleConverterInput(self->mSampleConv,
&srcdata, &srcframes, data[0].buf, (ALsizei)minz(data[0].len, INT_MAX)
);
if(srcframes > 0 && dstframes == data[0].len && data[1].len > 0)
@@ -1340,7 +1305,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
* block was filled, and there's space in the second
* dest block, do another run for the second block.
*/
- dstframes += SampleConverterInput(self->SampleConv,
+ dstframes += SampleConverterInput(self->mSampleConv,
&srcdata, &srcframes, data[1].buf, (ALsizei)minz(data[1].len, INT_MAX)
);
}
@@ -1358,7 +1323,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
dstframes = len1 + len2;
}
- ll_ringbuffer_write_advance(self->Ring, dstframes);
+ ll_ringbuffer_write_advance(self->mRing, dstframes);
hr = capture->ReleaseBuffer(numsamples);
if(FAILED(hr)) ERR("Failed to release capture buffer: 0x%08lx\n", hr);
@@ -1373,7 +1338,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
break;
}
- res = WaitForSingleObjectEx(self->NotifyEvent, 2000, FALSE);
+ res = WaitForSingleObjectEx(self->mNotifyEvent, 2000, FALSE);
if(res != WAIT_OBJECT_0)
ERR("WaitForSingleObjectEx error: 0x%lx\n", res);
}
@@ -1387,9 +1352,9 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
{
HRESULT hr{S_OK};
- self->NotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- self->MsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- if(self->NotifyEvent == nullptr || self->MsgEvent == nullptr)
+ self->mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ self->mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ if(self->mNotifyEvent == nullptr || self->mMsgEvent == nullptr)
{
ERR("Failed to create message events: %lu\n", GetLastError());
hr = E_FAIL;
@@ -1401,7 +1366,7 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
{
if(CaptureDevices.empty())
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, CAPTURE_DEVICE_PROBE))
(void)WaitForResponse(&req);
}
@@ -1429,7 +1394,7 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
else
{
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
- self->devid = iter->devid;
+ self->mDevId = iter->devid;
alstr_copy_range(&device->DeviceName, &*iter->name.cbegin(), &*iter->name.cend());
hr = S_OK;
}
@@ -1438,10 +1403,11 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
if(SUCCEEDED(hr))
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
hr = E_FAIL;
- if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
else
ERR("Failed to post thread message: %lu\n", GetLastError());
@@ -1449,24 +1415,25 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
if(FAILED(hr))
{
- if(self->NotifyEvent != nullptr)
- CloseHandle(self->NotifyEvent);
- self->NotifyEvent = nullptr;
- if(self->MsgEvent != nullptr)
- CloseHandle(self->MsgEvent);
- self->MsgEvent = nullptr;
+ if(self->mNotifyEvent != nullptr)
+ CloseHandle(self->mNotifyEvent);
+ self->mNotifyEvent = nullptr;
+ if(self->mMsgEvent != nullptr)
+ CloseHandle(self->mMsgEvent);
+ self->mMsgEvent = nullptr;
- self->devid.clear();
+ self->mDevId.clear();
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
}
else
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
hr = E_FAIL;
- if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
else
ERR("Failed to post thread message: %lu\n", GetLastError());
@@ -1482,9 +1449,9 @@ static ALCenum ALCwasapiCapture_open(ALCwasapiCapture *self, const ALCchar *devi
return ALC_NO_ERROR;
}
-static HRESULT ALCwasapiCapture_openProxy(ALCwasapiCapture *self)
+HRESULT ALCwasapiCapture::openProxy()
{
- ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
+ ALCdevice *device{STATIC_CAST(ALCbackend, this)->mDevice};
void *ptr;
HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_INPROC_SERVER,
@@ -1492,65 +1459,62 @@ static HRESULT ALCwasapiCapture_openProxy(ALCwasapiCapture *self)
if(SUCCEEDED(hr))
{
auto Enumerator = reinterpret_cast<IMMDeviceEnumerator*>(ptr);
- if(self->devid.empty())
- hr = Enumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &self->mmdev);
+ if(mDevId.empty())
+ hr = Enumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &mMMDev);
else
- hr = Enumerator->GetDevice(self->devid.c_str(), &self->mmdev);
+ hr = Enumerator->GetDevice(mDevId.c_str(), &mMMDev);
Enumerator->Release();
}
if(SUCCEEDED(hr))
- hr = self->mmdev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
+ hr = mMMDev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr);
if(SUCCEEDED(hr))
{
- self->client = reinterpret_cast<IAudioClient*>(ptr);
+ mClient = reinterpret_cast<IAudioClient*>(ptr);
if(alstr_empty(device->DeviceName))
{
std::string devname;
- std::tie(devname, std::ignore) = get_device_name_and_guid(self->mmdev);
+ std::tie(devname, std::ignore) = get_device_name_and_guid(mMMDev);
alstr_copy_range(&device->DeviceName, &*devname.cbegin(), &*devname.cend());
}
}
if(FAILED(hr))
{
- if(self->mmdev)
- self->mmdev->Release();
- self->mmdev = nullptr;
+ if(mMMDev)
+ mMMDev->Release();
+ mMMDev = nullptr;
}
return hr;
}
-
-static void ALCwasapiCapture_closeProxy(ALCwasapiCapture *self)
+void ALCwasapiCapture::closeProxy()
{
- if(self->client)
- self->client->Release();
- self->client = nullptr;
+ if(mClient)
+ mClient->Release();
+ mClient = nullptr;
- if(self->mmdev)
- self->mmdev->Release();
- self->mmdev = nullptr;
+ if(mMMDev)
+ mMMDev->Release();
+ mMMDev = nullptr;
}
-
-static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
+HRESULT ALCwasapiCapture::resetProxy()
{
- ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
+ ALCdevice *device{STATIC_CAST(ALCbackend, this)->mDevice};
- IAudioClient *client{self->client};
- self->client = nullptr;
- if(client) client->Release();
- client = nullptr;
+ if(mClient)
+ mClient->Release();
+ mClient = nullptr;
void *ptr;
- HRESULT hr{self->mmdev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr)};
+ HRESULT hr{mMMDev->Activate(IID_IAudioClient, CLSCTX_INPROC_SERVER, nullptr, &ptr)};
if(FAILED(hr))
{
ERR("Failed to reactivate audio client: 0x%08lx\n", hr);
return hr;
}
- client = self->client = reinterpret_cast<IAudioClient*>(ptr);
+ mClient = reinterpret_cast<IAudioClient*>(ptr);
REFERENCE_TIME buf_time{ScaleCeil(device->UpdateSize*device->NumUpdates, REFTIME_PER_SEC,
device->Frequency)};
@@ -1628,15 +1592,15 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
OutputType.Format.cbSize = sizeof(OutputType) - sizeof(OutputType.Format);
WAVEFORMATEX *wfx;
- hr = client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
+ hr = mClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &OutputType.Format, &wfx);
if(FAILED(hr))
{
ERR("Failed to check format support: 0x%08lx\n", hr);
return hr;
}
- DestroySampleConverter(&self->SampleConv);
- DestroyChannelConverter(&self->ChannelConv);
+ DestroySampleConverter(&mSampleConv);
+ DestroyChannelConverter(&mChannelConv);
if(wfx != nullptr)
{
@@ -1694,8 +1658,8 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
if(device->FmtChans == DevFmtMono && OutputType.Format.nChannels == 2)
{
- self->ChannelConv = CreateChannelConverter(srcType, DevFmtStereo, device->FmtChans);
- if(!self->ChannelConv)
+ mChannelConv = CreateChannelConverter(srcType, DevFmtStereo, device->FmtChans);
+ if(!mChannelConv)
{
ERR("Failed to create %s stereo-to-mono converter\n", DevFmtTypeString(srcType));
return E_FAIL;
@@ -1708,8 +1672,8 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
}
else if(device->FmtChans == DevFmtStereo && OutputType.Format.nChannels == 1)
{
- self->ChannelConv = CreateChannelConverter(srcType, DevFmtMono, device->FmtChans);
- if(!self->ChannelConv)
+ mChannelConv = CreateChannelConverter(srcType, DevFmtMono, device->FmtChans);
+ if(!mChannelConv)
{
ERR("Failed to create %s mono-to-stereo converter\n", DevFmtTypeString(srcType));
return E_FAIL;
@@ -1720,11 +1684,11 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
if(device->Frequency != OutputType.Format.nSamplesPerSec || device->FmtType != srcType)
{
- self->SampleConv = CreateSampleConverter(
+ mSampleConv = CreateSampleConverter(
srcType, device->FmtType, ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder),
OutputType.Format.nSamplesPerSec, device->Frequency
);
- if(!self->SampleConv)
+ if(!mSampleConv)
{
ERR("Failed to create converter for %s format, dst: %s %uhz, src: %s %luhz\n",
DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
@@ -1736,8 +1700,8 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
device->Frequency, DevFmtTypeString(srcType), OutputType.Format.nSamplesPerSec);
}
- hr = client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
- buf_time, 0, &OutputType.Format, nullptr);
+ hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
+ buf_time, 0, &OutputType.Format, nullptr);
if(FAILED(hr))
{
ERR("Failed to initialize audio client: 0x%08lx\n", hr);
@@ -1745,7 +1709,7 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
}
UINT32 buffer_len;
- hr = client->GetBufferSize(&buffer_len);
+ hr = mClient->GetBufferSize(&buffer_len);
if(FAILED(hr))
{
ERR("Failed to get buffer size: 0x%08lx\n", hr);
@@ -1753,18 +1717,18 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
}
buffer_len = maxu(device->UpdateSize*device->NumUpdates, buffer_len);
- ll_ringbuffer_free(self->Ring);
- self->Ring = ll_ringbuffer_create(buffer_len,
+ ll_ringbuffer_free(mRing);
+ mRing = ll_ringbuffer_create(buffer_len,
FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
false
);
- if(!self->Ring)
+ if(!mRing)
{
ERR("Failed to allocate capture ring buffer\n");
return E_OUTOFMEMORY;
}
- hr = client->SetEventHandle(self->NotifyEvent);
+ hr = mClient->SetEventHandle(mNotifyEvent);
if(FAILED(hr))
{
ERR("Failed to set event handle: 0x%08lx\n", hr);
@@ -1777,21 +1741,21 @@ static HRESULT ALCwasapiCapture_resetProxy(ALCwasapiCapture *self)
static ALCboolean ALCwasapiCapture_start(ALCwasapiCapture *self)
{
- ThreadRequest req{ self->MsgEvent, 0 };
+ ThreadRequest req{ self->mMsgEvent, 0 };
HRESULT hr{E_FAIL};
- if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE;
}
-static HRESULT ALCwasapiCapture_startProxy(ALCwasapiCapture *self)
+HRESULT ALCwasapiCapture::startProxy()
{
- ResetEvent(self->NotifyEvent);
+ ResetEvent(mNotifyEvent);
- IAudioClient *client{self->client};
- HRESULT hr{client->Start()};
+ HRESULT hr{mClient->Start()};
if(FAILED(hr))
{
ERR("Failed to start audio client: 0x%08lx\n", hr);
@@ -1799,17 +1763,17 @@ static HRESULT ALCwasapiCapture_startProxy(ALCwasapiCapture *self)
}
void *ptr;
- hr = client->GetService(IID_IAudioCaptureClient, &ptr);
+ hr = mClient->GetService(IID_IAudioCaptureClient, &ptr);
if(SUCCEEDED(hr))
{
- self->capture = reinterpret_cast<IAudioCaptureClient*>(ptr);
+ mCapture = reinterpret_cast<IAudioCaptureClient*>(ptr);
try {
- self->killNow.store(AL_FALSE, std::memory_order_release);
- self->thread = std::thread(ALCwasapiCapture_recordProc, self);
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread(ALCwasapiCapture_recordProc, this);
}
catch(...) {
- self->capture->Release();
- self->capture = nullptr;
+ mCapture->Release();
+ mCapture = nullptr;
ERR("Failed to start thread\n");
hr = E_FAIL;
}
@@ -1817,8 +1781,8 @@ static HRESULT ALCwasapiCapture_startProxy(ALCwasapiCapture *self)
if(FAILED(hr))
{
- client->Stop();
- client->Reset();
+ mClient->Stop();
+ mClient->Reset();
}
return hr;
@@ -1827,44 +1791,45 @@ static HRESULT ALCwasapiCapture_startProxy(ALCwasapiCapture *self)
static void ALCwasapiCapture_stop(ALCwasapiCapture *self)
{
- ThreadRequest req{ self->MsgEvent, 0 };
- if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)STATIC_CAST(ALCwasapiProxy, self)))
+ ThreadRequest req{ self->mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(self);
+ if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
}
-static void ALCwasapiCapture_stopProxy(ALCwasapiCapture *self)
+void ALCwasapiCapture::stopProxy()
{
- if(!self->capture || !self->thread.joinable())
+ if(!mCapture || !mThread.joinable())
return;
- self->killNow.store(AL_TRUE);
- self->thread.join();
+ mKillNow.store(AL_TRUE);
+ mThread.join();
- self->capture->Release();
- self->capture = nullptr;
- self->client->Stop();
- self->client->Reset();
+ mCapture->Release();
+ mCapture = nullptr;
+ mClient->Stop();
+ mClient->Reset();
}
static ALuint ALCwasapiCapture_availableSamples(ALCwasapiCapture *self)
{
- return (ALuint)ll_ringbuffer_read_space(self->Ring);
+ return (ALuint)ll_ringbuffer_read_space(self->mRing);
}
static ALCenum ALCwasapiCapture_captureSamples(ALCwasapiCapture *self, ALCvoid *buffer, ALCuint samples)
{
if(ALCwasapiCapture_availableSamples(self) < samples)
return ALC_INVALID_VALUE;
- ll_ringbuffer_read(self->Ring, reinterpret_cast<char*>(buffer), samples);
+ ll_ringbuffer_read(self->mRing, reinterpret_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
-typedef struct ALCwasapiBackendFactory {
- DERIVE_FROM_TYPE(ALCbackendFactory);
-} ALCwasapiBackendFactory;
-#define ALCWASAPIBACKENDFACTORY_INITIALIZER { GET_VTABLE2(ALCwasapiBackendFactory, ALCbackendFactory) }
+struct ALCwasapiBackendFactory final : public ALCbackendFactory {
+ ALCwasapiBackendFactory() noexcept;
+};
+#define ALCWASAPIBACKENDFACTORY_INITIALIZER GET_VTABLE2(ALCwasapiBackendFactory, ALCbackendFactory)
static ALCboolean ALCwasapiBackendFactory_init(ALCwasapiBackendFactory *self);
static void ALCwasapiBackendFactory_deinit(ALCwasapiBackendFactory *self);
@@ -1874,6 +1839,11 @@ static ALCbackend* ALCwasapiBackendFactory_createBackend(ALCwasapiBackendFactory
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCwasapiBackendFactory);
+ALCwasapiBackendFactory::ALCwasapiBackendFactory() noexcept
+ : ALCbackendFactory{ALCWASAPIBACKENDFACTORY_INITIALIZER}
+{
+}
+
static ALCboolean ALCwasapiBackendFactory_init(ALCwasapiBackendFactory* UNUSED(self))
{
@@ -1889,7 +1859,7 @@ static ALCboolean ALCwasapiBackendFactory_init(ALCwasapiBackendFactory* UNUSED(s
ERR("Failed to create event: %lu\n", GetLastError());
else
{
- ThreadHdl = CreateThread(nullptr, 0, ALCwasapiProxy_messageHandler, &req, 0, &ThreadID);
+ ThreadHdl = CreateThread(nullptr, 0, WasapiProxy_messageHandler, &req, 0, &ThreadID);
if(ThreadHdl != nullptr)
InitResult = WaitForResponse(&req);
CloseHandle(req.FinishedEvt);
@@ -1979,6 +1949,6 @@ static ALCbackend* ALCwasapiBackendFactory_createBackend(ALCwasapiBackendFactory
ALCbackendFactory *ALCwasapiBackendFactory_getFactory(void)
{
- static ALCwasapiBackendFactory factory{ALCWASAPIBACKENDFACTORY_INITIALIZER};
+ static ALCwasapiBackendFactory factory{};
return STATIC_CAST(ALCbackendFactory, &factory);
}