aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/winmm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends/winmm.cpp')
-rw-r--r--Alc/backends/winmm.cpp293
1 files changed, 145 insertions, 148 deletions
diff --git a/Alc/backends/winmm.cpp b/Alc/backends/winmm.cpp
index 1258b6a2..09b7a2e2 100644
--- a/Alc/backends/winmm.cpp
+++ b/Alc/backends/winmm.cpp
@@ -120,11 +120,19 @@ void ProbeCaptureDevices(void)
}
-struct ALCwinmmPlayback final : public ALCbackend {
+struct WinMMPlayback final : public ALCbackend {
+ WinMMPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+ ~WinMMPlayback() override;
+
+ static void CALLBACK waveOutProcC(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
+ void CALLBACK waveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR param1, DWORD_PTR param2);
+
+ int mixerProc();
+
std::atomic<ALuint> mWritable{0u};
al::semaphore mSem;
int mIdx{0};
- std::array<WAVEHDR,4> mWaveBuffer;
+ std::array<WAVEHDR,4> mWaveBuffer{};
HWAVEOUT mOutHdl{nullptr};
@@ -133,105 +141,96 @@ struct ALCwinmmPlayback final : public ALCbackend {
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
- ALCwinmmPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "WinMMPlayback::"; }
};
-void ALCwinmmPlayback_Construct(ALCwinmmPlayback *self, ALCdevice *device);
-void ALCwinmmPlayback_Destruct(ALCwinmmPlayback *self);
-
-void CALLBACK ALCwinmmPlayback_waveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
-int ALCwinmmPlayback_mixerProc(ALCwinmmPlayback *self);
-
-ALCenum ALCwinmmPlayback_open(ALCwinmmPlayback *self, const ALCchar *name);
-ALCboolean ALCwinmmPlayback_reset(ALCwinmmPlayback *self);
-ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self);
-void ALCwinmmPlayback_stop(ALCwinmmPlayback *self);
-DECLARE_FORWARD2(ALCwinmmPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
-DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCwinmmPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(ALCwinmmPlayback);
-
-
-void ALCwinmmPlayback_Construct(ALCwinmmPlayback *self, ALCdevice *device)
+void WinMMPlayback_Construct(WinMMPlayback *self, ALCdevice *device);
+void WinMMPlayback_Destruct(WinMMPlayback *self);
+ALCenum WinMMPlayback_open(WinMMPlayback *self, const ALCchar *name);
+ALCboolean WinMMPlayback_reset(WinMMPlayback *self);
+ALCboolean WinMMPlayback_start(WinMMPlayback *self);
+void WinMMPlayback_stop(WinMMPlayback *self);
+DECLARE_FORWARD2(WinMMPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
+DECLARE_FORWARD(WinMMPlayback, ALCbackend, ALCuint, availableSamples)
+DECLARE_FORWARD(WinMMPlayback, ALCbackend, ClockLatency, getClockLatency)
+DECLARE_FORWARD(WinMMPlayback, ALCbackend, void, lock)
+DECLARE_FORWARD(WinMMPlayback, ALCbackend, void, unlock)
+DECLARE_DEFAULT_ALLOCATORS(WinMMPlayback)
+
+DEFINE_ALCBACKEND_VTABLE(WinMMPlayback);
+
+void WinMMPlayback_Construct(WinMMPlayback *self, ALCdevice *device)
{
- new (self) ALCwinmmPlayback{device};
- SET_VTABLE2(ALCwinmmPlayback, ALCbackend, self);
-
- std::fill(self->mWaveBuffer.begin(), self->mWaveBuffer.end(), WAVEHDR{});
+ new (self) WinMMPlayback{device};
+ SET_VTABLE2(WinMMPlayback, ALCbackend, self);
}
-void ALCwinmmPlayback_Destruct(ALCwinmmPlayback *self)
-{
- if(self->mOutHdl)
- waveOutClose(self->mOutHdl);
- self->mOutHdl = nullptr;
+void WinMMPlayback_Destruct(WinMMPlayback *self)
+{ self->~WinMMPlayback(); }
- al_free(self->mWaveBuffer[0].lpData);
- std::fill(self->mWaveBuffer.begin(), self->mWaveBuffer.end(), WAVEHDR{});
+WinMMPlayback::~WinMMPlayback()
+{
+ if(mOutHdl)
+ waveOutClose(mOutHdl);
+ mOutHdl = nullptr;
- self->~ALCwinmmPlayback();
+ al_free(mWaveBuffer[0].lpData);
+ std::fill(mWaveBuffer.begin(), mWaveBuffer.end(), WAVEHDR{});
}
-/* ALCwinmmPlayback_waveOutProc
+void CALLBACK WinMMPlayback::waveOutProcC(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
+{ reinterpret_cast<WinMMPlayback*>(instance)->waveOutProc(device, msg, param1, param2); }
+
+/* WinMMPlayback::waveOutProc
*
- * Posts a message to 'ALCwinmmPlayback_mixerProc' everytime a WaveOut Buffer
- * is completed and returns to the application (for more data)
+ * Posts a message to 'WinMMPlayback::mixerProc' everytime a WaveOut Buffer is
+ * completed and returns to the application (for more data)
*/
-void CALLBACK ALCwinmmPlayback_waveOutProc(HWAVEOUT UNUSED(device), UINT msg,
- DWORD_PTR instance, DWORD_PTR UNUSED(param1),
- DWORD_PTR UNUSED(param2))
+void CALLBACK WinMMPlayback::waveOutProc(HWAVEOUT UNUSED(device), UINT msg,
+ DWORD_PTR UNUSED(param1), DWORD_PTR UNUSED(param2))
{
- if(msg != WOM_DONE)
- return;
-
- auto self = reinterpret_cast<ALCwinmmPlayback*>(instance);
- self->mWritable.fetch_add(1, std::memory_order_acq_rel);
- self->mSem.post();
+ if(msg != WOM_DONE) return;
+ mWritable.fetch_add(1, std::memory_order_acq_rel);
+ mSem.post();
}
-FORCE_ALIGN int ALCwinmmPlayback_mixerProc(ALCwinmmPlayback *self)
+FORCE_ALIGN int WinMMPlayback::mixerProc()
{
- ALCdevice *device{self->mDevice};
-
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
- ALCwinmmPlayback_lock(self);
- while(!self->mKillNow.load(std::memory_order_acquire) &&
- device->Connected.load(std::memory_order_acquire))
+ WinMMPlayback_lock(this);
+ while(!mKillNow.load(std::memory_order_acquire) &&
+ mDevice->Connected.load(std::memory_order_acquire))
{
- ALsizei todo = self->mWritable.load(std::memory_order_acquire);
+ ALsizei todo = mWritable.load(std::memory_order_acquire);
if(todo < 1)
{
- ALCwinmmPlayback_unlock(self);
- self->mSem.wait();
- ALCwinmmPlayback_lock(self);
+ WinMMPlayback_unlock(this);
+ mSem.wait();
+ WinMMPlayback_lock(this);
continue;
}
- int widx{self->mIdx};
+ int widx{mIdx};
do {
- WAVEHDR &waveHdr = self->mWaveBuffer[widx];
- widx = (widx+1) % self->mWaveBuffer.size();
+ WAVEHDR &waveHdr = mWaveBuffer[widx];
+ widx = (widx+1) % mWaveBuffer.size();
- aluMixData(device, waveHdr.lpData, device->UpdateSize);
- self->mWritable.fetch_sub(1, std::memory_order_acq_rel);
- waveOutWrite(self->mOutHdl, &waveHdr, sizeof(WAVEHDR));
+ aluMixData(mDevice, waveHdr.lpData, mDevice->UpdateSize);
+ mWritable.fetch_sub(1, std::memory_order_acq_rel);
+ waveOutWrite(mOutHdl, &waveHdr, sizeof(WAVEHDR));
} while(--todo);
- self->mIdx = widx;
+ mIdx = widx;
}
- ALCwinmmPlayback_unlock(self);
+ WinMMPlayback_unlock(this);
return 0;
}
-ALCenum ALCwinmmPlayback_open(ALCwinmmPlayback *self, const ALCchar *deviceName)
+ALCenum WinMMPlayback_open(WinMMPlayback *self, const ALCchar *deviceName)
{
ALCdevice *device{self->mDevice};
@@ -269,8 +268,7 @@ retry_open:
self->mFormat.cbSize = 0;
MMRESULT res{waveOutOpen(&self->mOutHdl, DeviceID, &self->mFormat,
- (DWORD_PTR)&ALCwinmmPlayback_waveOutProc, (DWORD_PTR)self, CALLBACK_FUNCTION
- )};
+ (DWORD_PTR)&WinMMPlayback::waveOutProcC, (DWORD_PTR)self, CALLBACK_FUNCTION)};
if(res != MMSYSERR_NOERROR)
{
if(device->FmtType == DevFmtFloat)
@@ -286,7 +284,7 @@ retry_open:
return ALC_NO_ERROR;
}
-ALCboolean ALCwinmmPlayback_reset(ALCwinmmPlayback *self)
+ALCboolean WinMMPlayback_reset(WinMMPlayback *self)
{
ALCdevice *device{self->mDevice};
@@ -354,7 +352,7 @@ ALCboolean ALCwinmmPlayback_reset(ALCwinmmPlayback *self)
return ALC_TRUE;
}
-ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self)
+ALCboolean WinMMPlayback_start(WinMMPlayback *self)
{
try {
std::for_each(self->mWaveBuffer.begin(), self->mWaveBuffer.end(),
@@ -365,7 +363,7 @@ ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self)
std::memory_order_release);
self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread(ALCwinmmPlayback_mixerProc, self);
+ self->mThread = std::thread{std::mem_fn(&WinMMPlayback::mixerProc), self};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -376,7 +374,7 @@ ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self)
return ALC_FALSE;
}
-void ALCwinmmPlayback_stop(ALCwinmmPlayback *self)
+void WinMMPlayback_stop(WinMMPlayback *self)
{
if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
return;
@@ -392,7 +390,15 @@ void ALCwinmmPlayback_stop(ALCwinmmPlayback *self)
}
-struct ALCwinmmCapture final : public ALCbackend {
+struct WinMMCapture final : public ALCbackend {
+ WinMMCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+ ~WinMMCapture() override;
+
+ static void CALLBACK waveInProcC(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
+ void CALLBACK waveInProc(HWAVEIN device, UINT msg, DWORD_PTR param1, DWORD_PTR param2);
+
+ int captureProc();
+
std::atomic<ALuint> mReadable{0u};
al::semaphore mSem;
int mIdx{0};
@@ -407,104 +413,95 @@ struct ALCwinmmCapture final : public ALCbackend {
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
- ALCwinmmCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "WinMMCapture::"; }
};
-void ALCwinmmCapture_Construct(ALCwinmmCapture *self, ALCdevice *device);
-void ALCwinmmCapture_Destruct(ALCwinmmCapture *self);
-
-void CALLBACK ALCwinmmCapture_waveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
-int ALCwinmmCapture_captureProc(ALCwinmmCapture *self);
-
-ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *deviceName);
-DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, ALCboolean, reset)
-ALCboolean ALCwinmmCapture_start(ALCwinmmCapture *self);
-void ALCwinmmCapture_stop(ALCwinmmCapture *self);
-ALCenum ALCwinmmCapture_captureSamples(ALCwinmmCapture *self, ALCvoid *buffer, ALCuint samples);
-ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self);
-DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCwinmmCapture)
-
-DEFINE_ALCBACKEND_VTABLE(ALCwinmmCapture);
-
-
-void ALCwinmmCapture_Construct(ALCwinmmCapture *self, ALCdevice *device)
+void WinMMCapture_Construct(WinMMCapture *self, ALCdevice *device);
+void WinMMCapture_Destruct(WinMMCapture *self);
+ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName);
+DECLARE_FORWARD(WinMMCapture, ALCbackend, ALCboolean, reset)
+ALCboolean WinMMCapture_start(WinMMCapture *self);
+void WinMMCapture_stop(WinMMCapture *self);
+ALCenum WinMMCapture_captureSamples(WinMMCapture *self, ALCvoid *buffer, ALCuint samples);
+ALCuint WinMMCapture_availableSamples(WinMMCapture *self);
+DECLARE_FORWARD(WinMMCapture, ALCbackend, ClockLatency, getClockLatency)
+DECLARE_FORWARD(WinMMCapture, ALCbackend, void, lock)
+DECLARE_FORWARD(WinMMCapture, ALCbackend, void, unlock)
+DECLARE_DEFAULT_ALLOCATORS(WinMMCapture)
+
+DEFINE_ALCBACKEND_VTABLE(WinMMCapture);
+
+void WinMMCapture_Construct(WinMMCapture *self, ALCdevice *device)
{
- new (self) ALCwinmmCapture{device};
- SET_VTABLE2(ALCwinmmCapture, ALCbackend, self);
+ new (self) WinMMCapture{device};
+ SET_VTABLE2(WinMMCapture, ALCbackend, self);
}
-void ALCwinmmCapture_Destruct(ALCwinmmCapture *self)
+void WinMMCapture_Destruct(WinMMCapture *self)
+{ self->~WinMMCapture(); }
+
+WinMMCapture::~WinMMCapture()
{
// Close the Wave device
- if(self->mInHdl)
- waveInClose(self->mInHdl);
- self->mInHdl = nullptr;
-
- al_free(self->mWaveBuffer[0].lpData);
- std::fill(self->mWaveBuffer.begin(), self->mWaveBuffer.end(), WAVEHDR{});
+ if(mInHdl)
+ waveInClose(mInHdl);
+ mInHdl = nullptr;
- self->~ALCwinmmCapture();
+ al_free(mWaveBuffer[0].lpData);
+ std::fill(mWaveBuffer.begin(), mWaveBuffer.end(), WAVEHDR{});
}
+void CALLBACK WinMMCapture::waveInProcC(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
+{ reinterpret_cast<WinMMCapture*>(instance)->waveInProc(device, msg, param1, param2); }
-/* ALCwinmmCapture_waveInProc
+/* WinMMCapture::waveInProc
*
- * Posts a message to 'ALCwinmmCapture_captureProc' everytime a WaveIn Buffer
- * is completed and returns to the application (with more data).
+ * Posts a message to 'WinMMCapture::captureProc' everytime a WaveIn Buffer is
+ * completed and returns to the application (with more data).
*/
-void CALLBACK ALCwinmmCapture_waveInProc(HWAVEIN UNUSED(device), UINT msg,
- DWORD_PTR instance, DWORD_PTR UNUSED(param1),
- DWORD_PTR UNUSED(param2))
+void CALLBACK WinMMCapture::waveInProc(HWAVEIN UNUSED(device), UINT msg,
+ DWORD_PTR UNUSED(param1), DWORD_PTR UNUSED(param2))
{
- if(msg != WIM_DATA)
- return;
-
- auto self = reinterpret_cast<ALCwinmmCapture*>(instance);
- self->mReadable.fetch_add(1, std::memory_order_acq_rel);
- self->mSem.post();
+ if(msg != WIM_DATA) return;
+ mReadable.fetch_add(1, std::memory_order_acq_rel);
+ mSem.post();
}
-int ALCwinmmCapture_captureProc(ALCwinmmCapture *self)
+int WinMMCapture::captureProc()
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
-
althrd_setname(RECORD_THREAD_NAME);
- ALCwinmmCapture_lock(self);
- while(!self->mKillNow.load(std::memory_order_acquire) &&
- device->Connected.load(std::memory_order_acquire))
+ WinMMCapture_lock(this);
+ while(!mKillNow.load(std::memory_order_acquire) &&
+ mDevice->Connected.load(std::memory_order_acquire))
{
- ALuint todo{self->mReadable.load(std::memory_order_acquire)};
+ ALuint todo{mReadable.load(std::memory_order_acquire)};
if(todo < 1)
{
- ALCwinmmCapture_unlock(self);
- self->mSem.wait();
- ALCwinmmCapture_lock(self);
+ WinMMCapture_unlock(this);
+ mSem.wait();
+ WinMMCapture_lock(this);
continue;
}
- int widx{self->mIdx};
+ int widx{mIdx};
do {
- WAVEHDR &waveHdr = self->mWaveBuffer[widx];
- widx = (widx+1) % self->mWaveBuffer.size();
+ WAVEHDR &waveHdr = mWaveBuffer[widx];
+ widx = (widx+1) % mWaveBuffer.size();
- ring->write(waveHdr.lpData, waveHdr.dwBytesRecorded / self->mFormat.nBlockAlign);
- self->mReadable.fetch_sub(1, std::memory_order_acq_rel);
- waveInAddBuffer(self->mInHdl, &waveHdr, sizeof(WAVEHDR));
+ mRing->write(waveHdr.lpData, waveHdr.dwBytesRecorded / mFormat.nBlockAlign);
+ mReadable.fetch_sub(1, std::memory_order_acq_rel);
+ waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR));
} while(--todo);
- self->mIdx = widx;
+ mIdx = widx;
}
- ALCwinmmCapture_unlock(self);
+ WinMMCapture_unlock(this);
return 0;
}
-ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *deviceName)
+ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName)
{
ALCdevice *device{self->mDevice};
@@ -560,7 +557,7 @@ ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *deviceName)
self->mFormat.cbSize = 0;
MMRESULT res{waveInOpen(&self->mInHdl, DeviceID, &self->mFormat,
- (DWORD_PTR)&ALCwinmmCapture_waveInProc, (DWORD_PTR)self, CALLBACK_FUNCTION
+ (DWORD_PTR)&WinMMCapture::waveInProcC, (DWORD_PTR)self, CALLBACK_FUNCTION
)};
if(res != MMSYSERR_NOERROR)
{
@@ -597,7 +594,7 @@ ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *deviceName)
return ALC_NO_ERROR;
}
-ALCboolean ALCwinmmCapture_start(ALCwinmmCapture *self)
+ALCboolean WinMMCapture_start(WinMMCapture *self)
{
try {
for(size_t i{0};i < self->mWaveBuffer.size();++i)
@@ -607,7 +604,7 @@ ALCboolean ALCwinmmCapture_start(ALCwinmmCapture *self)
}
self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread(ALCwinmmCapture_captureProc, self);
+ self->mThread = std::thread{std::mem_fn(&WinMMCapture::captureProc), self};
waveInStart(self->mInHdl);
return ALC_TRUE;
@@ -620,7 +617,7 @@ ALCboolean ALCwinmmCapture_start(ALCwinmmCapture *self)
return ALC_FALSE;
}
-void ALCwinmmCapture_stop(ALCwinmmCapture *self)
+void WinMMCapture_stop(WinMMCapture *self)
{
waveInStop(self->mInHdl);
@@ -639,14 +636,14 @@ void ALCwinmmCapture_stop(ALCwinmmCapture *self)
self->mIdx = 0;
}
-ALCenum ALCwinmmCapture_captureSamples(ALCwinmmCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum WinMMCapture_captureSamples(WinMMCapture *self, ALCvoid *buffer, ALCuint samples)
{
RingBuffer *ring{self->mRing.get()};
ring->read(buffer, samples);
return ALC_NO_ERROR;
}
-ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self)
+ALCuint WinMMCapture_availableSamples(WinMMCapture *self)
{
RingBuffer *ring{self->mRing.get()};
return (ALCuint)ring->readSpace();
@@ -695,14 +692,14 @@ ALCbackend *WinMMBackendFactory::createBackend(ALCdevice *device, ALCbackend_Typ
{
if(type == ALCbackend_Playback)
{
- ALCwinmmPlayback *backend;
- NEW_OBJ(backend, ALCwinmmPlayback)(device);
+ WinMMPlayback *backend;
+ NEW_OBJ(backend, WinMMPlayback)(device);
return backend;
}
if(type == ALCbackend_Capture)
{
- ALCwinmmCapture *backend;
- NEW_OBJ(backend, ALCwinmmCapture)(device);
+ WinMMCapture *backend;
+ NEW_OBJ(backend, WinMMCapture)(device);
return backend;
}