aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/wasapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends/wasapi.cpp')
-rw-r--r--Alc/backends/wasapi.cpp262
1 files changed, 103 insertions, 159 deletions
diff --git a/Alc/backends/wasapi.cpp b/Alc/backends/wasapi.cpp
index 5c97324e..0d3d067e 100644
--- a/Alc/backends/wasapi.cpp
+++ b/Alc/backends/wasapi.cpp
@@ -494,19 +494,25 @@ DWORD WasapiProxy::messageHandler(void *ptr)
}
-struct WasapiPlayback final : public ALCbackend, WasapiProxy {
- WasapiPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct WasapiPlayback final : public BackendBase, WasapiProxy {
+ WasapiPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
~WasapiPlayback() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
HRESULT openProxy() override;
void closeProxy() override;
+ ALCboolean reset() override;
HRESULT resetProxy() override;
+ ALCboolean start() override;
HRESULT startProxy() override;
+ void stop() override;
void stopProxy() override;
+ ClockLatency getClockLatency() override;
+
std::wstring mDevId;
IMMDevice *mMMDev{nullptr};
@@ -522,32 +528,9 @@ struct WasapiPlayback final : public ALCbackend, WasapiProxy {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "WasapiPlayback::"; }
+ DEF_NEWDEL(WasapiPlayback)
};
-void WasapiPlayback_Construct(WasapiPlayback *self, ALCdevice *device);
-void WasapiPlayback_Destruct(WasapiPlayback *self);
-ALCenum WasapiPlayback_open(WasapiPlayback *self, const ALCchar *name);
-ALCboolean WasapiPlayback_reset(WasapiPlayback *self);
-ALCboolean WasapiPlayback_start(WasapiPlayback *self);
-void WasapiPlayback_stop(WasapiPlayback *self);
-DECLARE_FORWARD2(WasapiPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
-DECLARE_FORWARD(WasapiPlayback, ALCbackend, ALCuint, availableSamples)
-ClockLatency WasapiPlayback_getClockLatency(WasapiPlayback *self);
-DECLARE_FORWARD(WasapiPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(WasapiPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(WasapiPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(WasapiPlayback);
-
-void WasapiPlayback_Construct(WasapiPlayback *self, ALCdevice *device)
-{
- new (self) WasapiPlayback{device};
- SET_VTABLE2(WasapiPlayback, ALCbackend, self);
-}
-
-void WasapiPlayback_Destruct(WasapiPlayback *self)
-{ self->~WasapiPlayback(); }
-
WasapiPlayback::~WasapiPlayback()
{
if(mMsgEvent)
@@ -576,9 +559,9 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
if(FAILED(hr))
{
ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr);
- WasapiPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "COM init failed: 0x%08lx", hr);
- WasapiPlayback_unlock(this);
+ unlock();
return 1;
}
@@ -594,9 +577,9 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
if(FAILED(hr))
{
ERR("Failed to get padding: 0x%08lx\n", hr);
- WasapiPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to retrieve buffer padding: 0x%08lx", hr);
- WasapiPlayback_unlock(this);
+ unlock();
break;
}
mPadding.store(written, std::memory_order_relaxed);
@@ -615,18 +598,18 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
hr = mRender->GetBuffer(len, &buffer);
if(SUCCEEDED(hr))
{
- WasapiPlayback_lock(this);
+ lock();
aluMixData(mDevice, buffer, len);
mPadding.store(written + len, std::memory_order_relaxed);
- WasapiPlayback_unlock(this);
+ unlock();
hr = mRender->ReleaseBuffer(len, 0);
}
if(FAILED(hr))
{
ERR("Failed to buffer data: 0x%08lx\n", hr);
- WasapiPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to send playback samples: 0x%08lx", hr);
- WasapiPlayback_unlock(this);
+ unlock();
break;
}
}
@@ -676,13 +659,13 @@ ALCboolean MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX *in)
return ALC_TRUE;
}
-ALCenum WasapiPlayback_open(WasapiPlayback *self, const ALCchar *deviceName)
+ALCenum WasapiPlayback::open(const ALCchar *name)
{
- HRESULT hr = S_OK;
+ HRESULT hr{S_OK};
- self->mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- self->mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- if(self->mNotifyEvent == nullptr || self->mMsgEvent == nullptr)
+ mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ if(mNotifyEvent == nullptr || mMsgEvent == nullptr)
{
ERR("Failed to create message events: %lu\n", GetLastError());
hr = E_FAIL;
@@ -690,35 +673,34 @@ ALCenum WasapiPlayback_open(WasapiPlayback *self, const ALCchar *deviceName)
if(SUCCEEDED(hr))
{
- if(deviceName)
+ if(name)
{
if(PlaybackDevices.empty())
{
- ThreadRequest req = { self->mMsgEvent, 0 };
+ ThreadRequest req = { mMsgEvent, 0 };
if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, ALL_DEVICE_PROBE))
(void)WaitForResponse(&req);
}
hr = E_FAIL;
auto iter = std::find_if(PlaybackDevices.cbegin(), PlaybackDevices.cend(),
- [deviceName](const DevMap &entry) -> bool
- { return entry.name == deviceName || entry.endpoint_guid == deviceName; }
+ [name](const DevMap &entry) -> bool
+ { return entry.name == name || entry.endpoint_guid == name; }
);
if(iter == PlaybackDevices.cend())
{
- std::wstring wname{utf8_to_wstr(deviceName)};
+ std::wstring wname{utf8_to_wstr(name)};
iter = std::find_if(PlaybackDevices.cbegin(), PlaybackDevices.cend(),
[&wname](const DevMap &entry) -> bool
{ return entry.devid == wname; }
);
}
if(iter == PlaybackDevices.cend())
- WARN("Failed to find device name matching \"%s\"\n", deviceName);
+ WARN("Failed to find device name matching \"%s\"\n", name);
else
{
- ALCdevice *device{self->mDevice};
- self->mDevId = iter->devid;
- device->DeviceName = iter->name;
+ mDevId = iter->devid;
+ mDevice->DeviceName = iter->name;
hr = S_OK;
}
}
@@ -726,8 +708,8 @@ ALCenum WasapiPlayback_open(WasapiPlayback *self, const ALCchar *deviceName)
if(SUCCEEDED(hr))
{
- ThreadRequest req{ self->mMsgEvent, 0 };
- auto proxy = static_cast<WasapiProxy*>(self);
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
hr = E_FAIL;
if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)proxy))
@@ -738,14 +720,14 @@ ALCenum WasapiPlayback_open(WasapiPlayback *self, const ALCchar *deviceName)
if(FAILED(hr))
{
- if(self->mNotifyEvent != nullptr)
- CloseHandle(self->mNotifyEvent);
- self->mNotifyEvent = nullptr;
- if(self->mMsgEvent != nullptr)
- CloseHandle(self->mMsgEvent);
- self->mMsgEvent = nullptr;
+ if(mNotifyEvent != nullptr)
+ CloseHandle(mNotifyEvent);
+ mNotifyEvent = nullptr;
+ if(mMsgEvent != nullptr)
+ CloseHandle(mMsgEvent);
+ mMsgEvent = nullptr;
- self->mDevId.clear();
+ mDevId.clear();
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
@@ -798,12 +780,11 @@ void WasapiPlayback::closeProxy()
}
-ALCboolean WasapiPlayback_reset(WasapiPlayback *self)
+ALCboolean WasapiPlayback::reset()
{
- ThreadRequest req{ self->mMsgEvent, 0 };
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
HRESULT hr{E_FAIL};
-
- auto proxy = static_cast<WasapiProxy*>(self);
if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
@@ -1066,12 +1047,11 @@ HRESULT WasapiPlayback::resetProxy()
}
-ALCboolean WasapiPlayback_start(WasapiPlayback *self)
+ALCboolean WasapiPlayback::start()
{
- ThreadRequest req{ self->mMsgEvent, 0 };
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
HRESULT hr{E_FAIL};
-
- auto proxy = static_cast<WasapiProxy*>(self);
if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
@@ -1113,10 +1093,10 @@ HRESULT WasapiPlayback::startProxy()
}
-void WasapiPlayback_stop(WasapiPlayback *self)
+void WasapiPlayback::stop()
{
- ThreadRequest req{ self->mMsgEvent, 0 };
- auto proxy = static_cast<WasapiProxy*>(self);
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
}
@@ -1135,34 +1115,39 @@ void WasapiPlayback::stopProxy()
}
-ClockLatency WasapiPlayback_getClockLatency(WasapiPlayback *self)
+ClockLatency WasapiPlayback::getClockLatency()
{
ClockLatency ret;
- WasapiPlayback_lock(self);
- ALCdevice *device{self->mDevice};
- ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{self->mPadding.load(std::memory_order_relaxed)};
- ret.Latency /= device->Frequency;
- WasapiPlayback_unlock(self);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.Latency = std::chrono::seconds{mPadding.load(std::memory_order_relaxed)};
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
-struct WasapiCapture final : public ALCbackend, WasapiProxy {
- WasapiCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct WasapiCapture final : public BackendBase, WasapiProxy {
+ WasapiCapture(ALCdevice *device) noexcept : BackendBase{device} { }
~WasapiCapture() override;
int recordProc();
+ ALCenum open(const ALCchar *name) override;
HRESULT openProxy() override;
void closeProxy() override;
HRESULT resetProxy() override;
+ ALCboolean start() override;
HRESULT startProxy() override;
+ void stop() override;
void stopProxy() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
std::wstring mDevId;
IMMDevice *mMMDev{nullptr};
@@ -1180,33 +1165,9 @@ struct WasapiCapture final : public ALCbackend, WasapiProxy {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "WasapiCapture::"; }
+ DEF_NEWDEL(WasapiCapture)
};
-void WasapiCapture_Construct(WasapiCapture *self, ALCdevice *device);
-void WasapiCapture_Destruct(WasapiCapture *self);
-ALCenum WasapiCapture_open(WasapiCapture *self, const ALCchar *name);
-DECLARE_FORWARD(WasapiCapture, ALCbackend, ALCboolean, reset)
-ALCboolean WasapiCapture_start(WasapiCapture *self);
-void WasapiCapture_stop(WasapiCapture *self);
-ALCenum WasapiCapture_captureSamples(WasapiCapture *self, ALCvoid *buffer, ALCuint samples);
-ALuint WasapiCapture_availableSamples(WasapiCapture *self);
-DECLARE_FORWARD(WasapiCapture, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(WasapiCapture, ALCbackend, void, lock)
-DECLARE_FORWARD(WasapiCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(WasapiCapture)
-
-DEFINE_ALCBACKEND_VTABLE(WasapiCapture);
-
-
-void WasapiCapture_Construct(WasapiCapture *self, ALCdevice *device)
-{
- new (self) WasapiCapture{device};
- SET_VTABLE2(WasapiCapture, ALCbackend, self);
-}
-
-void WasapiCapture_Destruct(WasapiCapture *self)
-{ self->~WasapiCapture(); }
-
WasapiCapture::~WasapiCapture()
{
if(mMsgEvent)
@@ -1232,9 +1193,9 @@ FORCE_ALIGN int WasapiCapture::recordProc()
if(FAILED(hr))
{
ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr);
- WasapiCapture_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "COM init failed: 0x%08lx", hr);
- WasapiCapture_unlock(this);
+ unlock();
return 1;
}
@@ -1306,9 +1267,9 @@ FORCE_ALIGN int WasapiCapture::recordProc()
if(FAILED(hr))
{
- WasapiCapture_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to capture samples: 0x%08lx", hr);
- WasapiCapture_unlock(this);
+ unlock();
break;
}
@@ -1322,13 +1283,13 @@ FORCE_ALIGN int WasapiCapture::recordProc()
}
-ALCenum WasapiCapture_open(WasapiCapture *self, const ALCchar *deviceName)
+ALCenum WasapiCapture::open(const ALCchar *name)
{
HRESULT hr{S_OK};
- self->mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- self->mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- if(self->mNotifyEvent == nullptr || self->mMsgEvent == nullptr)
+ mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ mMsgEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ if(mNotifyEvent == nullptr || mMsgEvent == nullptr)
{
ERR("Failed to create message events: %lu\n", GetLastError());
hr = E_FAIL;
@@ -1336,35 +1297,34 @@ ALCenum WasapiCapture_open(WasapiCapture *self, const ALCchar *deviceName)
if(SUCCEEDED(hr))
{
- if(deviceName)
+ if(name)
{
if(CaptureDevices.empty())
{
- ThreadRequest req{ self->mMsgEvent, 0 };
+ ThreadRequest req{ mMsgEvent, 0 };
if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, CAPTURE_DEVICE_PROBE))
(void)WaitForResponse(&req);
}
hr = E_FAIL;
auto iter = std::find_if(CaptureDevices.cbegin(), CaptureDevices.cend(),
- [deviceName](const DevMap &entry) -> bool
- { return entry.name == deviceName || entry.endpoint_guid == deviceName; }
+ [name](const DevMap &entry) -> bool
+ { return entry.name == name || entry.endpoint_guid == name; }
);
if(iter == CaptureDevices.cend())
{
- std::wstring wname{utf8_to_wstr(deviceName)};
+ std::wstring wname{utf8_to_wstr(name)};
iter = std::find_if(CaptureDevices.cbegin(), CaptureDevices.cend(),
[&wname](const DevMap &entry) -> bool
{ return entry.devid == wname; }
);
}
if(iter == CaptureDevices.cend())
- WARN("Failed to find device name matching \"%s\"\n", deviceName);
+ WARN("Failed to find device name matching \"%s\"\n", name);
else
{
- ALCdevice *device{self->mDevice};
- self->mDevId = iter->devid;
- device->DeviceName = iter->name;
+ mDevId = iter->devid;
+ mDevice->DeviceName = iter->name;
hr = S_OK;
}
}
@@ -1372,10 +1332,9 @@ ALCenum WasapiCapture_open(WasapiCapture *self, const ALCchar *deviceName)
if(SUCCEEDED(hr))
{
- ThreadRequest req{ self->mMsgEvent, 0 };
-
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
hr = E_FAIL;
- auto proxy = static_cast<WasapiProxy*>(self);
if(PostThreadMessage(ThreadID, WM_USER_OpenDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
else
@@ -1384,24 +1343,23 @@ ALCenum WasapiCapture_open(WasapiCapture *self, const ALCchar *deviceName)
if(FAILED(hr))
{
- if(self->mNotifyEvent != nullptr)
- CloseHandle(self->mNotifyEvent);
- self->mNotifyEvent = nullptr;
- if(self->mMsgEvent != nullptr)
- CloseHandle(self->mMsgEvent);
- self->mMsgEvent = nullptr;
+ if(mNotifyEvent != nullptr)
+ CloseHandle(mNotifyEvent);
+ mNotifyEvent = nullptr;
+ if(mMsgEvent != nullptr)
+ CloseHandle(mMsgEvent);
+ mMsgEvent = nullptr;
- self->mDevId.clear();
+ mDevId.clear();
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
}
else
{
- ThreadRequest req{ self->mMsgEvent, 0 };
-
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
hr = E_FAIL;
- auto proxy = static_cast<WasapiProxy*>(self);
if(PostThreadMessage(ThreadID, WM_USER_ResetDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
else
@@ -1694,12 +1652,11 @@ HRESULT WasapiCapture::resetProxy()
}
-ALCboolean WasapiCapture_start(WasapiCapture *self)
+ALCboolean WasapiCapture::start()
{
- ThreadRequest req{ self->mMsgEvent, 0 };
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
HRESULT hr{E_FAIL};
-
- auto proxy = static_cast<WasapiProxy*>(self);
if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)proxy))
hr = WaitForResponse(&req);
@@ -1744,10 +1701,10 @@ HRESULT WasapiCapture::startProxy()
}
-void WasapiCapture_stop(WasapiCapture *self)
+void WasapiCapture::stop()
{
- ThreadRequest req{ self->mMsgEvent, 0 };
- auto proxy = static_cast<WasapiProxy*>(self);
+ ThreadRequest req{ mMsgEvent, 0 };
+ auto proxy = static_cast<WasapiProxy*>(this);
if(PostThreadMessage(ThreadID, WM_USER_StopDevice, (WPARAM)&req, (LPARAM)proxy))
(void)WaitForResponse(&req);
}
@@ -1767,16 +1724,12 @@ void WasapiCapture::stopProxy()
}
-ALuint WasapiCapture_availableSamples(WasapiCapture *self)
-{
- RingBuffer *ring{self->mRing.get()};
- return (ALuint)ring->readSpace();
-}
+ALCuint WasapiCapture::availableSamples()
+{ return (ALCuint)mRing->readSpace(); }
-ALCenum WasapiCapture_captureSamples(WasapiCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum WasapiCapture::captureSamples(void *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
@@ -1857,21 +1810,12 @@ void WasapiBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *WasapiBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *WasapiBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- WasapiPlayback *backend;
- NEW_OBJ(backend, WasapiPlayback)(device);
- return backend;
- }
+ return new WasapiPlayback{device};
if(type == ALCbackend_Capture)
- {
- WasapiCapture *backend;
- NEW_OBJ(backend, WasapiCapture)(device);
- return backend;
- }
-
+ return new WasapiCapture{device};
return nullptr;
}