aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends')
-rw-r--r--Alc/backends/alsa.cpp413
-rw-r--r--Alc/backends/alsa.h2
-rw-r--r--Alc/backends/base.cpp68
-rw-r--r--Alc/backends/base.h79
-rw-r--r--Alc/backends/coreaudio.cpp291
-rw-r--r--Alc/backends/coreaudio.h2
-rw-r--r--Alc/backends/dsound.cpp399
-rw-r--r--Alc/backends/dsound.h2
-rw-r--r--Alc/backends/jack.cpp199
-rw-r--r--Alc/backends/jack.h2
-rw-r--r--Alc/backends/loopback.cpp65
-rw-r--r--Alc/backends/loopback.h2
-rw-r--r--Alc/backends/null.cpp76
-rw-r--r--Alc/backends/null.h2
-rw-r--r--Alc/backends/opensl.cpp440
-rw-r--r--Alc/backends/opensl.h2
-rw-r--r--Alc/backends/oss.cpp287
-rw-r--r--Alc/backends/oss.h2
-rw-r--r--Alc/backends/portaudio.cpp285
-rw-r--r--Alc/backends/portaudio.h2
-rw-r--r--Alc/backends/pulseaudio.cpp479
-rw-r--r--Alc/backends/pulseaudio.h2
-rw-r--r--Alc/backends/qsa.cpp153
-rw-r--r--Alc/backends/qsa.h2
-rw-r--r--Alc/backends/sdl2.cpp158
-rw-r--r--Alc/backends/sdl2.h2
-rw-r--r--Alc/backends/sndio.cpp258
-rw-r--r--Alc/backends/sndio.h2
-rw-r--r--Alc/backends/solaris.cpp124
-rw-r--r--Alc/backends/solaris.h2
-rw-r--r--Alc/backends/wasapi.cpp262
-rw-r--r--Alc/backends/wasapi.h2
-rw-r--r--Alc/backends/wave.cpp164
-rw-r--r--Alc/backends/wave.h2
-rw-r--r--Alc/backends/winmm.cpp369
-rw-r--r--Alc/backends/winmm.h2
36 files changed, 1870 insertions, 2733 deletions
diff --git a/Alc/backends/alsa.cpp b/Alc/backends/alsa.cpp
index 17af2364..c5d75fe3 100644
--- a/Alc/backends/alsa.cpp
+++ b/Alc/backends/alsa.cpp
@@ -422,46 +422,32 @@ int verify_state(snd_pcm_t *handle)
}
-struct ALCplaybackAlsa final : public ALCbackend {
- ALCplaybackAlsa(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCplaybackAlsa() override;
+struct AlsaPlayback final : public BackendBase {
+ AlsaPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~AlsaPlayback() override;
int mixerProc();
int mixerNoMMapProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
+ ClockLatency getClockLatency() override;
+
snd_pcm_t *mPcmHandle{nullptr};
al::vector<char> mBuffer;
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device);
-void ALCplaybackAlsa_Destruct(ALCplaybackAlsa *self);
-ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name);
-ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self);
-ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self);
-void ALCplaybackAlsa_stop(ALCplaybackAlsa *self);
-DECLARE_FORWARD2(ALCplaybackAlsa, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, ALCuint, availableSamples)
-ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self);
-DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCplaybackAlsa)
-DEFINE_ALCBACKEND_VTABLE(ALCplaybackAlsa);
-
-
-void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device)
-{
- new (self) ALCplaybackAlsa{device};
- SET_VTABLE2(ALCplaybackAlsa, ALCbackend, self);
-}
-
-void ALCplaybackAlsa_Destruct(ALCplaybackAlsa *self)
-{ self->~ALCplaybackAlsa(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "AlsaPlayback::"; }
+ DEF_NEWDEL(AlsaPlayback)
+};
-ALCplaybackAlsa::~ALCplaybackAlsa()
+AlsaPlayback::~AlsaPlayback()
{
if(mPcmHandle)
snd_pcm_close(mPcmHandle);
@@ -469,7 +455,7 @@ ALCplaybackAlsa::~ALCplaybackAlsa()
}
-int ALCplaybackAlsa::mixerProc()
+int AlsaPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -482,9 +468,9 @@ int ALCplaybackAlsa::mixerProc()
if(state < 0)
{
ERR("Invalid state detected: %s\n", snd_strerror(state));
- ALCplaybackAlsa_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Bad state: %s", snd_strerror(state));
- ALCplaybackAlsa_unlock(this);
+ unlock();
break;
}
@@ -521,7 +507,7 @@ int ALCplaybackAlsa::mixerProc()
avail -= avail%update_size;
// it is possible that contiguous areas are smaller, thus we use a loop
- ALCplaybackAlsa_lock(this);
+ lock();
while(avail > 0)
{
snd_pcm_uframes_t frames{static_cast<snd_pcm_uframes_t>(avail)};
@@ -548,13 +534,13 @@ int ALCplaybackAlsa::mixerProc()
avail -= frames;
}
- ALCplaybackAlsa_unlock(this);
+ unlock();
}
return 0;
}
-int ALCplaybackAlsa::mixerNoMMapProc()
+int AlsaPlayback::mixerNoMMapProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -567,9 +553,9 @@ int ALCplaybackAlsa::mixerNoMMapProc()
if(state < 0)
{
ERR("Invalid state detected: %s\n", snd_strerror(state));
- ALCplaybackAlsa_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Bad state: %s", snd_strerror(state));
- ALCplaybackAlsa_unlock(this);
+ unlock();
break;
}
@@ -603,7 +589,7 @@ int ALCplaybackAlsa::mixerNoMMapProc()
continue;
}
- ALCplaybackAlsa_lock(this);
+ lock();
char *WritePtr{mBuffer.data()};
avail = snd_pcm_bytes_to_frames(mPcmHandle, mBuffer.size());
aluMixData(mDevice, WritePtr, avail);
@@ -637,14 +623,14 @@ int ALCplaybackAlsa::mixerNoMMapProc()
if(ret < 0) break;
}
}
- ALCplaybackAlsa_unlock(this);
+ unlock();
}
return 0;
}
-ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name)
+ALCenum AlsaPlayback::open(const ALCchar *name)
{
const char *driver{};
if(name)
@@ -667,7 +653,7 @@ ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name)
}
TRACE("Opening device \"%s\"\n", driver);
- int err{snd_pcm_open(&self->mPcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)};
+ int err{snd_pcm_open(&mPcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)};
if(err < 0)
{
ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(err));
@@ -677,18 +663,15 @@ ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name)
/* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */
snd_config_update_free_global();
- ALCdevice *device = self->mDevice;
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
+ALCboolean AlsaPlayback::reset()
{
- ALCdevice *device{self->mDevice};
-
snd_pcm_format_t format{SND_PCM_FORMAT_UNKNOWN};
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
format = SND_PCM_FORMAT_S8;
@@ -713,11 +696,11 @@ ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
break;
}
- bool allowmmap{!!GetConfigValueBool(device->DeviceName.c_str(), "alsa", "mmap", 1)};
- ALuint periods{device->NumUpdates};
- ALuint periodLen{static_cast<ALuint>(device->UpdateSize * U64(1000000) / device->Frequency)};
+ bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", 1)};
+ ALuint periods{mDevice->NumUpdates};
+ ALuint periodLen{static_cast<ALuint>(mDevice->UpdateSize * U64(1000000) / mDevice->Frequency)};
ALuint bufferLen{periodLen * periods};
- ALuint rate{device->Frequency};
+ ALuint rate{mDevice->Frequency};
snd_pcm_uframes_t periodSizeInFrames;
snd_pcm_sw_params_t *sp{};
@@ -727,15 +710,15 @@ ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
int dir, err;
snd_pcm_hw_params_malloc(&hp);
#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
- CHECK(snd_pcm_hw_params_any(self->mPcmHandle, hp));
+ CHECK(snd_pcm_hw_params_any(mPcmHandle, hp));
/* set interleaved access */
- if(!allowmmap || snd_pcm_hw_params_set_access(self->mPcmHandle, hp, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
+ if(!allowmmap || snd_pcm_hw_params_set_access(mPcmHandle, hp, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
{
/* No mmap */
- CHECK(snd_pcm_hw_params_set_access(self->mPcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
+ CHECK(snd_pcm_hw_params_set_access(mPcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
}
/* test and set format (implicitly sets sample bits) */
- if(snd_pcm_hw_params_test_format(self->mPcmHandle, hp, format) < 0)
+ if(snd_pcm_hw_params_test_format(mPcmHandle, hp, format) < 0)
{
static const struct {
snd_pcm_format_t format;
@@ -753,16 +736,16 @@ ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
for(const auto &fmt : formatlist)
{
format = fmt.format;
- if(snd_pcm_hw_params_test_format(self->mPcmHandle, hp, format) >= 0)
+ if(snd_pcm_hw_params_test_format(mPcmHandle, hp, format) >= 0)
{
- device->FmtType = fmt.fmttype;
+ mDevice->FmtType = fmt.fmttype;
break;
}
}
}
- CHECK(snd_pcm_hw_params_set_format(self->mPcmHandle, hp, format));
+ CHECK(snd_pcm_hw_params_set_format(mPcmHandle, hp, format));
/* test and set channels (implicitly sets frame bits) */
- if(snd_pcm_hw_params_test_channels(self->mPcmHandle, hp, device->channelsFromFmt()) < 0)
+ if(snd_pcm_hw_params_test_channels(mPcmHandle, hp, mDevice->channelsFromFmt()) < 0)
{
static const DevFmtChannels channellist[] = {
DevFmtStereo,
@@ -774,33 +757,33 @@ ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
for(const auto &chan : channellist)
{
- if(snd_pcm_hw_params_test_channels(self->mPcmHandle, hp, ChannelsFromDevFmt(chan, 0)) >= 0)
+ if(snd_pcm_hw_params_test_channels(mPcmHandle, hp, ChannelsFromDevFmt(chan, 0)) >= 0)
{
- device->FmtChans = chan;
- device->mAmbiOrder = 0;
+ mDevice->FmtChans = chan;
+ mDevice->mAmbiOrder = 0;
break;
}
}
}
- CHECK(snd_pcm_hw_params_set_channels(self->mPcmHandle, hp, device->channelsFromFmt()));
+ CHECK(snd_pcm_hw_params_set_channels(mPcmHandle, hp, mDevice->channelsFromFmt()));
/* set rate (implicitly constrains period/buffer parameters) */
- if(!GetConfigValueBool(device->DeviceName.c_str(), "alsa", "allow-resampler", 0) ||
- !(device->Flags&DEVICE_FREQUENCY_REQUEST))
+ if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "allow-resampler", 0) ||
+ !(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
{
- if(snd_pcm_hw_params_set_rate_resample(self->mPcmHandle, hp, 0) < 0)
+ if(snd_pcm_hw_params_set_rate_resample(mPcmHandle, hp, 0) < 0)
ERR("Failed to disable ALSA resampler\n");
}
- else if(snd_pcm_hw_params_set_rate_resample(self->mPcmHandle, hp, 1) < 0)
+ else if(snd_pcm_hw_params_set_rate_resample(mPcmHandle, hp, 1) < 0)
ERR("Failed to enable ALSA resampler\n");
- CHECK(snd_pcm_hw_params_set_rate_near(self->mPcmHandle, hp, &rate, nullptr));
+ CHECK(snd_pcm_hw_params_set_rate_near(mPcmHandle, hp, &rate, nullptr));
/* set buffer time (implicitly constrains period/buffer parameters) */
- if((err=snd_pcm_hw_params_set_buffer_time_near(self->mPcmHandle, hp, &bufferLen, nullptr)) < 0)
+ if((err=snd_pcm_hw_params_set_buffer_time_near(mPcmHandle, hp, &bufferLen, nullptr)) < 0)
ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
/* set period time (implicitly sets buffer size/bytes/time and period size/bytes) */
- if((err=snd_pcm_hw_params_set_period_time_near(self->mPcmHandle, hp, &periodLen, nullptr)) < 0)
+ if((err=snd_pcm_hw_params_set_period_time_near(mPcmHandle, hp, &periodLen, nullptr)) < 0)
ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
/* install and prepare hardware configuration */
- CHECK(snd_pcm_hw_params(self->mPcmHandle, hp));
+ CHECK(snd_pcm_hw_params(mPcmHandle, hp));
/* retrieve configuration info */
CHECK(snd_pcm_hw_params_get_access(hp, &access));
@@ -812,19 +795,19 @@ ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self)
hp = nullptr;
snd_pcm_sw_params_malloc(&sp);
- CHECK(snd_pcm_sw_params_current(self->mPcmHandle, sp));
- CHECK(snd_pcm_sw_params_set_avail_min(self->mPcmHandle, sp, periodSizeInFrames));
- CHECK(snd_pcm_sw_params_set_stop_threshold(self->mPcmHandle, sp, periodSizeInFrames*periods));
- CHECK(snd_pcm_sw_params(self->mPcmHandle, sp));
+ CHECK(snd_pcm_sw_params_current(mPcmHandle, sp));
+ CHECK(snd_pcm_sw_params_set_avail_min(mPcmHandle, sp, periodSizeInFrames));
+ CHECK(snd_pcm_sw_params_set_stop_threshold(mPcmHandle, sp, periodSizeInFrames*periods));
+ CHECK(snd_pcm_sw_params(mPcmHandle, sp));
#undef CHECK
snd_pcm_sw_params_free(sp);
sp = nullptr;
- device->NumUpdates = periods;
- device->UpdateSize = periodSizeInFrames;
- device->Frequency = rate;
+ mDevice->NumUpdates = periods;
+ mDevice->UpdateSize = periodSizeInFrames;
+ mDevice->Frequency = rate;
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
return ALC_TRUE;
@@ -835,9 +818,8 @@ error:
return ALC_FALSE;
}
-ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self)
+ALCboolean AlsaPlayback::start()
{
- ALCdevice *device{self->mDevice};
snd_pcm_hw_params_t *hp{};
snd_pcm_access_t access;
const char *funcerr;
@@ -845,7 +827,7 @@ ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self)
snd_pcm_hw_params_malloc(&hp);
#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
- CHECK(snd_pcm_hw_params_current(self->mPcmHandle, hp));
+ CHECK(snd_pcm_hw_params_current(mPcmHandle, hp));
/* retrieve configuration info */
CHECK(snd_pcm_hw_params_get_access(hp, &access));
#undef CHECK
@@ -859,26 +841,26 @@ ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self)
snd_pcm_hw_params_free(hp);
hp = nullptr;
- int (ALCplaybackAlsa::*thread_func)(){};
+ int (AlsaPlayback::*thread_func)(){};
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
{
- self->mBuffer.resize(snd_pcm_frames_to_bytes(self->mPcmHandle, device->UpdateSize));
- thread_func = &ALCplaybackAlsa::mixerNoMMapProc;
+ mBuffer.resize(snd_pcm_frames_to_bytes(mPcmHandle, mDevice->UpdateSize));
+ thread_func = &AlsaPlayback::mixerNoMMapProc;
}
else
{
- err = snd_pcm_prepare(self->mPcmHandle);
+ err = snd_pcm_prepare(mPcmHandle);
if(err < 0)
{
ERR("snd_pcm_prepare(data->mPcmHandle) failed: %s\n", snd_strerror(err));
return ALC_FALSE;
}
- thread_func = &ALCplaybackAlsa::mixerProc;
+ thread_func = &AlsaPlayback::mixerProc;
}
try {
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(thread_func), self};
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(thread_func), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -886,45 +868,50 @@ ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self)
}
catch(...) {
}
- self->mBuffer.clear();
+ mBuffer.clear();
return ALC_FALSE;
}
-void ALCplaybackAlsa_stop(ALCplaybackAlsa *self)
+void AlsaPlayback::stop()
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !mThread.joinable())
return;
+ mThread.join();
- self->mThread.join();
-
- self->mBuffer.clear();
+ mBuffer.clear();
}
-ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self)
+ClockLatency AlsaPlayback::getClockLatency()
{
- ALCdevice *device{self->mDevice};
ClockLatency ret;
- ALCplaybackAlsa_lock(self);
- ret.ClockTime = GetDeviceClockTime(device);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
snd_pcm_sframes_t delay{};
- int err{snd_pcm_delay(self->mPcmHandle, &delay)};
+ int err{snd_pcm_delay(mPcmHandle, &delay)};
if(err < 0)
{
ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
delay = 0;
}
ret.Latency = std::chrono::seconds{std::max<snd_pcm_sframes_t>(0, delay)};
- ret.Latency /= device->Frequency;
- ALCplaybackAlsa_unlock(self);
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
-struct ALCcaptureAlsa final : public ALCbackend {
- ALCcaptureAlsa(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCcaptureAlsa() override;
+struct AlsaCapture final : public BackendBase {
+ AlsaCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~AlsaCapture() override;
+
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(ALCvoid *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+ ClockLatency getClockLatency() override;
snd_pcm_t *mPcmHandle{nullptr};
@@ -934,34 +921,12 @@ struct ALCcaptureAlsa final : public ALCbackend {
RingBufferPtr mRing{nullptr};
snd_pcm_sframes_t mLastAvail{0};
-};
-
-void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device);
-void ALCcaptureAlsa_Destruct(ALCcaptureAlsa *self);
-ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name);
-DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, ALCboolean, reset)
-ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self);
-void ALCcaptureAlsa_stop(ALCcaptureAlsa *self);
-ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples);
-ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self);
-ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self);
-DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCcaptureAlsa)
-
-DEFINE_ALCBACKEND_VTABLE(ALCcaptureAlsa);
-
-void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device)
-{
- new (self) ALCcaptureAlsa{device};
- SET_VTABLE2(ALCcaptureAlsa, ALCbackend, self);
-}
-
-void ALCcaptureAlsa_Destruct(ALCcaptureAlsa *self)
-{ self->~ALCcaptureAlsa(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "AlsaCapture::"; }
+ DEF_NEWDEL(AlsaCapture)
+};
-ALCcaptureAlsa::~ALCcaptureAlsa()
+AlsaCapture::~AlsaCapture()
{
if(mPcmHandle)
snd_pcm_close(mPcmHandle);
@@ -969,9 +934,8 @@ ALCcaptureAlsa::~ALCcaptureAlsa()
}
-ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
+ALCenum AlsaCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
const char *driver{};
if(name)
{
@@ -993,7 +957,7 @@ ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
}
TRACE("Opening device \"%s\"\n", driver);
- int err{snd_pcm_open(&self->mPcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)};
+ int err{snd_pcm_open(&mPcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)};
if(err < 0)
{
ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(err));
@@ -1004,7 +968,7 @@ ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
snd_config_update_free_global();
snd_pcm_format_t format{SND_PCM_FORMAT_UNKNOWN};
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
format = SND_PCM_FORMAT_S8;
@@ -1029,35 +993,35 @@ ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
break;
}
- snd_pcm_uframes_t bufferSizeInFrames{maxu(device->UpdateSize*device->NumUpdates,
- 100*device->Frequency/1000)};
- snd_pcm_uframes_t periodSizeInFrames{minu(bufferSizeInFrames, 25*device->Frequency/1000)};
+ snd_pcm_uframes_t bufferSizeInFrames{maxu(mDevice->UpdateSize*mDevice->NumUpdates,
+ 100*mDevice->Frequency/1000)};
+ snd_pcm_uframes_t periodSizeInFrames{minu(bufferSizeInFrames, 25*mDevice->Frequency/1000)};
bool needring{false};
const char *funcerr{};
snd_pcm_hw_params_t *hp{};
snd_pcm_hw_params_malloc(&hp);
#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
- CHECK(snd_pcm_hw_params_any(self->mPcmHandle, hp));
+ CHECK(snd_pcm_hw_params_any(mPcmHandle, hp));
/* set interleaved access */
- CHECK(snd_pcm_hw_params_set_access(self->mPcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
+ CHECK(snd_pcm_hw_params_set_access(mPcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
/* set format (implicitly sets sample bits) */
- CHECK(snd_pcm_hw_params_set_format(self->mPcmHandle, hp, format));
+ CHECK(snd_pcm_hw_params_set_format(mPcmHandle, hp, format));
/* set channels (implicitly sets frame bits) */
- CHECK(snd_pcm_hw_params_set_channels(self->mPcmHandle, hp, device->channelsFromFmt()));
+ CHECK(snd_pcm_hw_params_set_channels(mPcmHandle, hp, mDevice->channelsFromFmt()));
/* set rate (implicitly constrains period/buffer parameters) */
- CHECK(snd_pcm_hw_params_set_rate(self->mPcmHandle, hp, device->Frequency, 0));
+ CHECK(snd_pcm_hw_params_set_rate(mPcmHandle, hp, mDevice->Frequency, 0));
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
- if(snd_pcm_hw_params_set_buffer_size_min(self->mPcmHandle, hp, &bufferSizeInFrames) < 0)
+ if(snd_pcm_hw_params_set_buffer_size_min(mPcmHandle, hp, &bufferSizeInFrames) < 0)
{
TRACE("Buffer too large, using intermediate ring buffer\n");
needring = true;
- CHECK(snd_pcm_hw_params_set_buffer_size_near(self->mPcmHandle, hp, &bufferSizeInFrames));
+ CHECK(snd_pcm_hw_params_set_buffer_size_near(mPcmHandle, hp, &bufferSizeInFrames));
}
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
- CHECK(snd_pcm_hw_params_set_period_size_near(self->mPcmHandle, hp, &periodSizeInFrames, nullptr));
+ CHECK(snd_pcm_hw_params_set_period_size_near(mPcmHandle, hp, &periodSizeInFrames, nullptr));
/* install and prepare hardware configuration */
- CHECK(snd_pcm_hw_params(self->mPcmHandle, hp));
+ CHECK(snd_pcm_hw_params(mPcmHandle, hp));
/* retrieve configuration info */
CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, nullptr));
#undef CHECK
@@ -1066,16 +1030,16 @@ ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
if(needring)
{
- self->mRing = CreateRingBuffer(device->UpdateSize*device->NumUpdates,
- device->frameSizeFromFmt(), false);
- if(!self->mRing)
+ mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates,
+ mDevice->frameSizeFromFmt(), false);
+ if(!mRing)
{
ERR("ring buffer create failed\n");
goto error2;
}
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
@@ -1084,99 +1048,99 @@ error:
if(hp) snd_pcm_hw_params_free(hp);
error2:
- self->mRing = nullptr;
- snd_pcm_close(self->mPcmHandle);
- self->mPcmHandle = nullptr;
+ mRing = nullptr;
+ snd_pcm_close(mPcmHandle);
+ mPcmHandle = nullptr;
return ALC_INVALID_VALUE;
}
-ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self)
+
+ALCboolean AlsaCapture::start()
{
- int err{snd_pcm_prepare(self->mPcmHandle)};
+ int err{snd_pcm_prepare(mPcmHandle)};
if(err < 0)
ERR("prepare failed: %s\n", snd_strerror(err));
else
{
- err = snd_pcm_start(self->mPcmHandle);
+ err = snd_pcm_start(mPcmHandle);
if(err < 0)
ERR("start failed: %s\n", snd_strerror(err));
}
if(err < 0)
{
- aluHandleDisconnect(self->mDevice, "Capture state failure: %s", snd_strerror(err));
+ aluHandleDisconnect(mDevice, "Capture state failure: %s", snd_strerror(err));
return ALC_FALSE;
}
- self->mDoCapture = true;
+ mDoCapture = true;
return ALC_TRUE;
}
-void ALCcaptureAlsa_stop(ALCcaptureAlsa *self)
+void AlsaCapture::stop()
{
/* OpenAL requires access to unread audio after stopping, but ALSA's
* snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's
- * available now so it'll be available later after the drop. */
- ALCuint avail{ALCcaptureAlsa_availableSamples(self)};
- if(!self->mRing && avail > 0)
+ * available now so it'll be available later after the drop.
+ */
+ ALCuint avail{availableSamples()};
+ if(!mRing && avail > 0)
{
/* The ring buffer implicitly captures when checking availability.
* Direct access needs to explicitly capture it into temp storage. */
- al::vector<char> temp(snd_pcm_frames_to_bytes(self->mPcmHandle, avail));
- ALCcaptureAlsa_captureSamples(self, temp.data(), avail);
- self->mBuffer = std::move(temp);
+ al::vector<char> temp(snd_pcm_frames_to_bytes(mPcmHandle, avail));
+ captureSamples(temp.data(), avail);
+ mBuffer = std::move(temp);
}
- int err{snd_pcm_drop(self->mPcmHandle)};
+ int err{snd_pcm_drop(mPcmHandle)};
if(err < 0)
ERR("drop failed: %s\n", snd_strerror(err));
- self->mDoCapture = false;
+ mDoCapture = false;
}
-ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples)
+ALCenum AlsaCapture::captureSamples(ALCvoid *buffer, ALCuint samples)
{
- ALCdevice *device{self->mDevice};
-
- if(RingBuffer *ring{self->mRing.get()})
+ if(mRing)
{
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
- self->mLastAvail -= samples;
- while(device->Connected.load(std::memory_order_acquire) && samples > 0)
+ mLastAvail -= samples;
+ while(mDevice->Connected.load(std::memory_order_acquire) && samples > 0)
{
snd_pcm_sframes_t amt{0};
- if(!self->mBuffer.empty())
+ if(!mBuffer.empty())
{
/* First get any data stored from the last stop */
- amt = snd_pcm_bytes_to_frames(self->mPcmHandle, self->mBuffer.size());
+ amt = snd_pcm_bytes_to_frames(mPcmHandle, mBuffer.size());
if((snd_pcm_uframes_t)amt > samples) amt = samples;
- amt = snd_pcm_frames_to_bytes(self->mPcmHandle, amt);
- memcpy(buffer, self->mBuffer.data(), amt);
+ amt = snd_pcm_frames_to_bytes(mPcmHandle, amt);
+ memcpy(buffer, mBuffer.data(), amt);
- self->mBuffer.erase(self->mBuffer.begin(), self->mBuffer.begin()+amt);
- amt = snd_pcm_bytes_to_frames(self->mPcmHandle, amt);
+ mBuffer.erase(mBuffer.begin(), mBuffer.begin()+amt);
+ amt = snd_pcm_bytes_to_frames(mPcmHandle, amt);
}
- else if(self->mDoCapture)
- amt = snd_pcm_readi(self->mPcmHandle, buffer, samples);
+ else if(mDoCapture)
+ amt = snd_pcm_readi(mPcmHandle, buffer, samples);
if(amt < 0)
{
ERR("read error: %s\n", snd_strerror(amt));
if(amt == -EAGAIN)
continue;
- if((amt=snd_pcm_recover(self->mPcmHandle, amt, 1)) >= 0)
+ if((amt=snd_pcm_recover(mPcmHandle, amt, 1)) >= 0)
{
- amt = snd_pcm_start(self->mPcmHandle);
+ amt = snd_pcm_start(mPcmHandle);
if(amt >= 0)
- amt = snd_pcm_avail_update(self->mPcmHandle);
+ amt = snd_pcm_avail_update(mPcmHandle);
}
if(amt < 0)
{
ERR("restore error: %s\n", snd_strerror(amt));
- aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
+ aluHandleDisconnect(mDevice, "Capture recovery failure: %s", snd_strerror(amt));
break;
}
/* If the amount available is less than what's asked, we lost it
@@ -1190,100 +1154,96 @@ ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALC
samples -= amt;
}
if(samples > 0)
- memset(buffer, ((device->FmtType == DevFmtUByte) ? 0x80 : 0),
- snd_pcm_frames_to_bytes(self->mPcmHandle, samples));
+ memset(buffer, ((mDevice->FmtType == DevFmtUByte) ? 0x80 : 0),
+ snd_pcm_frames_to_bytes(mPcmHandle, samples));
return ALC_NO_ERROR;
}
-ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
+ALCuint AlsaCapture::availableSamples()
{
- ALCdevice *device{self->mDevice};
-
snd_pcm_sframes_t avail{0};
- if(device->Connected.load(std::memory_order_acquire) && self->mDoCapture)
- avail = snd_pcm_avail_update(self->mPcmHandle);
+ if(mDevice->Connected.load(std::memory_order_acquire) && mDoCapture)
+ avail = snd_pcm_avail_update(mPcmHandle);
if(avail < 0)
{
ERR("avail update failed: %s\n", snd_strerror(avail));
- if((avail=snd_pcm_recover(self->mPcmHandle, avail, 1)) >= 0)
+ if((avail=snd_pcm_recover(mPcmHandle, avail, 1)) >= 0)
{
- if(self->mDoCapture)
- avail = snd_pcm_start(self->mPcmHandle);
+ if(mDoCapture)
+ avail = snd_pcm_start(mPcmHandle);
if(avail >= 0)
- avail = snd_pcm_avail_update(self->mPcmHandle);
+ avail = snd_pcm_avail_update(mPcmHandle);
}
if(avail < 0)
{
ERR("restore error: %s\n", snd_strerror(avail));
- aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(avail));
+ aluHandleDisconnect(mDevice, "Capture recovery failure: %s", snd_strerror(avail));
}
}
- RingBuffer *ring{self->mRing.get()};
- if(!ring)
+ if(!mRing)
{
if(avail < 0) avail = 0;
- avail += snd_pcm_bytes_to_frames(self->mPcmHandle, self->mBuffer.size());
- if(avail > self->mLastAvail) self->mLastAvail = avail;
- return self->mLastAvail;
+ avail += snd_pcm_bytes_to_frames(mPcmHandle, mBuffer.size());
+ if(avail > mLastAvail) mLastAvail = avail;
+ return mLastAvail;
}
while(avail > 0)
{
- auto vec = ring->getWriteVector();
+ auto vec = mRing->getWriteVector();
if(vec.first.len == 0) break;
snd_pcm_sframes_t amt{std::min<snd_pcm_sframes_t>(vec.first.len, avail)};
- amt = snd_pcm_readi(self->mPcmHandle, vec.first.buf, amt);
+ amt = snd_pcm_readi(mPcmHandle, vec.first.buf, amt);
if(amt < 0)
{
ERR("read error: %s\n", snd_strerror(amt));
if(amt == -EAGAIN)
continue;
- if((amt=snd_pcm_recover(self->mPcmHandle, amt, 1)) >= 0)
+ if((amt=snd_pcm_recover(mPcmHandle, amt, 1)) >= 0)
{
- if(self->mDoCapture)
- amt = snd_pcm_start(self->mPcmHandle);
+ if(mDoCapture)
+ amt = snd_pcm_start(mPcmHandle);
if(amt >= 0)
- amt = snd_pcm_avail_update(self->mPcmHandle);
+ amt = snd_pcm_avail_update(mPcmHandle);
}
if(amt < 0)
{
ERR("restore error: %s\n", snd_strerror(amt));
- aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt));
+ aluHandleDisconnect(mDevice, "Capture recovery failure: %s", snd_strerror(amt));
break;
}
avail = amt;
continue;
}
- ring->writeAdvance(amt);
+ mRing->writeAdvance(amt);
avail -= amt;
}
- return ring->readSpace();
+ return mRing->readSpace();
}
-ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
+ClockLatency AlsaCapture::getClockLatency()
{
- ALCdevice *device{self->mDevice};
ClockLatency ret;
- ALCcaptureAlsa_lock(self);
- ret.ClockTime = GetDeviceClockTime(device);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
snd_pcm_sframes_t delay{};
- int err{snd_pcm_delay(self->mPcmHandle, &delay)};
+ int err{snd_pcm_delay(mPcmHandle, &delay)};
if(err < 0)
{
ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
delay = 0;
}
ret.Latency = std::chrono::seconds{std::max<snd_pcm_sframes_t>(0, delay)};
- ret.Latency /= device->Frequency;
- ALCcaptureAlsa_unlock(self);
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
@@ -1332,21 +1292,12 @@ void AlsaBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *AlsaBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *AlsaBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCplaybackAlsa *backend;
- NEW_OBJ(backend, ALCplaybackAlsa)(device);
- return backend;
- }
+ return new AlsaPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCcaptureAlsa *backend;
- NEW_OBJ(backend, ALCcaptureAlsa)(device);
- return backend;
- }
-
+ return new AlsaCapture{device};
return nullptr;
}
diff --git a/Alc/backends/alsa.h b/Alc/backends/alsa.h
index 8ee78f56..e9169c48 100644
--- a/Alc/backends/alsa.h
+++ b/Alc/backends/alsa.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/base.cpp b/Alc/backends/base.cpp
index 021a0f17..1fef0439 100644
--- a/Alc/backends/base.cpp
+++ b/Alc/backends/base.cpp
@@ -12,80 +12,60 @@
void ALCdevice_Lock(ALCdevice *device)
-{ V0(device->Backend,lock)(); }
+{ device->Backend->lock(); }
void ALCdevice_Unlock(ALCdevice *device)
-{ V0(device->Backend,unlock)(); }
+{ device->Backend->unlock(); }
ClockLatency GetClockLatency(ALCdevice *device)
{
- ClockLatency ret = V0(device->Backend,getClockLatency)();
+ BackendBase *backend{device->Backend};
+ ClockLatency ret{backend->getClockLatency()};
ret.Latency += device->FixedLatency;
return ret;
}
-/* Base ALCbackend method implementations. */
-ALCbackend::ALCbackend(ALCdevice *device) noexcept : mDevice{device}
+/* BackendBase method implementations. */
+BackendBase::BackendBase(ALCdevice *device) noexcept : mDevice{device}
{ }
-ALCbackend::~ALCbackend()
+BackendBase::~BackendBase()
{ }
-ALCboolean ALCbackend_reset(ALCbackend* UNUSED(self))
-{
- return ALC_FALSE;
-}
+ALCboolean BackendBase::reset()
+{ return ALC_FALSE; }
-ALCenum ALCbackend_captureSamples(ALCbackend* UNUSED(self), void* UNUSED(buffer), ALCuint UNUSED(samples))
-{
- return ALC_INVALID_DEVICE;
-}
+ALCenum BackendBase::captureSamples(void* UNUSED(buffer), ALCuint UNUSED(samples))
+{ return ALC_INVALID_DEVICE; }
-ALCuint ALCbackend_availableSamples(ALCbackend* UNUSED(self))
-{
- return 0;
-}
+ALCuint BackendBase::availableSamples()
+{ return 0; }
-ClockLatency ALCbackend_getClockLatency(ALCbackend *self)
+ClockLatency BackendBase::getClockLatency()
{
- ALCdevice *device = self->mDevice;
- ALuint refcount;
ClockLatency ret;
+ ALuint refcount;
do {
- while(((refcount=device->MixCount.load(std::memory_order_acquire))&1))
+ while(((refcount=mDevice->MixCount.load(std::memory_order_acquire))&1))
std::this_thread::yield();
- ret.ClockTime = GetDeviceClockTime(device);
+ ret.ClockTime = GetDeviceClockTime(mDevice);
std::atomic_thread_fence(std::memory_order_acquire);
- } while(refcount != device->MixCount.load(std::memory_order_relaxed));
+ } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
/* NOTE: The device will generally have about all but one periods filled at
* any given time during playback. Without a more accurate measurement from
* the output, this is an okay approximation.
*/
- ret.Latency = std::chrono::seconds{device->UpdateSize*maxi(device->NumUpdates-1, 0)};
- ret.Latency /= device->Frequency;
+ ret.Latency = std::chrono::seconds{mDevice->UpdateSize*maxi(mDevice->NumUpdates-1, 0)};
+ ret.Latency /= mDevice->Frequency;
return ret;
}
-void ALCbackend_lock(ALCbackend *self)
-{
- try {
- self->mMutex.lock();
- }
- catch(...) {
- std::terminate();
- }
-}
+void BackendBase::lock() noexcept
+{ mMutex.lock(); }
-void ALCbackend_unlock(ALCbackend *self)
-{
- try {
- self->mMutex.unlock();
- }
- catch(...) {
- std::terminate();
- }
-}
+void BackendBase::unlock() noexcept
+{ mMutex.unlock(); }
diff --git a/Alc/backends/base.h b/Alc/backends/base.h
index 4380540f..b9ea3b61 100644
--- a/Alc/backends/base.h
+++ b/Alc/backends/base.h
@@ -6,7 +6,6 @@
#include <mutex>
#include "alMain.h"
-#include "polymorphism.h"
struct ClockLatency {
@@ -32,77 +31,29 @@ void ALCdevice_Unlock(ALCdevice *device);
ClockLatency GetClockLatency(ALCdevice *device);
+struct BackendBase {
+ virtual ALCenum open(const ALCchar *name) = 0;
-struct ALCbackendVtable;
+ virtual ALCboolean reset();
+ virtual ALCboolean start() = 0;
+ virtual void stop() = 0;
-struct ALCbackend {
- const ALCbackendVtable *vtbl;
+ virtual ALCenum captureSamples(void *buffer, ALCuint samples);
+ virtual ALCuint availableSamples();
- ALCdevice *mDevice;
-
- std::recursive_mutex mMutex;
-
- ALCbackend(ALCdevice *device) noexcept;
- virtual ~ALCbackend();
-};
-
-ALCboolean ALCbackend_reset(ALCbackend *self);
-ALCenum ALCbackend_captureSamples(ALCbackend *self, void *buffer, ALCuint samples);
-ALCuint ALCbackend_availableSamples(ALCbackend *self);
-ClockLatency ALCbackend_getClockLatency(ALCbackend *self);
-void ALCbackend_lock(ALCbackend *self);
-void ALCbackend_unlock(ALCbackend *self);
-
-struct ALCbackendVtable {
- void (*const Destruct)(ALCbackend*);
+ virtual ClockLatency getClockLatency();
- ALCenum (*const open)(ALCbackend*, const ALCchar*);
+ virtual void lock() noexcept;
+ virtual void unlock() noexcept;
- ALCboolean (*const reset)(ALCbackend*);
- ALCboolean (*const start)(ALCbackend*);
- void (*const stop)(ALCbackend*);
-
- ALCenum (*const captureSamples)(ALCbackend*, void*, ALCuint);
- ALCuint (*const availableSamples)(ALCbackend*);
-
- ClockLatency (*const getClockLatency)(ALCbackend*);
+ ALCdevice *mDevice;
- void (*const lock)(ALCbackend*);
- void (*const unlock)(ALCbackend*);
+ std::recursive_mutex mMutex;
- void (*const Delete)(void*);
+ BackendBase(ALCdevice *device) noexcept;
+ virtual ~BackendBase();
};
-#define DEFINE_ALCBACKEND_VTABLE(T) \
-DECLARE_THUNK(T, ALCbackend, void, Destruct) \
-DECLARE_THUNK1(T, ALCbackend, ALCenum, open, const ALCchar*) \
-DECLARE_THUNK(T, ALCbackend, ALCboolean, reset) \
-DECLARE_THUNK(T, ALCbackend, ALCboolean, start) \
-DECLARE_THUNK(T, ALCbackend, void, stop) \
-DECLARE_THUNK2(T, ALCbackend, ALCenum, captureSamples, void*, ALCuint) \
-DECLARE_THUNK(T, ALCbackend, ALCuint, availableSamples) \
-DECLARE_THUNK(T, ALCbackend, ClockLatency, getClockLatency) \
-DECLARE_THUNK(T, ALCbackend, void, lock) \
-DECLARE_THUNK(T, ALCbackend, void, unlock) \
-static void T##_ALCbackend_Delete(void *ptr) \
-{ T##_Delete(static_cast<T*>(static_cast<ALCbackend*>(ptr))); } \
- \
-static const ALCbackendVtable T##_ALCbackend_vtable = { \
- T##_ALCbackend_Destruct, \
- \
- T##_ALCbackend_open, \
- T##_ALCbackend_reset, \
- T##_ALCbackend_start, \
- T##_ALCbackend_stop, \
- T##_ALCbackend_captureSamples, \
- T##_ALCbackend_availableSamples, \
- T##_ALCbackend_getClockLatency, \
- T##_ALCbackend_lock, \
- T##_ALCbackend_unlock, \
- \
- T##_ALCbackend_Delete, \
-}
-
enum ALCbackend_Type {
ALCbackend_Playback,
@@ -119,7 +70,7 @@ struct BackendFactory {
virtual void probe(DevProbe type, std::string *outnames) = 0;
- virtual ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) = 0;
+ virtual BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) = 0;
};
#endif /* ALC_BACKENDS_BASE_H */
diff --git a/Alc/backends/coreaudio.cpp b/Alc/backends/coreaudio.cpp
index 82312d67..3f1f48d8 100644
--- a/Alc/backends/coreaudio.cpp
+++ b/Alc/backends/coreaudio.cpp
@@ -30,6 +30,7 @@
#include "alu.h"
#include "ringbuffer.h"
#include "converter.h"
+#include "backends/base.h"
#include <unistd.h>
#include <AudioUnit/AudioUnit.h>
@@ -41,9 +42,9 @@ namespace {
static const ALCchar ca_device[] = "CoreAudio Default";
-struct ALCcoreAudioPlayback final : public ALCbackend {
- ALCcoreAudioPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCcoreAudioPlayback() override;
+struct CoreAudioPlayback final : public BackendBase {
+ CoreAudioPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~CoreAudioPlayback() override;
static OSStatus MixerProcC(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
@@ -52,64 +53,47 @@ struct ALCcoreAudioPlayback final : public ALCbackend {
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
AudioUnit mAudioUnit;
ALuint mFrameSize{0u};
AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
-};
-
-static void ALCcoreAudioPlayback_Construct(ALCcoreAudioPlayback *self, ALCdevice *device);
-static void ALCcoreAudioPlayback_Destruct(ALCcoreAudioPlayback *self);
-static ALCenum ALCcoreAudioPlayback_open(ALCcoreAudioPlayback *self, const ALCchar *name);
-static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self);
-static ALCboolean ALCcoreAudioPlayback_start(ALCcoreAudioPlayback *self);
-static void ALCcoreAudioPlayback_stop(ALCcoreAudioPlayback *self);
-static DECLARE_FORWARD2(ALCcoreAudioPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-static DECLARE_FORWARD(ALCcoreAudioPlayback, ALCbackend, ALCuint, availableSamples)
-static DECLARE_FORWARD(ALCcoreAudioPlayback, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(ALCcoreAudioPlayback, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCcoreAudioPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCcoreAudioPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(ALCcoreAudioPlayback);
-
-
-static void ALCcoreAudioPlayback_Construct(ALCcoreAudioPlayback *self, ALCdevice *device)
-{
- new (self) ALCcoreAudioPlayback{device};
- SET_VTABLE2(ALCcoreAudioPlayback, ALCbackend, self);
-}
-static void ALCcoreAudioPlayback_Destruct(ALCcoreAudioPlayback *self)
-{ self->~ALCcoreAudioPlayback(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "CoreAudioPlayback::"; }
+ DEF_NEWDEL(CoreAudioPlayback)
+};
-ALCcoreAudioPlayback::~ALCcoreAudioPlayback()
+CoreAudioPlayback::~CoreAudioPlayback()
{
AudioUnitUninitialize(mAudioUnit);
AudioComponentInstanceDispose(mAudioUnit);
}
-OSStatus ALCcoreAudioPlayback::MixerProcC(void *inRefCon,
+OSStatus CoreAudioPlayback::MixerProcC(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
- return static_cast<ALCcoreAudioPlayback*>(inRefCon)->MixerProc(ioActionFlags, inTimeStamp,
+ return static_cast<CoreAudioPlayback*>(inRefCon)->MixerProc(ioActionFlags, inTimeStamp,
inBusNumber, inNumberFrames, ioData);
}
-OSStatus ALCcoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags* UNUSED(ioActionFlags),
+OSStatus CoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags* UNUSED(ioActionFlags),
const AudioTimeStamp* UNUSED(inTimeStamp), UInt32 UNUSED(inBusNumber),
UInt32 UNUSED(inNumberFrames), AudioBufferList *ioData)
{
- ALCcoreAudioPlayback_lock(this);
+ lock();
aluMixData(mDevice, ioData->mBuffers[0].mData, ioData->mBuffers[0].mDataByteSize/mFrameSize);
- ALCcoreAudioPlayback_unlock(this);
+ unlock();
return noErr;
}
-static ALCenum ALCcoreAudioPlayback_open(ALCcoreAudioPlayback *self, const ALCchar *name)
+ALCenum CoreAudioPlayback::open(const ALCchar *name)
{
if(!name)
name = ca_device;
@@ -135,7 +119,7 @@ static ALCenum ALCcoreAudioPlayback_open(ALCcoreAudioPlayback *self, const ALCch
return ALC_INVALID_VALUE;
}
- OSStatus err{AudioComponentInstanceNew(comp, &self->mAudioUnit)};
+ OSStatus err{AudioComponentInstanceNew(comp, &mAudioUnit)};
if(err != noErr)
{
ERR("AudioComponentInstanceNew failed\n");
@@ -143,32 +127,29 @@ static ALCenum ALCcoreAudioPlayback_open(ALCcoreAudioPlayback *self, const ALCch
}
/* init and start the default audio unit... */
- err = AudioUnitInitialize(self->mAudioUnit);
+ err = AudioUnitInitialize(mAudioUnit);
if(err != noErr)
{
ERR("AudioUnitInitialize failed\n");
- AudioComponentInstanceDispose(self->mAudioUnit);
+ AudioComponentInstanceDispose(mAudioUnit);
return ALC_INVALID_VALUE;
}
- ALCdevice *device{self->mDevice};
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
+ALCboolean CoreAudioPlayback::reset()
{
- ALCdevice *device{self->mDevice};
-
- OSStatus err{AudioUnitUninitialize(self->mAudioUnit)};
+ OSStatus err{AudioUnitUninitialize(mAudioUnit)};
if(err != noErr)
ERR("-- AudioUnitUninitialize failed.\n");
/* retrieve default output unit's properties (output side) */
AudioStreamBasicDescription streamFormat{};
auto size = static_cast<UInt32>(sizeof(AudioStreamBasicDescription));
- err = AudioUnitGetProperty(self->mAudioUnit, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output, 0, &streamFormat, &size);
+ err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output,
+ 0, &streamFormat, &size);
if(err != noErr || size != sizeof(AudioStreamBasicDescription))
{
ERR("AudioUnitGetProperty failed\n");
@@ -186,19 +167,19 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
#endif
/* set default output unit's input side to match output side */
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input, 0, &streamFormat, size);
+ err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
+ 0, &streamFormat, size);
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
return ALC_FALSE;
}
- if(device->Frequency != streamFormat.mSampleRate)
+ if(mDevice->Frequency != streamFormat.mSampleRate)
{
- device->NumUpdates = static_cast<ALuint>(
- (ALuint64)device->NumUpdates*streamFormat.mSampleRate/device->Frequency);
- device->Frequency = streamFormat.mSampleRate;
+ mDevice->NumUpdates = static_cast<ALuint>(
+ (ALuint64)mDevice->NumUpdates*streamFormat.mSampleRate/mDevice->Frequency);
+ mDevice->Frequency = streamFormat.mSampleRate;
}
/* FIXME: How to tell what channels are what in the output device, and how
@@ -206,53 +187,53 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
switch(streamFormat.mChannelsPerFrame)
{
case 1:
- device->FmtChans = DevFmtMono;
+ mDevice->FmtChans = DevFmtMono;
break;
case 2:
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
break;
case 4:
- device->FmtChans = DevFmtQuad;
+ mDevice->FmtChans = DevFmtQuad;
break;
case 6:
- device->FmtChans = DevFmtX51;
+ mDevice->FmtChans = DevFmtX51;
break;
case 7:
- device->FmtChans = DevFmtX61;
+ mDevice->FmtChans = DevFmtX61;
break;
case 8:
- device->FmtChans = DevFmtX71;
+ mDevice->FmtChans = DevFmtX71;
break;
default:
ERR("Unhandled channel count (%d), using Stereo\n", streamFormat.mChannelsPerFrame);
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
streamFormat.mChannelsPerFrame = 2;
break;
}
- SetDefaultWFXChannelOrder(device);
+ SetDefaultWFXChannelOrder(mDevice);
/* use channel count and sample rate from the default output unit's current
* parameters, but reset everything else */
streamFormat.mFramesPerPacket = 1;
streamFormat.mFormatFlags = 0;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtUByte:
- device->FmtType = DevFmtByte;
+ mDevice->FmtType = DevFmtByte;
/* fall-through */
case DevFmtByte:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
streamFormat.mBitsPerChannel = 8;
break;
case DevFmtUShort:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
streamFormat.mBitsPerChannel = 16;
break;
case DevFmtUInt:
- device->FmtType = DevFmtInt;
+ mDevice->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
@@ -270,8 +251,8 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
streamFormat.mFormatFlags |= kAudioFormatFlagsNativeEndian |
kLinearPCMFormatFlagIsPacked;
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input, 0, &streamFormat, sizeof(AudioStreamBasicDescription));
+ err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
+ 0, &streamFormat, sizeof(AudioStreamBasicDescription));
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
@@ -279,12 +260,12 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
}
/* setup callback */
- self->mFrameSize = device->frameSizeFromFmt();
+ mFrameSize = mDevice->frameSizeFromFmt();
AURenderCallbackStruct input{};
- input.inputProc = ALCcoreAudioPlayback::MixerProcC;
- input.inputProcRefCon = self;
+ input.inputProc = CoreAudioPlayback::MixerProcC;
+ input.inputProcRefCon = this;
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioUnitProperty_SetRenderCallback,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &input, sizeof(AURenderCallbackStruct));
if(err != noErr)
{
@@ -293,7 +274,7 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
}
/* init the default audio unit... */
- err = AudioUnitInitialize(self->mAudioUnit);
+ err = AudioUnitInitialize(mAudioUnit);
if(err != noErr)
{
ERR("AudioUnitInitialize failed\n");
@@ -303,9 +284,9 @@ static ALCboolean ALCcoreAudioPlayback_reset(ALCcoreAudioPlayback *self)
return ALC_TRUE;
}
-static ALCboolean ALCcoreAudioPlayback_start(ALCcoreAudioPlayback *self)
+ALCboolean CoreAudioPlayback::start()
{
- OSStatus err{AudioOutputUnitStart(self->mAudioUnit)};
+ OSStatus err{AudioOutputUnitStart(mAudioUnit)};
if(err != noErr)
{
ERR("AudioOutputUnitStart failed\n");
@@ -314,17 +295,17 @@ static ALCboolean ALCcoreAudioPlayback_start(ALCcoreAudioPlayback *self)
return ALC_TRUE;
}
-static void ALCcoreAudioPlayback_stop(ALCcoreAudioPlayback *self)
+void CoreAudioPlayback::stop()
{
- OSStatus err{AudioOutputUnitStop(self->mAudioUnit)};
+ OSStatus err{AudioOutputUnitStop(mAudioUnit)};
if(err != noErr)
ERR("AudioOutputUnitStop failed\n");
}
-struct ALCcoreAudioCapture final : public ALCbackend {
- ALCcoreAudioCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCcoreAudioCapture() override;
+struct CoreAudioCapture final : public BackendBase {
+ CoreAudioCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~CoreAudioCapture() override;
static OSStatus RecordProcC(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
@@ -333,6 +314,12 @@ struct ALCcoreAudioCapture final : public ALCbackend {
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber,
UInt32 inNumberFrames, AudioBufferList *ioData);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
AudioUnit mAudioUnit{0};
ALuint mFrameSize{0u};
@@ -341,34 +328,12 @@ struct ALCcoreAudioCapture final : public ALCbackend {
SampleConverterPtr mConverter;
RingBufferPtr mRing{nullptr};
-};
-
-static void ALCcoreAudioCapture_Construct(ALCcoreAudioCapture *self, ALCdevice *device);
-static void ALCcoreAudioCapture_Destruct(ALCcoreAudioCapture *self);
-static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar *name);
-static DECLARE_FORWARD(ALCcoreAudioCapture, ALCbackend, ALCboolean, reset)
-static ALCboolean ALCcoreAudioCapture_start(ALCcoreAudioCapture *self);
-static void ALCcoreAudioCapture_stop(ALCcoreAudioCapture *self);
-static ALCenum ALCcoreAudioCapture_captureSamples(ALCcoreAudioCapture *self, ALCvoid *buffer, ALCuint samples);
-static ALCuint ALCcoreAudioCapture_availableSamples(ALCcoreAudioCapture *self);
-static DECLARE_FORWARD(ALCcoreAudioCapture, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(ALCcoreAudioCapture, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCcoreAudioCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCcoreAudioCapture)
-DEFINE_ALCBACKEND_VTABLE(ALCcoreAudioCapture);
-
-
-static void ALCcoreAudioCapture_Construct(ALCcoreAudioCapture *self, ALCdevice *device)
-{
- new (self) ALCcoreAudioCapture{device};
- SET_VTABLE2(ALCcoreAudioCapture, ALCbackend, self);
-}
-
-static void ALCcoreAudioCapture_Destruct(ALCcoreAudioCapture *self)
-{ self->~ALCcoreAudioCapture(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "CoreAudioCapture::"; }
+ DEF_NEWDEL(CoreAudioCapture)
+};
-ALCcoreAudioCapture::~ALCcoreAudioCapture()
+CoreAudioCapture::~CoreAudioCapture()
{
if(mAudioUnit)
AudioComponentInstanceDispose(mAudioUnit);
@@ -376,17 +341,17 @@ ALCcoreAudioCapture::~ALCcoreAudioCapture()
}
-OSStatus ALCcoreAudioCapture::RecordProcC(void *inRefCon,
+OSStatus CoreAudioCapture::RecordProcC(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
- return static_cast<ALCcoreAudioCapture*>(inRefCon)->RecordProc(ioActionFlags, inTimeStamp,
+ return static_cast<CoreAudioCapture*>(inRefCon)->RecordProc(ioActionFlags, inTimeStamp,
inBusNumber, inNumberFrames, ioData);
}
-OSStatus ALCcoreAudioCapture::RecordProc(AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData)
+OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags* UNUSED(ioActionFlags),
+ const AudioTimeStamp *inTimeStamp, UInt32 UNUSED(inBusNumber), UInt32 inNumberFrames,
+ AudioBufferList* UNUSED(ioData))
{
AudioUnitRenderActionFlags flags = 0;
union {
@@ -430,9 +395,8 @@ OSStatus ALCcoreAudioCapture::RecordProc(AudioUnitRenderActionFlags *ioActionFla
}
-static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar *name)
+ALCenum CoreAudioCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
AudioStreamBasicDescription requestedFormat; // The application requested format
AudioStreamBasicDescription hardwareFormat; // The hardware format
AudioStreamBasicDescription outputFormat; // The AudioUnit output format
@@ -469,7 +433,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Open the component
- err = AudioComponentInstanceNew(comp, &self->mAudioUnit);
+ err = AudioComponentInstanceNew(comp, &mAudioUnit);
if(err != noErr)
{
ERR("AudioComponentInstanceNew failed\n");
@@ -478,7 +442,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
// Turn off AudioUnit output
enableIO = 0;
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioOutputUnitProperty_EnableIO,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output, 0, &enableIO, sizeof(ALuint));
if(err != noErr)
{
@@ -488,7 +452,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
// Turn on AudioUnit input
enableIO = 1;
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioOutputUnitProperty_EnableIO,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input, 1, &enableIO, sizeof(ALuint));
if(err != noErr)
{
@@ -519,7 +483,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Track the input device
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioOutputUnitProperty_CurrentDevice,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, 0, &inputDevice, sizeof(AudioDeviceID));
if(err != noErr)
{
@@ -530,10 +494,10 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
#endif
// set capture callback
- input.inputProc = ALCcoreAudioCapture::RecordProcC;
- input.inputProcRefCon = self;
+ input.inputProc = CoreAudioCapture::RecordProcC;
+ input.inputProcRefCon = this;
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioOutputUnitProperty_SetInputCallback,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global, 0, &input, sizeof(AURenderCallbackStruct));
if(err != noErr)
{
@@ -542,7 +506,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Initialize the device
- err = AudioUnitInitialize(self->mAudioUnit);
+ err = AudioUnitInitialize(mAudioUnit);
if(err != noErr)
{
ERR("AudioUnitInitialize failed\n");
@@ -551,8 +515,8 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
// Get the hardware format
propertySize = sizeof(AudioStreamBasicDescription);
- err = AudioUnitGetProperty(self->mAudioUnit, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input, 1, &hardwareFormat, &propertySize);
+ err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
+ 1, &hardwareFormat, &propertySize);
if(err != noErr || propertySize != sizeof(AudioStreamBasicDescription))
{
ERR("AudioUnitGetProperty failed\n");
@@ -560,7 +524,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Set up the requested format description
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtUByte:
requestedFormat.mBitsPerChannel = 8;
@@ -581,11 +545,11 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
case DevFmtByte:
case DevFmtUShort:
case DevFmtUInt:
- ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
+ ERR("%s samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_VALUE;
}
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
requestedFormat.mChannelsPerFrame = 1;
@@ -600,20 +564,20 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
case DevFmtX61:
case DevFmtX71:
case DevFmtAmbi3D:
- ERR("%s not supported\n", DevFmtChannelsString(device->FmtChans));
+ ERR("%s not supported\n", DevFmtChannelsString(mDevice->FmtChans));
return ALC_INVALID_VALUE;
}
requestedFormat.mBytesPerFrame = requestedFormat.mChannelsPerFrame * requestedFormat.mBitsPerChannel / 8;
requestedFormat.mBytesPerPacket = requestedFormat.mBytesPerFrame;
- requestedFormat.mSampleRate = device->Frequency;
+ requestedFormat.mSampleRate = mDevice->Frequency;
requestedFormat.mFormatID = kAudioFormatLinearPCM;
requestedFormat.mReserved = 0;
requestedFormat.mFramesPerPacket = 1;
// save requested format description for later use
- self->mFormat = requestedFormat;
- self->mFrameSize = device->frameSizeFromFmt();
+ mFormat = requestedFormat;
+ mFrameSize = mDevice->frameSizeFromFmt();
// Use intermediate format for sample rate conversion (outputFormat)
// Set sample rate to the same as hardware for resampling later
@@ -622,8 +586,8 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
// The output format should be the requested format, but using the hardware sample rate
// This is because the AudioUnit will automatically scale other properties, except for sample rate
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output, 1, (void *)&outputFormat, sizeof(outputFormat));
+ err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output,
+ 1, (void*)&outputFormat, sizeof(outputFormat));
if(err != noErr)
{
ERR("AudioUnitSetProperty failed\n");
@@ -631,9 +595,9 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Set the AudioUnit output format frame count
- ALuint64 FrameCount64{device->UpdateSize};
- FrameCount64 = (FrameCount64*outputFormat.mSampleRate + device->Frequency-1) /
- device->Frequency;
+ ALuint64 FrameCount64{mDevice->UpdateSize};
+ FrameCount64 = (FrameCount64*outputFormat.mSampleRate + mDevice->Frequency-1) /
+ mDevice->Frequency;
FrameCount64 += MAX_RESAMPLE_PADDING*2;
if(FrameCount64 > std::numeric_limits<uint32_t>::max()/2)
{
@@ -642,7 +606,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
outputFrameCount = static_cast<uint32_t>(FrameCount64);
- err = AudioUnitSetProperty(self->mAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice,
+ err = AudioUnitSetProperty(mAudioUnit, kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Output, 0, &outputFrameCount, sizeof(outputFrameCount));
if(err != noErr)
{
@@ -651,22 +615,22 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
}
// Set up sample converter if needed
- if(outputFormat.mSampleRate != device->Frequency)
- self->mConverter = CreateSampleConverter(device->FmtType, device->FmtType,
- self->mFormat.mChannelsPerFrame, hardwareFormat.mSampleRate, device->Frequency,
+ if(outputFormat.mSampleRate != mDevice->Frequency)
+ mConverter = CreateSampleConverter(mDevice->FmtType, mDevice->FmtType,
+ mFormat.mChannelsPerFrame, hardwareFormat.mSampleRate, mDevice->Frequency,
BSinc24Resampler);
- self->mRing = CreateRingBuffer(outputFrameCount, self->mFrameSize, false);
- if(!self->mRing) return ALC_INVALID_VALUE;
+ mRing = CreateRingBuffer(outputFrameCount, mFrameSize, false);
+ if(!mRing) return ALC_INVALID_VALUE;
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCcoreAudioCapture_start(ALCcoreAudioCapture *self)
+ALCboolean CoreAudioCapture::start()
{
- OSStatus err{AudioOutputUnitStart(self->mAudioUnit)};
+ OSStatus err{AudioOutputUnitStart(mAudioUnit)};
if(err != noErr)
{
ERR("AudioOutputUnitStart failed\n");
@@ -675,48 +639,44 @@ static ALCboolean ALCcoreAudioCapture_start(ALCcoreAudioCapture *self)
return ALC_TRUE;
}
-static void ALCcoreAudioCapture_stop(ALCcoreAudioCapture *self)
+void CoreAudioCapture::stop()
{
- OSStatus err{AudioOutputUnitStop(self->mAudioUnit)};
+ OSStatus err{AudioOutputUnitStop(mAudioUnit)};
if(err != noErr)
ERR("AudioOutputUnitStop failed\n");
}
-static ALCenum ALCcoreAudioCapture_captureSamples(ALCcoreAudioCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum CoreAudioCapture::captureSamples(void *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
-
- if(!self->mConverter)
+ if(!mConverter)
{
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
- auto rec_vec = ring->getReadVector();
+ auto rec_vec = mRing->getReadVector();
const void *src0{rec_vec.first.buf};
auto src0len = static_cast<ALsizei>(rec_vec.first.len);
- auto got = static_cast<ALuint>(SampleConverterInput(self->mConverter.get(), &src0, &src0len,
+ auto got = static_cast<ALuint>(SampleConverterInput(mConverter.get(), &src0, &src0len,
buffer, samples));
size_t total_read{rec_vec.first.len - src0len};
if(got < samples && !src0len && rec_vec.second.len > 0)
{
const void *src1{rec_vec.second.buf};
auto src1len = static_cast<ALsizei>(rec_vec.second.len);
- got += static_cast<ALuint>(SampleConverterInput(self->mConverter.get(), &src1, &src1len,
+ got += static_cast<ALuint>(SampleConverterInput(mConverter.get(), &src1, &src1len,
static_cast<char*>(buffer)+got, samples-got));
total_read += rec_vec.second.len - src1len;
}
- ring->readAdvance(total_read);
+ mRing->readAdvance(total_read);
return ALC_NO_ERROR;
}
-static ALCuint ALCcoreAudioCapture_availableSamples(ALCcoreAudioCapture *self)
+ALCuint CoreAudioCapture::availableSamples()
{
- RingBuffer *ring{self->mRing.get()};
-
- if(!self->mConverter) return ring->readSpace();
- return SampleConverterAvailableOut(self->mConverter.get(), ring->readSpace());
+ if(!mConverter) return mRing->readSpace();
+ return SampleConverterAvailableOut(mConverter.get(), mRing->readSpace());
}
} // namespace
@@ -744,20 +704,11 @@ void CoreAudioBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *CoreAudioBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *CoreAudioBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCcoreAudioPlayback *backend;
- NEW_OBJ(backend, ALCcoreAudioPlayback)(device);
- return backend;
- }
+ return new CoreAudioPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCcoreAudioCapture *backend;
- NEW_OBJ(backend, ALCcoreAudioCapture)(device);
- return backend;
- }
-
+ return new CoreAudioCapture{device};
return nullptr;
}
diff --git a/Alc/backends/coreaudio.h b/Alc/backends/coreaudio.h
index bc9c492c..db151b8a 100644
--- a/Alc/backends/coreaudio.h
+++ b/Alc/backends/coreaudio.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/dsound.cpp b/Alc/backends/dsound.cpp
index 832068ad..44e6fde4 100644
--- a/Alc/backends/dsound.cpp
+++ b/Alc/backends/dsound.cpp
@@ -184,12 +184,17 @@ BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHAR* UNUS
}
-struct ALCdsoundPlayback final : public ALCbackend {
- ALCdsoundPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCdsoundPlayback() override;
+struct DSoundPlayback final : public BackendBase {
+ DSoundPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~DSoundPlayback() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
IDirectSound *mDS{nullptr};
IDirectSoundBuffer *mPrimaryBuffer{nullptr};
IDirectSoundBuffer *mBuffer{nullptr};
@@ -198,34 +203,12 @@ struct ALCdsoundPlayback final : public ALCbackend {
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-void ALCdsoundPlayback_Construct(ALCdsoundPlayback *self, ALCdevice *device);
-void ALCdsoundPlayback_Destruct(ALCdsoundPlayback *self);
-ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *name);
-ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self);
-ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self);
-void ALCdsoundPlayback_stop(ALCdsoundPlayback *self);
-DECLARE_FORWARD2(ALCdsoundPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCdsoundPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(ALCdsoundPlayback);
-
-void ALCdsoundPlayback_Construct(ALCdsoundPlayback *self, ALCdevice *device)
-{
- new (self) ALCdsoundPlayback{device};
- SET_VTABLE2(ALCdsoundPlayback, ALCbackend, self);
-}
-
-void ALCdsoundPlayback_Destruct(ALCdsoundPlayback *self)
-{ self->~ALCdsoundPlayback(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "DSoundPlayback::"; }
+ DEF_NEWDEL(DSoundPlayback)
+};
-ALCdsoundPlayback::~ALCdsoundPlayback()
+DSoundPlayback::~DSoundPlayback()
{
if(mNotifies)
mNotifies->Release();
@@ -246,7 +229,7 @@ ALCdsoundPlayback::~ALCdsoundPlayback()
}
-FORCE_ALIGN int ALCdsoundPlayback::mixerProc()
+FORCE_ALIGN int DSoundPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -257,9 +240,9 @@ FORCE_ALIGN int ALCdsoundPlayback::mixerProc()
if(FAILED(err))
{
ERR("Failed to get buffer caps: 0x%lx\n", err);
- ALCdsoundPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failure retrieving playback buffer info: 0x%lx", err);
- ALCdsoundPlayback_unlock(this);
+ unlock();
return 1;
}
@@ -285,9 +268,9 @@ FORCE_ALIGN int ALCdsoundPlayback::mixerProc()
if(FAILED(err))
{
ERR("Failed to play buffer: 0x%lx\n", err);
- ALCdsoundPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failure starting playback: 0x%lx", err);
- ALCdsoundPlayback_unlock(this);
+ unlock();
return 1;
}
Playing = true;
@@ -319,25 +302,22 @@ FORCE_ALIGN int ALCdsoundPlayback::mixerProc()
}
}
- // Successfully locked the output buffer
if(SUCCEEDED(err))
{
- // If we have an active context, mix data directly into output buffer otherwise fill with silence
- ALCdsoundPlayback_lock(this);
+ lock();
aluMixData(mDevice, WritePtr1, WriteCnt1/FrameSize);
if(WriteCnt2 > 0)
aluMixData(mDevice, WritePtr2, WriteCnt2/FrameSize);
- ALCdsoundPlayback_unlock(this);
+ unlock();
- // Unlock output buffer only when successfully locked
mBuffer->Unlock(WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
}
else
{
ERR("Buffer lock error: %#lx\n", err);
- ALCdsoundPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to lock output buffer: 0x%lx", err);
- ALCdsoundPlayback_unlock(this);
+ unlock();
return 1;
}
@@ -349,10 +329,8 @@ FORCE_ALIGN int ALCdsoundPlayback::mixerProc()
return 0;
}
-ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *deviceName)
+ALCenum DSoundPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
HRESULT hr;
if(PlaybackDevices.empty())
{
@@ -366,16 +344,16 @@ ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *deviceNam
}
const GUID *guid{nullptr};
- if(!deviceName && !PlaybackDevices.empty())
+ if(!name && !PlaybackDevices.empty())
{
- deviceName = PlaybackDevices[0].name.c_str();
+ name = PlaybackDevices[0].name.c_str();
guid = &PlaybackDevices[0].guid;
}
else
{
auto iter = std::find_if(PlaybackDevices.cbegin(), PlaybackDevices.cend(),
- [deviceName](const DevMap &entry) -> bool
- { return entry.name == deviceName; }
+ [name](const DevMap &entry) -> bool
+ { return entry.name == name; }
);
if(iter == PlaybackDevices.cend())
return ALC_INVALID_VALUE;
@@ -383,52 +361,50 @@ ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *deviceNam
}
hr = DS_OK;
- self->mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
- if(!self->mNotifyEvent) hr = E_FAIL;
+ mNotifyEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr);
+ if(!mNotifyEvent) hr = E_FAIL;
//DirectSound Init code
if(SUCCEEDED(hr))
- hr = DirectSoundCreate(guid, &self->mDS, nullptr);
+ hr = DirectSoundCreate(guid, &mDS, nullptr);
if(SUCCEEDED(hr))
- hr = self->mDS->SetCooperativeLevel(GetForegroundWindow(), DSSCL_PRIORITY);
+ hr = mDS->SetCooperativeLevel(GetForegroundWindow(), DSSCL_PRIORITY);
if(FAILED(hr))
{
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
}
- device->DeviceName = deviceName;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self)
+ALCboolean DSoundPlayback::reset()
{
- ALCdevice *device{self->mDevice};
-
- if(self->mNotifies)
- self->mNotifies->Release();
- self->mNotifies = nullptr;
- if(self->mBuffer)
- self->mBuffer->Release();
- self->mBuffer = nullptr;
- if(self->mPrimaryBuffer)
- self->mPrimaryBuffer->Release();
- self->mPrimaryBuffer = nullptr;
+ if(mNotifies)
+ mNotifies->Release();
+ mNotifies = nullptr;
+ if(mBuffer)
+ mBuffer->Release();
+ mBuffer = nullptr;
+ if(mPrimaryBuffer)
+ mPrimaryBuffer->Release();
+ mPrimaryBuffer = nullptr;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
- device->FmtType = DevFmtUByte;
+ mDevice->FmtType = DevFmtUByte;
break;
case DevFmtFloat:
- if((device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
+ if((mDevice->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
break;
/* fall-through */
case DevFmtUShort:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
break;
case DevFmtUInt:
- device->FmtType = DevFmtInt;
+ mDevice->FmtType = DevFmtInt;
break;
case DevFmtUByte:
case DevFmtShort:
@@ -438,37 +414,37 @@ ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self)
WAVEFORMATEXTENSIBLE OutputType{};
DWORD speakers;
- HRESULT hr{self->mDS->GetSpeakerConfig(&speakers)};
+ HRESULT hr{mDS->GetSpeakerConfig(&speakers)};
if(SUCCEEDED(hr))
{
speakers = DSSPEAKER_CONFIG(speakers);
- if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
+ if(!(mDevice->Flags&DEVICE_CHANNELS_REQUEST))
{
if(speakers == DSSPEAKER_MONO)
- device->FmtChans = DevFmtMono;
+ mDevice->FmtChans = DevFmtMono;
else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
else if(speakers == DSSPEAKER_QUAD)
- device->FmtChans = DevFmtQuad;
+ mDevice->FmtChans = DevFmtQuad;
else if(speakers == DSSPEAKER_5POINT1_SURROUND)
- device->FmtChans = DevFmtX51;
+ mDevice->FmtChans = DevFmtX51;
else if(speakers == DSSPEAKER_5POINT1_BACK)
- device->FmtChans = DevFmtX51Rear;
+ mDevice->FmtChans = DevFmtX51Rear;
else if(speakers == DSSPEAKER_7POINT1 || speakers == DSSPEAKER_7POINT1_SURROUND)
- device->FmtChans = DevFmtX71;
+ mDevice->FmtChans = DevFmtX71;
else
ERR("Unknown system speaker config: 0x%lx\n", speakers);
}
- device->IsHeadphones = (device->FmtChans == DevFmtStereo &&
- speakers == DSSPEAKER_HEADPHONE);
+ mDevice->IsHeadphones = (mDevice->FmtChans == DevFmtStereo &&
+ speakers == DSSPEAKER_HEADPHONE);
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
break;
case DevFmtAmbi3D:
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
/*fall-through*/
case DevFmtStereo:
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
@@ -520,62 +496,62 @@ ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self)
retry_open:
hr = S_OK;
OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
- OutputType.Format.nChannels = device->channelsFromFmt();
- OutputType.Format.wBitsPerSample = device->bytesFromFmt() * 8;
+ OutputType.Format.nChannels = mDevice->channelsFromFmt();
+ OutputType.Format.wBitsPerSample = mDevice->bytesFromFmt() * 8;
OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
- OutputType.Format.nSamplesPerSec = device->Frequency;
+ OutputType.Format.nSamplesPerSec = mDevice->Frequency;
OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
OutputType.Format.cbSize = 0;
}
- if(OutputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat)
+ if(OutputType.Format.nChannels > 2 || mDevice->FmtType == DevFmtFloat)
{
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
OutputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
- if(device->FmtType == DevFmtFloat)
+ if(mDevice->FmtType == DevFmtFloat)
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- if(self->mPrimaryBuffer)
- self->mPrimaryBuffer->Release();
- self->mPrimaryBuffer = nullptr;
+ if(mPrimaryBuffer)
+ mPrimaryBuffer->Release();
+ mPrimaryBuffer = nullptr;
}
else
{
- if(SUCCEEDED(hr) && !self->mPrimaryBuffer)
+ if(SUCCEEDED(hr) && !mPrimaryBuffer)
{
DSBUFFERDESC DSBDescription{};
DSBDescription.dwSize = sizeof(DSBDescription);
DSBDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
- hr = self->mDS->CreateSoundBuffer(&DSBDescription, &self->mPrimaryBuffer, nullptr);
+ hr = mDS->CreateSoundBuffer(&DSBDescription, &mPrimaryBuffer, nullptr);
}
if(SUCCEEDED(hr))
- hr = self->mPrimaryBuffer->SetFormat(&OutputType.Format);
+ hr = mPrimaryBuffer->SetFormat(&OutputType.Format);
}
if(SUCCEEDED(hr))
{
- if(device->NumUpdates > MAX_UPDATES)
+ if(mDevice->NumUpdates > MAX_UPDATES)
{
- device->UpdateSize = (device->UpdateSize*device->NumUpdates +
- MAX_UPDATES-1) / MAX_UPDATES;
- device->NumUpdates = MAX_UPDATES;
+ mDevice->UpdateSize = (mDevice->UpdateSize*mDevice->NumUpdates + MAX_UPDATES-1) /
+ MAX_UPDATES;
+ mDevice->NumUpdates = MAX_UPDATES;
}
DSBUFFERDESC DSBDescription{};
DSBDescription.dwSize = sizeof(DSBDescription);
DSBDescription.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 |
DSBCAPS_GLOBALFOCUS;
- DSBDescription.dwBufferBytes = device->UpdateSize * device->NumUpdates *
+ DSBDescription.dwBufferBytes = mDevice->UpdateSize * mDevice->NumUpdates *
OutputType.Format.nBlockAlign;
DSBDescription.lpwfxFormat = &OutputType.Format;
- hr = self->mDS->CreateSoundBuffer(&DSBDescription, &self->mBuffer, nullptr);
- if(FAILED(hr) && device->FmtType == DevFmtFloat)
+ hr = mDS->CreateSoundBuffer(&DSBDescription, &mBuffer, nullptr);
+ if(FAILED(hr) && mDevice->FmtType == DevFmtFloat)
{
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
goto retry_open;
}
}
@@ -583,50 +559,50 @@ retry_open:
if(SUCCEEDED(hr))
{
void *ptr;
- hr = self->mBuffer->QueryInterface(IID_IDirectSoundNotify, &ptr);
+ hr = mBuffer->QueryInterface(IID_IDirectSoundNotify, &ptr);
if(SUCCEEDED(hr))
{
auto Notifies = static_cast<IDirectSoundNotify*>(ptr);
- self->mNotifies = Notifies;
+ mNotifies = Notifies;
- device->NumUpdates = minu(device->NumUpdates, MAX_UPDATES);
+ mDevice->NumUpdates = minu(mDevice->NumUpdates, MAX_UPDATES);
std::array<DSBPOSITIONNOTIFY,MAX_UPDATES> nots;
- for(ALuint i{0};i < device->NumUpdates;++i)
+ for(ALuint i{0};i < mDevice->NumUpdates;++i)
{
- nots[i].dwOffset = i * device->UpdateSize * OutputType.Format.nBlockAlign;
- nots[i].hEventNotify = self->mNotifyEvent;
+ nots[i].dwOffset = i * mDevice->UpdateSize * OutputType.Format.nBlockAlign;
+ nots[i].hEventNotify = mNotifyEvent;
}
- if(Notifies->SetNotificationPositions(device->NumUpdates, nots.data()) != DS_OK)
+ if(Notifies->SetNotificationPositions(mDevice->NumUpdates, nots.data()) != DS_OK)
hr = E_FAIL;
}
}
if(FAILED(hr))
{
- if(self->mNotifies)
- self->mNotifies->Release();
- self->mNotifies = nullptr;
- if(self->mBuffer)
- self->mBuffer->Release();
- self->mBuffer = nullptr;
- if(self->mPrimaryBuffer)
- self->mPrimaryBuffer->Release();
- self->mPrimaryBuffer = nullptr;
+ if(mNotifies)
+ mNotifies->Release();
+ mNotifies = nullptr;
+ if(mBuffer)
+ mBuffer->Release();
+ mBuffer = nullptr;
+ if(mPrimaryBuffer)
+ mPrimaryBuffer->Release();
+ mPrimaryBuffer = nullptr;
return ALC_FALSE;
}
- ResetEvent(self->mNotifyEvent);
- SetDefaultWFXChannelOrder(device);
+ ResetEvent(mNotifyEvent);
+ SetDefaultWFXChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self)
+ALCboolean DSoundPlayback::start()
{
try {
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread(std::mem_fn(&ALCdsoundPlayback::mixerProc), self);
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&DSoundPlayback::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -637,20 +613,25 @@ ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self)
return ALC_FALSE;
}
-void ALCdsoundPlayback_stop(ALCdsoundPlayback *self)
+void DSoundPlayback::stop()
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !mThread.joinable())
return;
+ mThread.join();
- self->mThread.join();
-
- self->mBuffer->Stop();
+ mBuffer->Stop();
}
-struct ALCdsoundCapture final : public ALCbackend {
- ALCdsoundCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCdsoundCapture() override;
+struct DSoundCapture final : public BackendBase {
+ DSoundCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~DSoundCapture() override;
+
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
IDirectSoundCapture *mDSC{nullptr};
IDirectSoundCaptureBuffer *mDSCbuffer{nullptr};
@@ -658,32 +639,12 @@ struct ALCdsoundCapture final : public ALCbackend {
DWORD mCursor{0u};
RingBufferPtr mRing;
-};
-
-void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device);
-void ALCdsoundCapture_Destruct(ALCdsoundCapture *self);
-ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *name);
-DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ALCboolean, reset)
-ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self);
-void ALCdsoundCapture_stop(ALCdsoundCapture *self);
-ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples);
-ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self);
-DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCdsoundCapture)
-DEFINE_ALCBACKEND_VTABLE(ALCdsoundCapture);
-
-void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device)
-{
- new (self) ALCdsoundCapture{device};
- SET_VTABLE2(ALCdsoundCapture, ALCbackend, self);
-}
-void ALCdsoundCapture_Destruct(ALCdsoundCapture *self)
-{ self->~ALCdsoundCapture(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "DSoundCapture::"; }
+ DEF_NEWDEL(DSoundCapture)
+};
-ALCdsoundCapture::~ALCdsoundCapture()
+DSoundCapture::~DSoundCapture()
{
if(mDSCbuffer)
{
@@ -698,10 +659,8 @@ ALCdsoundCapture::~ALCdsoundCapture()
}
-ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
+ALCenum DSoundCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
HRESULT hr;
if(CaptureDevices.empty())
{
@@ -715,28 +674,28 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
}
const GUID *guid{nullptr};
- if(!deviceName && !CaptureDevices.empty())
+ if(!name && !CaptureDevices.empty())
{
- deviceName = CaptureDevices[0].name.c_str();
+ name = CaptureDevices[0].name.c_str();
guid = &CaptureDevices[0].guid;
}
else
{
auto iter = std::find_if(CaptureDevices.cbegin(), CaptureDevices.cend(),
- [deviceName](const DevMap &entry) -> bool
- { return entry.name == deviceName; }
+ [name](const DevMap &entry) -> bool
+ { return entry.name == name; }
);
if(iter == CaptureDevices.cend())
return ALC_INVALID_VALUE;
guid = &iter->guid;
}
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
case DevFmtUShort:
case DevFmtUInt:
- WARN("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
+ WARN("%s capture samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_ENUM;
case DevFmtUByte:
@@ -747,7 +706,7 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
}
WAVEFORMATEXTENSIBLE InputType{};
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
InputType.dwChannelMask = SPEAKER_FRONT_CENTER;
@@ -798,31 +757,31 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
SPEAKER_SIDE_RIGHT;
break;
case DevFmtAmbi3D:
- WARN("%s capture not supported\n", DevFmtChannelsString(device->FmtChans));
+ WARN("%s capture not supported\n", DevFmtChannelsString(mDevice->FmtChans));
return ALC_INVALID_ENUM;
}
InputType.Format.wFormatTag = WAVE_FORMAT_PCM;
- InputType.Format.nChannels = device->channelsFromFmt();
- InputType.Format.wBitsPerSample = device->bytesFromFmt() * 8;
+ InputType.Format.nChannels = mDevice->channelsFromFmt();
+ InputType.Format.wBitsPerSample = mDevice->bytesFromFmt() * 8;
InputType.Format.nBlockAlign = InputType.Format.nChannels*InputType.Format.wBitsPerSample/8;
- InputType.Format.nSamplesPerSec = device->Frequency;
+ InputType.Format.nSamplesPerSec = mDevice->Frequency;
InputType.Format.nAvgBytesPerSec = InputType.Format.nSamplesPerSec*InputType.Format.nBlockAlign;
InputType.Format.cbSize = 0;
InputType.Samples.wValidBitsPerSample = InputType.Format.wBitsPerSample;
- if(device->FmtType == DevFmtFloat)
+ if(mDevice->FmtType == DevFmtFloat)
InputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else
InputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- if(InputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat)
+ if(InputType.Format.nChannels > 2 || mDevice->FmtType == DevFmtFloat)
{
InputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
}
- ALuint samples{device->UpdateSize * device->NumUpdates};
- samples = maxu(samples, 100 * device->Frequency / 1000);
+ ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
+ samples = maxu(samples, 100 * mDevice->Frequency / 1000);
DSCBUFFERDESC DSCBDescription{};
DSCBDescription.dwSize = sizeof(DSCBDescription);
@@ -831,107 +790,101 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
DSCBDescription.lpwfxFormat = &InputType.Format;
//DirectSoundCapture Init code
- hr = DirectSoundCaptureCreate(guid, &self->mDSC, nullptr);
+ hr = DirectSoundCaptureCreate(guid, &mDSC, nullptr);
if(SUCCEEDED(hr))
- self->mDSC->CreateCaptureBuffer(&DSCBDescription, &self->mDSCbuffer, nullptr);
+ mDSC->CreateCaptureBuffer(&DSCBDescription, &mDSCbuffer, nullptr);
if(SUCCEEDED(hr))
{
- self->mRing = CreateRingBuffer(device->UpdateSize*device->NumUpdates,
+ mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates,
InputType.Format.nBlockAlign, false);
- if(!self->mRing) hr = DSERR_OUTOFMEMORY;
+ if(!mRing) hr = DSERR_OUTOFMEMORY;
}
if(FAILED(hr))
{
ERR("Device init failed: 0x%08lx\n", hr);
- self->mRing = nullptr;
- if(self->mDSCbuffer)
- self->mDSCbuffer->Release();
- self->mDSCbuffer = nullptr;
- if(self->mDSC)
- self->mDSC->Release();
- self->mDSC = nullptr;
+ mRing = nullptr;
+ if(mDSCbuffer)
+ mDSCbuffer->Release();
+ mDSCbuffer = nullptr;
+ if(mDSC)
+ mDSC->Release();
+ mDSC = nullptr;
return ALC_INVALID_VALUE;
}
- self->mBufferBytes = DSCBDescription.dwBufferBytes;
- SetDefaultWFXChannelOrder(device);
+ mBufferBytes = DSCBDescription.dwBufferBytes;
+ SetDefaultWFXChannelOrder(mDevice);
- device->DeviceName = deviceName;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self)
+ALCboolean DSoundCapture::start()
{
- HRESULT hr{self->mDSCbuffer->Start(DSCBSTART_LOOPING)};
+ HRESULT hr{mDSCbuffer->Start(DSCBSTART_LOOPING)};
if(FAILED(hr))
{
ERR("start failed: 0x%08lx\n", hr);
- aluHandleDisconnect(self->mDevice, "Failure starting capture: 0x%lx", hr);
+ aluHandleDisconnect(mDevice, "Failure starting capture: 0x%lx", hr);
return ALC_FALSE;
}
-
return ALC_TRUE;
}
-void ALCdsoundCapture_stop(ALCdsoundCapture *self)
+void DSoundCapture::stop()
{
- HRESULT hr{self->mDSCbuffer->Stop()};
+ HRESULT hr{mDSCbuffer->Stop()};
if(FAILED(hr))
{
ERR("stop failed: 0x%08lx\n", hr);
- aluHandleDisconnect(self->mDevice, "Failure stopping capture: 0x%lx", hr);
+ aluHandleDisconnect(mDevice, "Failure stopping capture: 0x%lx", hr);
}
}
-ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum DSoundCapture::captureSamples(void *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
-ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
+ALCuint DSoundCapture::availableSamples()
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
-
- if(!device->Connected.load(std::memory_order_acquire))
- return static_cast<ALCuint>(ring->readSpace());
+ if(!mDevice->Connected.load(std::memory_order_acquire))
+ return static_cast<ALCuint>(mRing->readSpace());
- ALsizei FrameSize{device->frameSizeFromFmt()};
- DWORD BufferBytes{self->mBufferBytes};
- DWORD LastCursor{self->mCursor};
+ ALsizei FrameSize{mDevice->frameSizeFromFmt()};
+ DWORD BufferBytes{mBufferBytes};
+ DWORD LastCursor{mCursor};
DWORD ReadCursor;
void *ReadPtr1, *ReadPtr2;
DWORD ReadCnt1, ReadCnt2;
- HRESULT hr{self->mDSCbuffer->GetCurrentPosition(nullptr, &ReadCursor)};
+ HRESULT hr{mDSCbuffer->GetCurrentPosition(nullptr, &ReadCursor)};
if(SUCCEEDED(hr))
{
DWORD NumBytes{(ReadCursor-LastCursor + BufferBytes) % BufferBytes};
- if(!NumBytes) return static_cast<ALCubyte>(ring->readSpace());
- hr = self->mDSCbuffer->Lock(LastCursor, NumBytes, &ReadPtr1, &ReadCnt1,
- &ReadPtr2, &ReadCnt2, 0);
+ if(!NumBytes) return static_cast<ALCubyte>(mRing->readSpace());
+ hr = mDSCbuffer->Lock(LastCursor, NumBytes, &ReadPtr1, &ReadCnt1, &ReadPtr2, &ReadCnt2, 0);
}
if(SUCCEEDED(hr))
{
- ring->write(ReadPtr1, ReadCnt1/FrameSize);
+ mRing->write(ReadPtr1, ReadCnt1/FrameSize);
if(ReadPtr2 != nullptr && ReadCnt2 > 0)
- ring->write(ReadPtr2, ReadCnt2/FrameSize);
- hr = self->mDSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
- self->mCursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
+ mRing->write(ReadPtr2, ReadCnt2/FrameSize);
+ hr = mDSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
+ mCursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
}
if(FAILED(hr))
{
ERR("update failed: 0x%08lx\n", hr);
- aluHandleDisconnect(device, "Failure retrieving capture data: 0x%lx", hr);
+ aluHandleDisconnect(mDevice, "Failure retrieving capture data: 0x%lx", hr);
}
- return static_cast<ALCuint>(ring->readSpace());
+ return static_cast<ALCuint>(mRing->readSpace());
}
} // namespace
@@ -996,21 +949,11 @@ void DSoundBackendFactory::probe(DevProbe type, std::string *outnames)
CoUninitialize();
}
-ALCbackend *DSoundBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *DSoundBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCdsoundPlayback *backend;
- NEW_OBJ(backend, ALCdsoundPlayback)(device);
- return backend;
- }
-
+ return new DSoundPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCdsoundCapture *backend;
- NEW_OBJ(backend, ALCdsoundCapture)(device);
- return backend;
- }
-
+ return new DSoundCapture{device};
return nullptr;
}
diff --git a/Alc/backends/dsound.h b/Alc/backends/dsound.h
index 3911686e..93b76c7c 100644
--- a/Alc/backends/dsound.h
+++ b/Alc/backends/dsound.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/jack.cpp b/Alc/backends/jack.cpp
index 26086bf9..77bbf487 100644
--- a/Alc/backends/jack.cpp
+++ b/Alc/backends/jack.cpp
@@ -148,9 +148,9 @@ ALCboolean jack_load(void)
}
-struct ALCjackPlayback final : public ALCbackend {
- ALCjackPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCjackPlayback() override;
+struct JackPlayback final : public BackendBase {
+ JackPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~JackPlayback() override;
static int bufferSizeNotifyC(jack_nframes_t numframes, void *arg);
int bufferSizeNotify(jack_nframes_t numframes);
@@ -160,6 +160,12 @@ struct ALCjackPlayback final : public ALCbackend {
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+ ClockLatency getClockLatency() override;
+
jack_client_t *mClient{nullptr};
jack_port_t *mPort[MAX_OUTPUT_CHANNELS]{};
@@ -168,34 +174,12 @@ struct ALCjackPlayback final : public ALCbackend {
std::atomic<bool> mKillNow{true};
std::thread mThread;
-};
-
-void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device);
-void ALCjackPlayback_Destruct(ALCjackPlayback *self);
-ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name);
-ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self);
-ALCboolean ALCjackPlayback_start(ALCjackPlayback *self);
-void ALCjackPlayback_stop(ALCjackPlayback *self);
-DECLARE_FORWARD2(ALCjackPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCjackPlayback, ALCbackend, ALCuint, availableSamples)
-ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self);
-DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCjackPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCjackPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(ALCjackPlayback);
+ static constexpr inline const char *CurrentPrefix() noexcept { return "JackPlayback::"; }
+ DEF_NEWDEL(JackPlayback)
+};
-void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device)
-{
- new (self) ALCjackPlayback{device};
- SET_VTABLE2(ALCjackPlayback, ALCbackend, self);
-}
-
-void ALCjackPlayback_Destruct(ALCjackPlayback *self)
-{ self->~ALCjackPlayback(); }
-
-ALCjackPlayback::~ALCjackPlayback()
+JackPlayback::~JackPlayback()
{
if(!mClient)
return;
@@ -210,12 +194,12 @@ ALCjackPlayback::~ALCjackPlayback()
}
-int ALCjackPlayback::bufferSizeNotifyC(jack_nframes_t numframes, void *arg)
-{ return static_cast<ALCjackPlayback*>(arg)->bufferSizeNotify(numframes); }
+int JackPlayback::bufferSizeNotifyC(jack_nframes_t numframes, void *arg)
+{ return static_cast<JackPlayback*>(arg)->bufferSizeNotify(numframes); }
-int ALCjackPlayback::bufferSizeNotify(jack_nframes_t numframes)
+int JackPlayback::bufferSizeNotify(jack_nframes_t numframes)
{
- ALCjackPlayback_lock(this);
+ lock();
mDevice->UpdateSize = numframes;
mDevice->NumUpdates = 2;
@@ -233,15 +217,15 @@ int ALCjackPlayback::bufferSizeNotify(jack_nframes_t numframes)
ERR("Failed to reallocate ringbuffer\n");
aluHandleDisconnect(mDevice, "Failed to reallocate %u-sample buffer", bufsize);
}
- ALCjackPlayback_unlock(this);
+ unlock();
return 0;
}
-int ALCjackPlayback::processC(jack_nframes_t numframes, void *arg)
-{ return static_cast<ALCjackPlayback*>(arg)->process(numframes); }
+int JackPlayback::processC(jack_nframes_t numframes, void *arg)
+{ return static_cast<JackPlayback*>(arg)->process(numframes); }
-int ALCjackPlayback::process(jack_nframes_t numframes)
+int JackPlayback::process(jack_nframes_t numframes)
{
jack_default_audio_sample_t *out[MAX_OUTPUT_CHANNELS];
ALsizei numchans{0};
@@ -311,20 +295,20 @@ int ALCjackPlayback::process(jack_nframes_t numframes)
return 0;
}
-int ALCjackPlayback::mixerProc()
+int JackPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
- ALCjackPlayback_lock(this);
+ lock();
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
{
if(mRing->writeSpace() < mDevice->UpdateSize)
{
- ALCjackPlayback_unlock(this);
+ unlock();
mSem.wait();
- ALCjackPlayback_lock(this);
+ lock();
continue;
}
@@ -340,13 +324,13 @@ int ALCjackPlayback::mixerProc()
aluMixData(mDevice, data.second.buf, len2);
mRing->writeAdvance(todo);
}
- ALCjackPlayback_unlock(this);
+ unlock();
return 0;
}
-ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
+ALCenum JackPlayback::open(const ALCchar *name)
{
if(!name)
name = jackDevice;
@@ -355,8 +339,8 @@ ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
const char *client_name{"alsoft"};
jack_status_t status;
- self->mClient = jack_client_open(client_name, ClientOptions, &status, nullptr);
- if(self->mClient == nullptr)
+ mClient = jack_client_open(client_name, ClientOptions, &status, nullptr);
+ if(mClient == nullptr)
{
ERR("jack_client_open() failed, status = 0x%02x\n", status);
return ALC_INVALID_VALUE;
@@ -365,104 +349,102 @@ ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
TRACE("JACK server started\n");
if((status&JackNameNotUnique))
{
- client_name = jack_get_client_name(self->mClient);
+ client_name = jack_get_client_name(mClient);
TRACE("Client name not unique, got `%s' instead\n", client_name);
}
- jack_set_process_callback(self->mClient, &ALCjackPlayback::processC, self);
- jack_set_buffer_size_callback(self->mClient, &ALCjackPlayback::bufferSizeNotifyC, self);
+ jack_set_process_callback(mClient, &JackPlayback::processC, this);
+ jack_set_buffer_size_callback(mClient, &JackPlayback::bufferSizeNotifyC, this);
- ALCdevice *device{self->mDevice};
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
+ALCboolean JackPlayback::reset()
{
- std::for_each(std::begin(self->mPort), std::end(self->mPort),
- [self](jack_port_t *port) -> void
- { if(port) jack_port_unregister(self->mClient, port); }
+ std::for_each(std::begin(mPort), std::end(mPort),
+ [this](jack_port_t *port) -> void
+ { if(port) jack_port_unregister(mClient, port); }
);
- std::fill(std::begin(self->mPort), std::end(self->mPort), nullptr);
+ std::fill(std::begin(mPort), std::end(mPort), nullptr);
/* Ignore the requested buffer metrics and just keep one JACK-sized buffer
* ready for when requested.
*/
- ALCdevice *device{self->mDevice};
- device->Frequency = jack_get_sample_rate(self->mClient);
- device->UpdateSize = jack_get_buffer_size(self->mClient);
- device->NumUpdates = 2;
+ mDevice->Frequency = jack_get_sample_rate(mClient);
+ mDevice->UpdateSize = jack_get_buffer_size(mClient);
+ mDevice->NumUpdates = 2;
- ALuint bufsize{device->UpdateSize};
- if(ConfigValueUInt(device->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
- bufsize = maxu(NextPowerOf2(bufsize), device->UpdateSize);
- device->NumUpdates = (bufsize+device->UpdateSize) / device->UpdateSize;
+ ALuint bufsize{mDevice->UpdateSize};
+ if(ConfigValueUInt(mDevice->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
+ bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
+ mDevice->NumUpdates = (bufsize+mDevice->UpdateSize) / mDevice->UpdateSize;
/* Force 32-bit float output. */
- device->FmtType = DevFmtFloat;
+ mDevice->FmtType = DevFmtFloat;
- ALsizei numchans{device->channelsFromFmt()};
- auto ports_end = std::begin(self->mPort) + numchans;
- auto bad_port = std::find_if_not(std::begin(self->mPort), ports_end,
- [self](jack_port_t *&port) -> bool
+ ALsizei numchans{mDevice->channelsFromFmt()};
+ auto ports_end = std::begin(mPort) + numchans;
+ auto bad_port = std::find_if_not(std::begin(mPort), ports_end,
+ [this](jack_port_t *&port) -> bool
{
- std::string name{"channel_" + std::to_string(&port - self->mPort + 1)};
- port = jack_port_register(self->mClient, name.c_str(), JACK_DEFAULT_AUDIO_TYPE,
+ std::string name{"channel_" + std::to_string(&port - mPort + 1)};
+ port = jack_port_register(mClient, name.c_str(), JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
return port != nullptr;
}
);
if(bad_port != ports_end)
{
- ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(device->FmtChans));
- if(bad_port == std::begin(self->mPort)) return ALC_FALSE;
+ ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(mDevice->FmtChans));
+ if(bad_port == std::begin(mPort)) return ALC_FALSE;
- if(bad_port == std::begin(self->mPort)+1)
- device->FmtChans = DevFmtMono;
+ if(bad_port == std::begin(mPort)+1)
+ mDevice->FmtChans = DevFmtMono;
else
{
- ports_end = self->mPort+2;
+ ports_end = mPort+2;
while(bad_port != ports_end)
{
- jack_port_unregister(self->mClient, *(--bad_port));
+ jack_port_unregister(mClient, *(--bad_port));
*bad_port = nullptr;
}
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
}
- numchans = std::distance(std::begin(self->mPort), bad_port);
+ numchans = std::distance(std::begin(mPort), bad_port);
}
- self->mRing = nullptr;
- self->mRing = CreateRingBuffer(bufsize, device->frameSizeFromFmt(), true);
- if(!self->mRing)
+ mRing = nullptr;
+ mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
+ if(!mRing)
{
ERR("Failed to allocate ringbuffer\n");
return ALC_FALSE;
}
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
+ALCboolean JackPlayback::start()
{
- if(jack_activate(self->mClient))
+ if(jack_activate(mClient))
{
ERR("Failed to activate client\n");
return ALC_FALSE;
}
- const char **ports{jack_get_ports(self->mClient, nullptr, nullptr,
+ const char **ports{jack_get_ports(mClient, nullptr, nullptr,
JackPortIsPhysical|JackPortIsInput)};
if(ports == nullptr)
{
ERR("No physical playback ports found\n");
- jack_deactivate(self->mClient);
+ jack_deactivate(mClient);
return ALC_FALSE;
}
- std::mismatch(std::begin(self->mPort), std::end(self->mPort), ports,
- [self](const jack_port_t *port, const char *pname) -> bool
+ std::mismatch(std::begin(mPort), std::end(mPort), ports,
+ [this](const jack_port_t *port, const char *pname) -> bool
{
if(!port) return false;
if(!pname)
@@ -470,7 +452,7 @@ ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
ERR("No physical playback port for \"%s\"\n", jack_port_name(port));
return false;
}
- if(jack_connect(self->mClient, jack_port_name(port), pname))
+ if(jack_connect(mClient, jack_port_name(port), pname))
ERR("Failed to connect output port \"%s\" to \"%s\"\n", jack_port_name(port),
pname);
return true;
@@ -479,8 +461,8 @@ ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
jack_free(ports);
try {
- self->mKillNow.store(false, std::memory_order_release);
- self->mThread = std::thread(std::mem_fn(&ALCjackPlayback::mixerProc), self);
+ mKillNow.store(false, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&JackPlayback::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -488,33 +470,31 @@ ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
}
catch(...) {
}
- jack_deactivate(self->mClient);
+ jack_deactivate(mClient);
return ALC_FALSE;
}
-void ALCjackPlayback_stop(ALCjackPlayback *self)
+void JackPlayback::stop()
{
- if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mSem.post();
- self->mThread.join();
+ mSem.post();
+ mThread.join();
- jack_deactivate(self->mClient);
+ jack_deactivate(mClient);
}
-ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
+ClockLatency JackPlayback::getClockLatency()
{
ClockLatency ret;
- ALCjackPlayback_lock(self);
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
- ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ring->readSpace()};
- ret.Latency /= device->Frequency;
- ALCjackPlayback_unlock(self);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.Latency = std::chrono::seconds{mRing->readSpace()};
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
@@ -578,15 +558,10 @@ void JackBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *JackBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *JackBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCjackPlayback *backend;
- NEW_OBJ(backend, ALCjackPlayback)(device);
- return backend;
- }
-
+ return new JackPlayback{device};
return nullptr;
}
diff --git a/Alc/backends/jack.h b/Alc/backends/jack.h
index bdf73701..b9bb13b2 100644
--- a/Alc/backends/jack.h
+++ b/Alc/backends/jack.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/loopback.cpp b/Alc/backends/loopback.cpp
index eadacdfb..373b11c9 100644
--- a/Alc/backends/loopback.cpp
+++ b/Alc/backends/loopback.cpp
@@ -28,59 +28,35 @@
namespace {
-struct ALCloopback final : public ALCbackend {
- ALCloopback(ALCdevice *device) noexcept : ALCbackend{device} { }
-};
+struct LoopbackBackend final : public BackendBase {
+ LoopbackBackend(ALCdevice *device) noexcept : BackendBase{device} { }
-void ALCloopback_Construct(ALCloopback *self, ALCdevice *device);
-void ALCloopback_Destruct(ALCloopback *self);
-ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name);
-ALCboolean ALCloopback_reset(ALCloopback *self);
-ALCboolean ALCloopback_start(ALCloopback *self);
-void ALCloopback_stop(ALCloopback *self);
-DECLARE_FORWARD2(ALCloopback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCloopback, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCloopback, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCloopback, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCloopback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCloopback)
-DEFINE_ALCBACKEND_VTABLE(ALCloopback);
-
-
-void ALCloopback_Construct(ALCloopback *self, ALCdevice *device)
-{
- new (self) ALCloopback{device};
- SET_VTABLE2(ALCloopback, ALCbackend, self);
-}
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
-void ALCloopback_Destruct(ALCloopback *self)
-{
- self->~ALCloopback();
-}
+ DEF_NEWDEL(LoopbackBackend)
+};
-ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name)
+ALCenum LoopbackBackend::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCloopback_reset(ALCloopback *self)
+ALCboolean LoopbackBackend::reset()
{
- SetDefaultWFXChannelOrder(self->mDevice);
+ SetDefaultWFXChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCloopback_start(ALCloopback* UNUSED(self))
-{
- return ALC_TRUE;
-}
+ALCboolean LoopbackBackend::start()
+{ return ALC_TRUE; }
-void ALCloopback_stop(ALCloopback* UNUSED(self))
-{
-}
+void LoopbackBackend::stop()
+{ }
} // namespace
@@ -94,15 +70,10 @@ bool LoopbackBackendFactory::querySupport(ALCbackend_Type type)
void LoopbackBackendFactory::probe(DevProbe, std::string*)
{ }
-ALCbackend *LoopbackBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *LoopbackBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Loopback)
- {
- ALCloopback *backend;
- NEW_OBJ(backend, ALCloopback)(device);
- return backend;
- }
-
+ new LoopbackBackend{device};
return nullptr;
}
diff --git a/Alc/backends/loopback.h b/Alc/backends/loopback.h
index 4607d6ed..ab37c2d7 100644
--- a/Alc/backends/loopback.h
+++ b/Alc/backends/loopback.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/null.cpp b/Alc/backends/null.cpp
index 5367c46f..33340a5d 100644
--- a/Alc/backends/null.cpp
+++ b/Alc/backends/null.cpp
@@ -44,42 +44,24 @@ using std::chrono::nanoseconds;
constexpr ALCchar nullDevice[] = "No Output";
-struct ALCnullBackend final : public ALCbackend {
- ALCnullBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct NullBackend final : public BackendBase {
+ NullBackend(ALCdevice *device) noexcept : BackendBase{device} { }
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device);
-void ALCnullBackend_Destruct(ALCnullBackend *self);
-ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name);
-ALCboolean ALCnullBackend_reset(ALCnullBackend *self);
-ALCboolean ALCnullBackend_start(ALCnullBackend *self);
-void ALCnullBackend_stop(ALCnullBackend *self);
-DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCnullBackend, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCnullBackend)
-
-DEFINE_ALCBACKEND_VTABLE(ALCnullBackend);
-
-
-void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device)
-{
- new (self) ALCnullBackend{device};
- SET_VTABLE2(ALCnullBackend, ALCbackend, self);
-}
-
-void ALCnullBackend_Destruct(ALCnullBackend *self)
-{ self->~ALCnullBackend(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "NullBackend::"; }
+ DEF_NEWDEL(NullBackend)
+};
-int ALCnullBackend::mixerProc()
+int NullBackend::mixerProc()
{
const milliseconds restTime{mDevice->UpdateSize*1000/mDevice->Frequency / 2};
@@ -102,9 +84,9 @@ int ALCnullBackend::mixerProc()
}
while(avail-done >= mDevice->UpdateSize)
{
- ALCnullBackend_lock(this);
+ lock();
aluMixData(mDevice, nullptr, mDevice->UpdateSize);
- ALCnullBackend_unlock(this);
+ unlock();
done += mDevice->UpdateSize;
}
@@ -125,30 +107,29 @@ int ALCnullBackend::mixerProc()
}
-ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name)
+ALCenum NullBackend::open(const ALCchar *name)
{
if(!name)
name = nullDevice;
else if(strcmp(name, nullDevice) != 0)
return ALC_INVALID_VALUE;
- ALCdevice *device{self->mDevice};
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCnullBackend_reset(ALCnullBackend *self)
+ALCboolean NullBackend::reset()
{
- SetDefaultWFXChannelOrder(self->mDevice);
+ SetDefaultWFXChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCnullBackend_start(ALCnullBackend *self)
+ALCboolean NullBackend::start()
{
try {
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread(std::mem_fn(&ALCnullBackend::mixerProc), self);
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&NullBackend::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -159,11 +140,11 @@ ALCboolean ALCnullBackend_start(ALCnullBackend *self)
return ALC_FALSE;
}
-void ALCnullBackend_stop(ALCnullBackend *self)
+void NullBackend::stop()
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
}
} // namespace
@@ -188,16 +169,11 @@ void NullBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *NullBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *NullBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCnullBackend *backend;
- NEW_OBJ(backend, ALCnullBackend)(device);
- return backend;
- }
-
- return NULL;
+ return new NullBackend{device};
+ return nullptr;
}
BackendFactory &NullBackendFactory::getFactory()
diff --git a/Alc/backends/null.h b/Alc/backends/null.h
index 37457d94..d4164198 100644
--- a/Alc/backends/null.h
+++ b/Alc/backends/null.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/opensl.cpp b/Alc/backends/opensl.cpp
index b0e51441..4f2e07be 100644
--- a/Alc/backends/opensl.cpp
+++ b/Alc/backends/opensl.cpp
@@ -42,14 +42,15 @@
namespace {
/* Helper macros */
+#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
#define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS
#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
-static const ALCchar opensl_device[] = "OpenSL";
+constexpr ALCchar opensl_device[] = "OpenSL";
-static SLuint32 GetChannelMask(DevFmtChannels chans)
+SLuint32 GetChannelMask(DevFmtChannels chans)
{
switch(chans)
{
@@ -78,7 +79,7 @@ static SLuint32 GetChannelMask(DevFmtChannels chans)
}
#ifdef SL_DATAFORMAT_PCM_EX
-static SLuint32 GetTypeRepresentation(DevFmtType type)
+SLuint32 GetTypeRepresentation(DevFmtType type)
{
switch(type)
{
@@ -97,7 +98,7 @@ static SLuint32 GetTypeRepresentation(DevFmtType type)
}
#endif
-static const char *res_str(SLresult result)
+const char *res_str(SLresult result)
{
switch(result)
{
@@ -132,20 +133,26 @@ static const char *res_str(SLresult result)
}
#define PRINTERR(x, s) do { \
- if((x) != SL_RESULT_SUCCESS) \
+ if(UNLIKELY((x) != SL_RESULT_SUCCESS)) \
ERR("%s: %s\n", (s), res_str((x))); \
} while(0)
-struct ALCopenslPlayback final : public ALCbackend {
- ALCopenslPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCopenslPlayback() override;
+struct OpenSLPlayback final : public BackendBase {
+ OpenSLPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OpenSLPlayback() override;
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context);
void process(SLAndroidSimpleBufferQueueItf bq);
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+ ClockLatency getClockLatency() override;
+
/* engine interfaces */
SLObjectItf mEngineObj{nullptr};
SLEngineItf mEngine{nullptr};
@@ -163,34 +170,12 @@ struct ALCopenslPlayback final : public ALCbackend {
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device);
-static void ALCopenslPlayback_Destruct(ALCopenslPlayback *self);
-static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name);
-static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self);
-static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self);
-static void ALCopenslPlayback_stop(ALCopenslPlayback *self);
-static DECLARE_FORWARD2(ALCopenslPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, ALCuint, availableSamples)
-static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self);
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCopenslPlayback)
-DEFINE_ALCBACKEND_VTABLE(ALCopenslPlayback);
-
-
-static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device)
-{
- new (self) ALCopenslPlayback{device};
- SET_VTABLE2(ALCopenslPlayback, ALCbackend, self);
-}
-
-static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
-{ self->~ALCopenslPlayback(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OpenSLPlayback::"; }
+ DEF_NEWDEL(OpenSLPlayback)
+};
-ALCopenslPlayback::~ALCopenslPlayback()
+OpenSLPlayback::~OpenSLPlayback()
{
if(mBufferQueueObj)
VCALL0(mBufferQueueObj,Destroy)();
@@ -208,10 +193,10 @@ ALCopenslPlayback::~ALCopenslPlayback()
/* this callback handler is called every time a buffer finishes playing */
-void ALCopenslPlayback::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
-{ static_cast<ALCopenslPlayback*>(context)->process(bq); }
+void OpenSLPlayback::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
+{ static_cast<OpenSLPlayback*>(context)->process(bq); }
-void ALCopenslPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
+void OpenSLPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
{
/* A note on the ringbuffer usage: The buffer queue seems to hold on to the
* pointer passed to the Enqueue method, rather than copying the audio.
@@ -226,7 +211,7 @@ void ALCopenslPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
mSem.post();
}
-int ALCopenslPlayback::mixerProc()
+int OpenSLPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -242,7 +227,7 @@ int ALCopenslPlayback::mixerProc()
PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
}
- ALCopenslPlayback_lock(this);
+ lock();
if(SL_RESULT_SUCCESS != result)
aluHandleDisconnect(mDevice, "Failed to get playback buffer: 0x%08x", result);
@@ -251,7 +236,7 @@ int ALCopenslPlayback::mixerProc()
{
if(mRing->writeSpace() == 0)
{
- SLuint32 state = 0;
+ SLuint32 state{0};
result = VCALL(player,GetPlayState)(&state);
PRINTERR(result, "player->GetPlayState");
@@ -268,9 +253,9 @@ int ALCopenslPlayback::mixerProc()
if(mRing->writeSpace() == 0)
{
- ALCopenslPlayback_unlock(this);
+ unlock();
mSem.wait();
- ALCopenslPlayback_lock(this);
+ lock();
continue;
}
}
@@ -304,67 +289,63 @@ int ALCopenslPlayback::mixerProc()
data.first.buf += mDevice->UpdateSize*mFrameSize;
}
}
- ALCopenslPlayback_unlock(this);
+ unlock();
return 0;
}
-static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name)
+ALCenum OpenSLPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
- SLresult result;
-
if(!name)
name = opensl_device;
else if(strcmp(name, opensl_device) != 0)
return ALC_INVALID_VALUE;
// create engine
- result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
+ SLresult result{slCreateEngine(&mEngineObj, 0, NULL, 0, NULL, NULL)};
PRINTERR(result, "slCreateEngine");
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "engine->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
+ result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
PRINTERR(result, "engine->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngine,CreateOutputMix)(&self->mOutputMix, 0, NULL, NULL);
+ result = VCALL(mEngine,CreateOutputMix)(&mOutputMix, 0, NULL, NULL);
PRINTERR(result, "engine->CreateOutputMix");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mOutputMix,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mOutputMix,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "outputMix->Realize");
}
if(SL_RESULT_SUCCESS != result)
{
- if(self->mOutputMix != NULL)
- VCALL0(self->mOutputMix,Destroy)();
- self->mOutputMix = NULL;
+ if(mOutputMix)
+ VCALL0(mOutputMix,Destroy)();
+ mOutputMix = NULL;
- if(self->mEngineObj != NULL)
- VCALL0(self->mEngineObj,Destroy)();
- self->mEngineObj = NULL;
- self->mEngine = NULL;
+ if(mEngineObj)
+ VCALL0(mEngineObj,Destroy)();
+ mEngineObj = NULL;
+ mEngine = NULL;
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
+ALCboolean OpenSLPlayback::reset()
{
- ALCdevice *device{self->mDevice};
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
SLDataLocator_OutputMix loc_outmix;
SLDataSource audioSrc;
@@ -374,15 +355,15 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
SLboolean reqs[2];
SLresult result;
- if(self->mBufferQueueObj != NULL)
- VCALL0(self->mBufferQueueObj,Destroy)();
- self->mBufferQueueObj = NULL;
+ if(mBufferQueueObj)
+ VCALL0(mBufferQueueObj,Destroy)();
+ mBufferQueueObj = NULL;
- self->mRing = nullptr;
+ mRing = nullptr;
- sampleRate = device->Frequency;
+ sampleRate = mDevice->Frequency;
#if 0
- if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
+ if(!(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
{
/* FIXME: Disabled until I figure out how to get the Context needed for
* the getSystemService call.
@@ -449,43 +430,43 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
}
#endif
- if(sampleRate != device->Frequency)
+ if(sampleRate != mDevice->Frequency)
{
- device->NumUpdates = (device->NumUpdates*sampleRate + (device->Frequency>>1)) /
- device->Frequency;
- device->NumUpdates = maxu(device->NumUpdates, 2);
- device->Frequency = sampleRate;
+ mDevice->NumUpdates = (mDevice->NumUpdates*sampleRate + (mDevice->Frequency>>1)) /
+ mDevice->Frequency;
+ mDevice->NumUpdates = maxu(mDevice->NumUpdates, 2);
+ mDevice->Frequency = sampleRate;
}
- device->FmtChans = DevFmtStereo;
- device->FmtType = DevFmtShort;
+ mDevice->FmtChans = DevFmtStereo;
+ mDevice->FmtType = DevFmtShort;
- SetDefaultWFXChannelOrder(device);
- self->mFrameSize = device->frameSizeFromFmt();
+ SetDefaultWFXChannelOrder(mDevice);
+ mFrameSize = mDevice->frameSizeFromFmt();
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- loc_bufq.numBuffers = device->NumUpdates;
+ loc_bufq.numBuffers = mDevice->NumUpdates;
#ifdef SL_DATAFORMAT_PCM_EX
SLDataFormat_PCM_EX format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.sampleRate = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.sampleRate = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
- format_pcm.representation = GetTypeRepresentation(device->FmtType);
+ format_pcm.representation = GetTypeRepresentation(mDevice->FmtType);
#else
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.samplesPerSec = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.samplesPerSec = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
#endif
@@ -494,7 +475,7 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
audioSrc.pFormat = &format_pcm;
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
- loc_outmix.outputMix = self->mOutputMix;
+ loc_outmix.outputMix = mOutputMix;
audioSnk.pLocator = &loc_outmix;
audioSnk.pFormat = NULL;
@@ -504,22 +485,20 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
ids[1] = SL_IID_ANDROIDCONFIGURATION;
reqs[1] = SL_BOOLEAN_FALSE;
- result = VCALL(self->mEngine,CreateAudioPlayer)(&self->mBufferQueueObj,
- &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
- );
+ result = VCALL(mEngine,CreateAudioPlayer)(&mBufferQueueObj, &audioSrc, &audioSnk, COUNTOF(ids),
+ ids, reqs);
PRINTERR(result, "engine->CreateAudioPlayer");
if(SL_RESULT_SUCCESS == result)
{
/* Set the stream type to "media" (games, music, etc), if possible. */
SLAndroidConfigurationItf config;
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
+ result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
if(SL_RESULT_SUCCESS == result)
{
SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
- result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE,
- &streamType, sizeof(streamType)
- );
+ result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE, &streamType,
+ sizeof(streamType));
PRINTERR(result, "config->SetConfiguration");
}
@@ -528,26 +507,25 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "bufferQueue->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = CreateRingBuffer(device->NumUpdates,
- self->mFrameSize*device->UpdateSize, true);
- if(!self->mRing)
+ mRing = CreateRingBuffer(mDevice->NumUpdates, mFrameSize*mDevice->UpdateSize, true);
+ if(!mRing)
{
- ERR("Out of memory allocating ring buffer %ux%u %u\n", device->UpdateSize,
- device->NumUpdates, self->mFrameSize);
+ ERR("Out of memory allocating ring buffer %ux%u %u\n", mDevice->UpdateSize,
+ mDevice->NumUpdates, mFrameSize);
result = SL_RESULT_MEMORY_FAILURE;
}
}
if(SL_RESULT_SUCCESS != result)
{
- if(self->mBufferQueueObj != NULL)
- VCALL0(self->mBufferQueueObj,Destroy)();
- self->mBufferQueueObj = NULL;
+ if(mBufferQueueObj)
+ VCALL0(mBufferQueueObj,Destroy)();
+ mBufferQueueObj = NULL;
return ALC_FALSE;
}
@@ -555,26 +533,24 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
return ALC_TRUE;
}
-static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
+ALCboolean OpenSLPlayback::start()
{
- RingBuffer *ring{self->mRing.get()};
-
- ring->reset();
+ mRing->reset();
SLAndroidSimpleBufferQueueItf bufferQueue;
- SLresult result{VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue)};
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS != result)
return ALC_FALSE;
- result = VCALL(bufferQueue,RegisterCallback)(&ALCopenslPlayback::processC, self);
+ result = VCALL(bufferQueue,RegisterCallback)(&OpenSLPlayback::processC, this);
PRINTERR(result, "bufferQueue->RegisterCallback");
if(SL_RESULT_SUCCESS != result) return ALC_FALSE;
try {
- self->mKillNow.store(AL_FALSE);
- self->mThread = std::thread(std::mem_fn(&ALCopenslPlayback::mixerProc), self);
+ mKillNow.store(AL_FALSE);
+ mThread = std::thread(std::mem_fn(&OpenSLPlayback::mixerProc), this);
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -585,20 +561,16 @@ static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
return ALC_FALSE;
}
-
-static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
+void OpenSLPlayback::stop()
{
- SLAndroidSimpleBufferQueueItf bufferQueue;
- SLPlayItf player;
- SLresult result;
-
- if(self->mKillNow.exchange(AL_TRUE) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE) || !mThread.joinable())
return;
- self->mSem.post();
- self->mThread.join();
+ mSem.post();
+ mThread.join();
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
+ SLPlayItf player;
+ SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player)};
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS == result)
{
@@ -606,8 +578,8 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
PRINTERR(result, "player->SetPlayState");
}
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ SLAndroidSimpleBufferQueueItf bufferQueue;
+ result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS == result)
{
@@ -630,29 +602,33 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
}
}
-static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
+ClockLatency OpenSLPlayback::getClockLatency()
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
ClockLatency ret;
- ALCopenslPlayback_lock(self);
- ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ring->readSpace() * device->UpdateSize};
- ret.Latency /= device->Frequency;
- ALCopenslPlayback_unlock(self);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.Latency = std::chrono::seconds{mRing->readSpace() * mDevice->UpdateSize};
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
-struct ALCopenslCapture final : public ALCbackend {
- ALCopenslCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCopenslCapture() override;
+struct OpenSLCapture final : public BackendBase {
+ OpenSLCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OpenSLCapture() override;
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context);
void process(SLAndroidSimpleBufferQueueItf bq);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
/* engine interfaces */
SLObjectItf mEngineObj{nullptr};
SLEngineItf mEngine;
@@ -664,33 +640,12 @@ struct ALCopenslCapture final : public ALCbackend {
ALCuint mSplOffset{0u};
ALsizei mFrameSize{0};
-};
-static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device);
-static void ALCopenslCapture_Destruct(ALCopenslCapture *self);
-static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name);
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ALCboolean, reset)
-static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self);
-static void ALCopenslCapture_stop(ALCopenslCapture *self);
-static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples);
-static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self);
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCopenslCapture)
-DEFINE_ALCBACKEND_VTABLE(ALCopenslCapture);
-
-
-static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device)
-{
- new (self) ALCopenslCapture{device};
- SET_VTABLE2(ALCopenslCapture, ALCbackend, self);
-}
-
-static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
-{ self->~ALCopenslCapture(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OpenSLCapture::"; }
+ DEF_NEWDEL(OpenSLCapture)
+};
-ALCopenslCapture::~ALCopenslCapture()
+OpenSLCapture::~OpenSLCapture()
{
if(mRecordObj)
VCALL0(mRecordObj,Destroy)();
@@ -703,19 +658,18 @@ ALCopenslCapture::~ALCopenslCapture()
}
-void ALCopenslCapture::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
-{ static_cast<ALCopenslCapture*>(context)->process(bq); }
+void OpenSLCapture::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
+{ static_cast<OpenSLCapture*>(context)->process(bq); }
-void ALCopenslCapture::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
+void OpenSLCapture::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
{
/* A new chunk has been written into the ring buffer, advance it. */
mRing->writeAdvance(1);
}
-static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name)
+ALCenum OpenSLCapture::open(const ALCchar* name)
{
- ALCdevice *device{self->mDevice};
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLDataLocator_IODevice loc_dev;
@@ -728,32 +682,30 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
else if(strcmp(name, opensl_device) != 0)
return ALC_INVALID_VALUE;
- result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
+ result = slCreateEngine(&mEngineObj, 0, NULL, 0, NULL, NULL);
PRINTERR(result, "slCreateEngine");
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "engine->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
+ result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
PRINTERR(result, "engine->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
/* Ensure the total length is at least 100ms */
- ALsizei length = maxi(device->NumUpdates * device->UpdateSize,
- device->Frequency / 10);
+ ALsizei length{maxi(mDevice->NumUpdates*mDevice->UpdateSize, mDevice->Frequency/10)};
/* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
- ALsizei update_len = clampi(device->NumUpdates*device->UpdateSize / 3,
- device->Frequency / 100,
- device->Frequency / 100 * 5);
+ ALsizei update_len{clampi(mDevice->NumUpdates*mDevice->UpdateSize / 3,
+ mDevice->Frequency/100, mDevice->Frequency/100*5)};
- device->UpdateSize = update_len;
- device->NumUpdates = (length+update_len-1) / update_len;
+ mDevice->UpdateSize = update_len;
+ mDevice->NumUpdates = (length+update_len-1) / update_len;
- self->mFrameSize = device->frameSizeFromFmt();
+ mFrameSize = mDevice->frameSizeFromFmt();
}
loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT;
@@ -764,27 +716,27 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
audioSrc.pFormat = NULL;
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- loc_bq.numBuffers = device->NumUpdates;
+ loc_bq.numBuffers = mDevice->NumUpdates;
#ifdef SL_DATAFORMAT_PCM_EX
SLDataFormat_PCM_EX format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.sampleRate = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.sampleRate = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
- format_pcm.representation = GetTypeRepresentation(device->FmtType);
+ format_pcm.representation = GetTypeRepresentation(mDevice->FmtType);
#else
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.samplesPerSec = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.samplesPerSec = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
#endif
@@ -797,23 +749,21 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
const SLboolean reqs[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE };
- result = VCALL(self->mEngine,CreateAudioRecorder)(&self->mRecordObj,
- &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
- );
+ result = VCALL(mEngine,CreateAudioRecorder)(&mRecordObj, &audioSrc, &audioSnk,
+ COUNTOF(ids), ids, reqs);
PRINTERR(result, "engine->CreateAudioRecorder");
}
if(SL_RESULT_SUCCESS == result)
{
/* Set the record preset to "generic", if possible. */
SLAndroidConfigurationItf config;
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
PRINTERR(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
if(SL_RESULT_SUCCESS == result)
{
SLuint32 preset = SL_ANDROID_RECORDING_PRESET_GENERIC;
- result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET,
- &preset, sizeof(preset)
- );
+ result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET, &preset,
+ sizeof(preset));
PRINTERR(result, "config->SetConfiguration");
}
@@ -822,31 +772,28 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mRecordObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mRecordObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "recordObj->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = CreateRingBuffer(device->NumUpdates,
- device->UpdateSize*self->mFrameSize, false);
+ mRing = CreateRingBuffer(mDevice->NumUpdates, mDevice->UpdateSize*mFrameSize, false);
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(bufferQueue,RegisterCallback)(&ALCopenslCapture::processC, self);
+ result = VCALL(bufferQueue,RegisterCallback)(&OpenSLCapture::processC, this);
PRINTERR(result, "bufferQueue->RegisterCallback");
}
if(SL_RESULT_SUCCESS == result)
{
- RingBuffer *ring{self->mRing.get()};
- ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
+ ALsizei chunk_size = mDevice->UpdateSize * mFrameSize;
size_t i;
- auto data = ring->getWriteVector();
+ auto data = mRing->getWriteVector();
for(i = 0;i < data.first.len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data.first.buf + chunk_size*i, chunk_size);
@@ -861,28 +808,26 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
if(SL_RESULT_SUCCESS != result)
{
- if(self->mRecordObj != NULL)
- VCALL0(self->mRecordObj,Destroy)();
- self->mRecordObj = NULL;
+ if(mRecordObj)
+ VCALL0(mRecordObj,Destroy)();
+ mRecordObj = nullptr;
- if(self->mEngineObj != NULL)
- VCALL0(self->mEngineObj,Destroy)();
- self->mEngineObj = NULL;
- self->mEngine = NULL;
+ if(mEngineObj)
+ VCALL0(mEngineObj,Destroy)();
+ mEngineObj = nullptr;
+ mEngine = nullptr;
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self)
+ALCboolean OpenSLCapture::start()
{
SLRecordItf record;
- SLresult result;
-
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
+ SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
PRINTERR(result, "recordObj->GetInterface");
if(SL_RESULT_SUCCESS == result)
@@ -893,21 +838,19 @@ static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self)
if(SL_RESULT_SUCCESS != result)
{
- ALCopenslCapture_lock(self);
- aluHandleDisconnect(self->mDevice, "Failed to start capture: 0x%08x", result);
- ALCopenslCapture_unlock(self);
+ lock();
+ aluHandleDisconnect(mDevice, "Failed to start capture: 0x%08x", result);
+ unlock();
return ALC_FALSE;
}
return ALC_TRUE;
}
-static void ALCopenslCapture_stop(ALCopenslCapture *self)
+void OpenSLCapture::stop()
{
SLRecordItf record;
- SLresult result;
-
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
+ SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
PRINTERR(result, "recordObj->GetInterface");
if(SL_RESULT_SUCCESS == result)
@@ -917,37 +860,33 @@ static void ALCopenslCapture_stop(ALCopenslCapture *self)
}
}
-static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum OpenSLCapture::captureSamples(void* buffer, ALCuint samples)
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
- ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
+ ALsizei chunk_size = mDevice->UpdateSize * mFrameSize;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLresult result;
ALCuint i;
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
/* Read the desired samples from the ring buffer then advance its read
* pointer.
*/
- auto data = ring->getReadVector();
+ auto data = mRing->getReadVector();
for(i = 0;i < samples;)
{
- ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
- memcpy((ALCbyte*)buffer + i*self->mFrameSize,
- data.first.buf + self->mSplOffset*self->mFrameSize,
- rem * self->mFrameSize);
+ ALCuint rem{minu(samples - i, mDevice->UpdateSize - mSplOffset)};
+ memcpy((ALCbyte*)buffer + i*mFrameSize, data.first.buf + mSplOffset*mFrameSize,
+ rem * mFrameSize);
- self->mSplOffset += rem;
- if(self->mSplOffset == device->UpdateSize)
+ mSplOffset += rem;
+ if(mSplOffset == mDevice->UpdateSize)
{
/* Finished a chunk, reset the offset and advance the read pointer. */
- self->mSplOffset = 0;
+ mSplOffset = 0;
- ring->readAdvance(1);
+ mRing->readAdvance(1);
result = VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS != result) break;
@@ -964,21 +903,17 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
if(SL_RESULT_SUCCESS != result)
{
- ALCopenslCapture_lock(self);
- aluHandleDisconnect(device, "Failed to update capture buffer: 0x%08x", result);
- ALCopenslCapture_unlock(self);
+ lock();
+ aluHandleDisconnect(mDevice, "Failed to update capture buffer: 0x%08x", result);
+ unlock();
return ALC_INVALID_DEVICE;
}
return ALC_NO_ERROR;
}
-static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self)
-{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
- return ring->readSpace() * device->UpdateSize;
-}
+ALCuint OpenSLCapture::availableSamples()
+{ return mRing->readSpace()*mDevice->UpdateSize - mSplOffset; }
} // namespace
@@ -999,21 +934,12 @@ void OSLBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *OSLBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *OSLBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCopenslPlayback *backend;
- NEW_OBJ(backend, ALCopenslPlayback)(device);
- return backend;
- }
+ return new OpenSLPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCopenslCapture *backend;
- NEW_OBJ(backend, ALCopenslCapture)(device);
- return backend;
- }
-
+ return new OpenSLCapture{device};
return nullptr;
}
diff --git a/Alc/backends/opensl.h b/Alc/backends/opensl.h
index 31d0caae..bab15115 100644
--- a/Alc/backends/opensl.h
+++ b/Alc/backends/opensl.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/oss.cpp b/Alc/backends/oss.cpp
index 54d7e0af..c2139d4d 100644
--- a/Alc/backends/oss.cpp
+++ b/Alc/backends/oss.cpp
@@ -241,45 +241,29 @@ int log2i(ALCuint x)
}
-struct ALCplaybackOSS final : public ALCbackend {
- ALCplaybackOSS(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCplaybackOSS() override;
+struct OSSPlayback final : public BackendBase {
+ OSSPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OSSPlayback() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
int mFd{-1};
al::vector<ALubyte> mMixData;
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device);
-void ALCplaybackOSS_Destruct(ALCplaybackOSS *self);
-ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name);
-ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self);
-ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self);
-void ALCplaybackOSS_stop(ALCplaybackOSS *self);
-DECLARE_FORWARD2(ALCplaybackOSS, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
-DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCplaybackOSS)
-DEFINE_ALCBACKEND_VTABLE(ALCplaybackOSS);
-
-
-void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device)
-{
- new (self) ALCplaybackOSS{device};
- SET_VTABLE2(ALCplaybackOSS, ALCbackend, self);
-}
-void ALCplaybackOSS_Destruct(ALCplaybackOSS *self)
-{ self->~ALCplaybackOSS(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OSSPlayback::"; }
+ DEF_NEWDEL(OSSPlayback)
+};
-ALCplaybackOSS::~ALCplaybackOSS()
+OSSPlayback::~OSSPlayback()
{
if(mFd != -1)
close(mFd);
@@ -287,14 +271,14 @@ ALCplaybackOSS::~ALCplaybackOSS()
}
-int ALCplaybackOSS::mixerProc()
+int OSSPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
const int frame_size{mDevice->frameSizeFromFmt()};
- ALCplaybackOSS_lock(this);
+ lock();
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
{
@@ -302,9 +286,9 @@ int ALCplaybackOSS::mixerProc()
pollitem.fd = mFd;
pollitem.events = POLLOUT;
- ALCplaybackOSS_unlock(this);
+ unlock();
int pret{poll(&pollitem, 1, 1000)};
- ALCplaybackOSS_lock(this);
+ lock();
if(pret < 0)
{
if(errno == EINTR || errno == EAGAIN)
@@ -339,16 +323,14 @@ int ALCplaybackOSS::mixerProc()
write_ptr += wrote;
}
}
- ALCplaybackOSS_unlock(this);
+ unlock();
return 0;
}
-ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name)
+ALCenum OSSPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
const char *devname{DefaultPlayback};
if(!name)
name = DefaultName;
@@ -366,20 +348,19 @@ ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name)
devname = iter->device_name.c_str();
}
- self->mFd = open(devname, O_WRONLY);
- if(self->mFd == -1)
+ mFd = ::open(devname, O_WRONLY);
+ if(mFd == -1)
{
ERR("Could not open %s: %s\n", devname, strerror(errno));
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
+ALCboolean OSSPlayback::reset()
{
- ALCdevice *device{self->mDevice};
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
@@ -390,7 +371,7 @@ ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
int ossSpeed;
const char *err;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
ossFormat = AFMT_S8;
@@ -402,19 +383,19 @@ ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
ossFormat = AFMT_S16_NE;
break;
}
- periods = device->NumUpdates;
- numChannels = device->channelsFromFmt();
- ossSpeed = device->Frequency;
- frameSize = numChannels * device->bytesFromFmt();
+ periods = mDevice->NumUpdates;
+ numChannels = mDevice->channelsFromFmt();
+ ossSpeed = mDevice->Frequency;
+ frameSize = numChannels * mDevice->bytesFromFmt();
/* According to the OSS spec, 16 bytes (log2(16)) is the minimum. */
- log2FragmentSize = maxi(log2i(device->UpdateSize*frameSize), 4);
+ log2FragmentSize = maxi(log2i(mDevice->UpdateSize*frameSize), 4);
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
#define CHECKERR(func) if((func) < 0) { \
@@ -423,11 +404,11 @@ ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
}
/* Don't fail if SETFRAGMENT fails. We can handle just about anything
* that's reported back via GETOSPACE */
- ioctl(self->mFd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_SETFMT, &ossFormat));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_CHANNELS, &numChannels));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_SPEED, &ossSpeed));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_GETOSPACE, &info));
+ ioctl(mFd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_SETFMT, &ossFormat));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_CHANNELS, &numChannels));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_SPEED, &ossSpeed));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_GETOSPACE, &info));
if(0)
{
err:
@@ -436,38 +417,38 @@ ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
}
#undef CHECKERR
- if(device->channelsFromFmt() != numChannels)
+ if(mDevice->channelsFromFmt() != numChannels)
{
- ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels);
+ ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(mDevice->FmtChans),
+ numChannels);
return ALC_FALSE;
}
- if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
- (ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
- (ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
+ if(!((ossFormat == AFMT_S8 && mDevice->FmtType == DevFmtByte) ||
+ (ossFormat == AFMT_U8 && mDevice->FmtType == DevFmtUByte) ||
+ (ossFormat == AFMT_S16_NE && mDevice->FmtType == DevFmtShort)))
{
- ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat);
+ ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(mDevice->FmtType),
+ ossFormat);
return ALC_FALSE;
}
- device->Frequency = ossSpeed;
- device->UpdateSize = info.fragsize / frameSize;
- device->NumUpdates = info.fragments;
+ mDevice->Frequency = ossSpeed;
+ mDevice->UpdateSize = info.fragsize / frameSize;
+ mDevice->NumUpdates = info.fragments;
+
+ SetDefaultChannelOrder(mDevice);
- SetDefaultChannelOrder(device);
+ mMixData.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
return ALC_TRUE;
}
-ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self)
+ALCboolean OSSPlayback::start()
{
- ALCdevice *device{self->mDevice};
-
try {
- self->mMixData.resize(device->UpdateSize * device->frameSizeFromFmt());
-
- self->mKillNow.store(AL_FALSE);
- self->mThread = std::thread{std::mem_fn(&ALCplaybackOSS::mixerProc), self};
+ mKillNow.store(AL_FALSE);
+ mThread = std::thread{std::mem_fn(&OSSPlayback::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -478,58 +459,41 @@ ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self)
return ALC_FALSE;
}
-void ALCplaybackOSS_stop(ALCplaybackOSS *self)
+void OSSPlayback::stop()
{
- if(self->mKillNow.exchange(AL_TRUE) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
- if(ioctl(self->mFd, SNDCTL_DSP_RESET) != 0)
+ if(ioctl(mFd, SNDCTL_DSP_RESET) != 0)
ERR("Error resetting device: %s\n", strerror(errno));
-
- self->mMixData.clear();
}
-struct ALCcaptureOSS final : public ALCbackend {
- ALCcaptureOSS(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCcaptureOSS() override;
+struct OSScapture final : public BackendBase {
+ OSScapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OSScapture() override;
int recordProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(ALCvoid *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
int mFd{-1};
RingBufferPtr mRing{nullptr};
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device);
-void ALCcaptureOSS_Destruct(ALCcaptureOSS *self);
-ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name);
-DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALCboolean, reset)
-ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self);
-void ALCcaptureOSS_stop(ALCcaptureOSS *self);
-ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples);
-ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self);
-DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCcaptureOSS)
-DEFINE_ALCBACKEND_VTABLE(ALCcaptureOSS);
-
-
-void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device)
-{
- new (self) ALCcaptureOSS{device};
- SET_VTABLE2(ALCcaptureOSS, ALCbackend, self);
-}
-void ALCcaptureOSS_Destruct(ALCcaptureOSS *self)
-{ self->~ALCcaptureOSS(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OSScapture::"; }
+ DEF_NEWDEL(OSScapture)
+};
-ALCcaptureOSS::~ALCcaptureOSS()
+OSScapture::~OSScapture()
{
if(mFd != -1)
close(mFd);
@@ -537,7 +501,7 @@ ALCcaptureOSS::~ALCcaptureOSS()
}
-int ALCcaptureOSS::recordProc()
+int OSScapture::recordProc()
{
SetRTPriority();
althrd_setname(RECORD_THREAD_NAME);
@@ -555,7 +519,9 @@ int ALCcaptureOSS::recordProc()
if(errno == EINTR || errno == EAGAIN)
continue;
ERR("poll failed: %s\n", strerror(errno));
+ lock();
aluHandleDisconnect(mDevice, "Failed to check capture samples: %s", strerror(errno));
+ unlock();
break;
}
else if(sret == 0)
@@ -571,10 +537,10 @@ int ALCcaptureOSS::recordProc()
if(amt < 0)
{
ERR("read failed: %s\n", strerror(errno));
- ALCcaptureOSS_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed reading capture samples: %s",
strerror(errno));
- ALCcaptureOSS_unlock(this);
+ unlock();
break;
}
mRing->writeAdvance(amt/frame_size);
@@ -585,10 +551,8 @@ int ALCcaptureOSS::recordProc()
}
-ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
+ALCenum OSScapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
const char *devname{DefaultCapture};
if(!name)
name = DefaultName;
@@ -606,15 +570,15 @@ ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
devname = iter->device_name.c_str();
}
- self->mFd = open(devname, O_RDONLY);
- if(self->mFd == -1)
+ mFd = ::open(devname, O_RDONLY);
+ if(mFd == -1)
{
ERR("Could not open %s: %s\n", devname, strerror(errno));
return ALC_INVALID_VALUE;
}
int ossFormat{};
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
ossFormat = AFMT_S8;
@@ -629,15 +593,15 @@ ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
- ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
+ ERR("%s capture samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_VALUE;
}
int periods{4};
- int numChannels{device->channelsFromFmt()};
- int frameSize{numChannels * device->bytesFromFmt()};
- int ossSpeed{static_cast<int>(device->Frequency)};
- int log2FragmentSize{log2i(device->UpdateSize * device->NumUpdates *
+ int numChannels{mDevice->channelsFromFmt()};
+ int frameSize{numChannels * mDevice->bytesFromFmt()};
+ int ossSpeed{static_cast<int>(mDevice->Frequency)};
+ int log2FragmentSize{log2i(mDevice->UpdateSize * mDevice->NumUpdates *
frameSize / periods)};
/* according to the OSS spec, 16 bytes are the minimum */
@@ -650,57 +614,58 @@ ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
err = #func; \
goto err; \
}
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_SETFMT, &ossFormat));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_CHANNELS, &numChannels));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_SPEED, &ossSpeed));
- CHECKERR(ioctl(self->mFd, SNDCTL_DSP_GETISPACE, &info));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_SETFMT, &ossFormat));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_CHANNELS, &numChannels));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_SPEED, &ossSpeed));
+ CHECKERR(ioctl(mFd, SNDCTL_DSP_GETISPACE, &info));
if(0)
{
err:
ERR("%s failed: %s\n", err, strerror(errno));
- close(self->mFd);
- self->mFd = -1;
+ close(mFd);
+ mFd = -1;
return ALC_INVALID_VALUE;
}
#undef CHECKERR
- if(device->channelsFromFmt() != numChannels)
+ if(mDevice->channelsFromFmt() != numChannels)
{
- ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels);
- close(self->mFd);
- self->mFd = -1;
+ ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(mDevice->FmtChans),
+ numChannels);
+ close(mFd);
+ mFd = -1;
return ALC_INVALID_VALUE;
}
- if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
- (ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
- (ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
+ if(!((ossFormat == AFMT_S8 && mDevice->FmtType == DevFmtByte) ||
+ (ossFormat == AFMT_U8 && mDevice->FmtType == DevFmtUByte) ||
+ (ossFormat == AFMT_S16_NE && mDevice->FmtType == DevFmtShort)))
{
- ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat);
- close(self->mFd);
- self->mFd = -1;
+ ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(mDevice->FmtType), ossFormat);
+ close(mFd);
+ mFd = -1;
return ALC_INVALID_VALUE;
}
- self->mRing = CreateRingBuffer(device->UpdateSize*device->NumUpdates, frameSize, false);
- if(!self->mRing)
+ mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates, frameSize, false);
+ if(!mRing)
{
ERR("Ring buffer create failed\n");
- close(self->mFd);
- self->mFd = -1;
+ close(mFd);
+ mFd = -1;
return ALC_OUT_OF_MEMORY;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self)
+ALCboolean OSScapture::start()
{
try {
- self->mKillNow.store(AL_FALSE);
- self->mThread = std::thread{std::mem_fn(&ALCcaptureOSS::recordProc), self};
+ mKillNow.store(AL_FALSE);
+ mThread = std::thread{std::mem_fn(&OSScapture::recordProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -711,29 +676,24 @@ ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self)
return ALC_FALSE;
}
-void ALCcaptureOSS_stop(ALCcaptureOSS *self)
+void OSScapture::stop()
{
- if(self->mKillNow.exchange(AL_TRUE) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE) || !mThread.joinable())
return;
+ mThread.join();
- self->mThread.join();
-
- if(ioctl(self->mFd, SNDCTL_DSP_RESET) != 0)
+ if(ioctl(mFd, SNDCTL_DSP_RESET) != 0)
ERR("Error resetting device: %s\n", strerror(errno));
}
-ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples)
+ALCenum OSScapture::captureSamples(ALCvoid *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
-ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self)
-{
- RingBuffer *ring{self->mRing.get()};
- return ring->readSpace();
-}
+ALCuint OSScapture::availableSamples()
+{ return mRing->readSpace(); }
} // namespace
@@ -791,20 +751,11 @@ void OSSBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *OSSBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *OSSBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCplaybackOSS *backend;
- NEW_OBJ(backend, ALCplaybackOSS)(device);
- return backend;
- }
+ return new OSSPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCcaptureOSS *backend;
- NEW_OBJ(backend, ALCcaptureOSS)(device);
- return backend;
- }
-
+ return new OSScapture{device};
return nullptr;
}
diff --git a/Alc/backends/oss.h b/Alc/backends/oss.h
index 4652a779..8f65f1cc 100644
--- a/Alc/backends/oss.h
+++ b/Alc/backends/oss.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/portaudio.cpp b/Alc/backends/portaudio.cpp
index 44ffd9bd..34688db9 100644
--- a/Alc/backends/portaudio.cpp
+++ b/Alc/backends/portaudio.cpp
@@ -130,9 +130,9 @@ bool pa_load(void)
}
-struct ALCportPlayback final : public ALCbackend {
- ALCportPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCportPlayback() override;
+struct PortPlayback final : public BackendBase {
+ PortPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~PortPlayback() override;
static int writeCallbackC(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
@@ -140,37 +140,20 @@ struct ALCportPlayback final : public ALCbackend {
int writeCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
PaStream *mStream{nullptr};
PaStreamParameters mParams{};
ALuint mUpdateSize{0u};
-};
-
-void ALCportPlayback_Construct(ALCportPlayback *self, ALCdevice *device);
-void ALCportPlayback_Destruct(ALCportPlayback *self);
-ALCenum ALCportPlayback_open(ALCportPlayback *self, const ALCchar *name);
-ALCboolean ALCportPlayback_reset(ALCportPlayback *self);
-ALCboolean ALCportPlayback_start(ALCportPlayback *self);
-void ALCportPlayback_stop(ALCportPlayback *self);
-DECLARE_FORWARD2(ALCportPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
-DECLARE_FORWARD(ALCportPlayback, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCportPlayback, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCportPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCportPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCportPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(ALCportPlayback);
-
-
-void ALCportPlayback_Construct(ALCportPlayback *self, ALCdevice *device)
-{
- new (self) ALCportPlayback{device};
- SET_VTABLE2(ALCportPlayback, ALCbackend, self);
-}
-void ALCportPlayback_Destruct(ALCportPlayback *self)
-{ self->~ALCportPlayback(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "PortPlayback::"; }
+ DEF_NEWDEL(PortPlayback)
+};
-ALCportPlayback::~ALCportPlayback()
+PortPlayback::~PortPlayback()
{
PaError err{mStream ? Pa_CloseStream(mStream) : paNoError};
if(err != paNoError)
@@ -179,132 +162,124 @@ ALCportPlayback::~ALCportPlayback()
}
-int ALCportPlayback::writeCallbackC(const void *inputBuffer, void *outputBuffer,
+int PortPlayback::writeCallbackC(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
const PaStreamCallbackFlags statusFlags, void *userData)
{
- return static_cast<ALCportPlayback*>(userData)->writeCallback(inputBuffer, outputBuffer,
+ return static_cast<PortPlayback*>(userData)->writeCallback(inputBuffer, outputBuffer,
framesPerBuffer, timeInfo, statusFlags);
}
-int ALCportPlayback::writeCallback(const void* UNUSED(inputBuffer), void *outputBuffer,
+int PortPlayback::writeCallback(const void* UNUSED(inputBuffer), void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* UNUSED(timeInfo),
const PaStreamCallbackFlags UNUSED(statusFlags))
{
- ALCportPlayback_lock(this);
+ lock();
aluMixData(mDevice, outputBuffer, framesPerBuffer);
- ALCportPlayback_unlock(this);
+ unlock();
return 0;
}
-ALCenum ALCportPlayback_open(ALCportPlayback *self, const ALCchar *name)
+ALCenum PortPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
- PaError err;
-
if(!name)
name = pa_device;
else if(strcmp(name, pa_device) != 0)
return ALC_INVALID_VALUE;
- self->mUpdateSize = device->UpdateSize;
+ mUpdateSize = mDevice->UpdateSize;
- self->mParams.device = -1;
- if(!ConfigValueInt(nullptr, "port", "device", &self->mParams.device) ||
- self->mParams.device < 0)
- self->mParams.device = Pa_GetDefaultOutputDevice();
- self->mParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
- (float)device->Frequency;
- self->mParams.hostApiSpecificStreamInfo = nullptr;
+ mParams.device = -1;
+ if(!ConfigValueInt(nullptr, "port", "device", &mParams.device) || mParams.device < 0)
+ mParams.device = Pa_GetDefaultOutputDevice();
+ mParams.suggestedLatency = (mDevice->UpdateSize*mDevice->NumUpdates) /
+ (float)mDevice->Frequency;
+ mParams.hostApiSpecificStreamInfo = nullptr;
- self->mParams.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2);
+ mParams.channelCount = ((mDevice->FmtChans == DevFmtMono) ? 1 : 2);
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
- self->mParams.sampleFormat = paInt8;
+ mParams.sampleFormat = paInt8;
break;
case DevFmtUByte:
- self->mParams.sampleFormat = paUInt8;
+ mParams.sampleFormat = paUInt8;
break;
case DevFmtUShort:
/* fall-through */
case DevFmtShort:
- self->mParams.sampleFormat = paInt16;
+ mParams.sampleFormat = paInt16;
break;
case DevFmtUInt:
/* fall-through */
case DevFmtInt:
- self->mParams.sampleFormat = paInt32;
+ mParams.sampleFormat = paInt32;
break;
case DevFmtFloat:
- self->mParams.sampleFormat = paFloat32;
+ mParams.sampleFormat = paFloat32;
break;
}
retry_open:
- err = Pa_OpenStream(&self->mStream, nullptr, &self->mParams,
- device->Frequency, device->UpdateSize, paNoFlag,
- &ALCportPlayback::writeCallbackC, self
- );
+ PaError err{Pa_OpenStream(&mStream, nullptr, &mParams, mDevice->Frequency, mDevice->UpdateSize,
+ paNoFlag, &PortPlayback::writeCallbackC, this)};
if(err != paNoError)
{
- if(self->mParams.sampleFormat == paFloat32)
+ if(mParams.sampleFormat == paFloat32)
{
- self->mParams.sampleFormat = paInt16;
+ mParams.sampleFormat = paInt16;
goto retry_open;
}
ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCportPlayback_reset(ALCportPlayback *self)
+ALCboolean PortPlayback::reset()
{
- ALCdevice *device{self->mDevice};
-
- const PaStreamInfo *streamInfo{Pa_GetStreamInfo(self->mStream)};
- device->Frequency = streamInfo->sampleRate;
- device->UpdateSize = self->mUpdateSize;
-
- if(self->mParams.sampleFormat == paInt8)
- device->FmtType = DevFmtByte;
- else if(self->mParams.sampleFormat == paUInt8)
- device->FmtType = DevFmtUByte;
- else if(self->mParams.sampleFormat == paInt16)
- device->FmtType = DevFmtShort;
- else if(self->mParams.sampleFormat == paInt32)
- device->FmtType = DevFmtInt;
- else if(self->mParams.sampleFormat == paFloat32)
- device->FmtType = DevFmtFloat;
+ const PaStreamInfo *streamInfo{Pa_GetStreamInfo(mStream)};
+ mDevice->Frequency = streamInfo->sampleRate;
+ mDevice->UpdateSize = mUpdateSize;
+
+ if(mParams.sampleFormat == paInt8)
+ mDevice->FmtType = DevFmtByte;
+ else if(mParams.sampleFormat == paUInt8)
+ mDevice->FmtType = DevFmtUByte;
+ else if(mParams.sampleFormat == paInt16)
+ mDevice->FmtType = DevFmtShort;
+ else if(mParams.sampleFormat == paInt32)
+ mDevice->FmtType = DevFmtInt;
+ else if(mParams.sampleFormat == paFloat32)
+ mDevice->FmtType = DevFmtFloat;
else
{
- ERR("Unexpected sample format: 0x%lx\n", self->mParams.sampleFormat);
+ ERR("Unexpected sample format: 0x%lx\n", mParams.sampleFormat);
return ALC_FALSE;
}
- if(self->mParams.channelCount == 2)
- device->FmtChans = DevFmtStereo;
- else if(self->mParams.channelCount == 1)
- device->FmtChans = DevFmtMono;
+ if(mParams.channelCount == 2)
+ mDevice->FmtChans = DevFmtStereo;
+ else if(mParams.channelCount == 1)
+ mDevice->FmtChans = DevFmtMono;
else
{
- ERR("Unexpected channel count: %u\n", self->mParams.channelCount);
+ ERR("Unexpected channel count: %u\n", mParams.channelCount);
return ALC_FALSE;
}
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCportPlayback_start(ALCportPlayback *self)
+ALCboolean PortPlayback::start()
{
- PaError err{Pa_StartStream(self->mStream)};
+ PaError err{Pa_StartStream(mStream)};
if(err != paNoError)
{
ERR("Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err));
@@ -313,17 +288,17 @@ ALCboolean ALCportPlayback_start(ALCportPlayback *self)
return ALC_TRUE;
}
-void ALCportPlayback_stop(ALCportPlayback *self)
+void PortPlayback::stop()
{
- PaError err{Pa_StopStream(self->mStream)};
+ PaError err{Pa_StopStream(mStream)};
if(err != paNoError)
ERR("Error stopping stream: %s\n", Pa_GetErrorText(err));
}
-struct ALCportCapture final : public ALCbackend {
- ALCportCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCportCapture() override;
+struct PortCapture final : public BackendBase {
+ PortCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~PortCapture() override;
static int readCallbackC(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
@@ -331,38 +306,22 @@ struct ALCportCapture final : public ALCbackend {
int readCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(ALCvoid *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
PaStream *mStream{nullptr};
PaStreamParameters mParams;
RingBufferPtr mRing{nullptr};
-};
-
-void ALCportCapture_Construct(ALCportCapture *self, ALCdevice *device);
-void ALCportCapture_Destruct(ALCportCapture *self);
-ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name);
-DECLARE_FORWARD(ALCportCapture, ALCbackend, ALCboolean, reset)
-ALCboolean ALCportCapture_start(ALCportCapture *self);
-void ALCportCapture_stop(ALCportCapture *self);
-ALCenum ALCportCapture_captureSamples(ALCportCapture *self, ALCvoid *buffer, ALCuint samples);
-ALCuint ALCportCapture_availableSamples(ALCportCapture *self);
-DECLARE_FORWARD(ALCportCapture, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(ALCportCapture, ALCbackend, void, lock)
-DECLARE_FORWARD(ALCportCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCportCapture)
-
-DEFINE_ALCBACKEND_VTABLE(ALCportCapture);
+ static constexpr inline const char *CurrentPrefix() noexcept { return "PortCapture::"; }
+ DEF_NEWDEL(PortCapture)
+};
-void ALCportCapture_Construct(ALCportCapture *self, ALCdevice *device)
-{
- new (self) ALCportCapture{device};
- SET_VTABLE2(ALCportCapture, ALCbackend, self);
-}
-
-void ALCportCapture_Destruct(ALCportCapture *self)
-{ self->~ALCportCapture(); }
-
-ALCportCapture::~ALCportCapture()
+PortCapture::~PortCapture()
{
PaError err{mStream ? Pa_CloseStream(mStream) : paNoError};
if(err != paNoError)
@@ -371,15 +330,15 @@ ALCportCapture::~ALCportCapture()
}
-int ALCportCapture::readCallbackC(const void *inputBuffer, void *outputBuffer,
+int PortCapture::readCallbackC(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
const PaStreamCallbackFlags statusFlags, void* userData)
{
- return static_cast<ALCportCapture*>(userData)->readCallback(inputBuffer, outputBuffer,
+ return static_cast<PortCapture*>(userData)->readCallback(inputBuffer, outputBuffer,
framesPerBuffer, timeInfo, statusFlags);
}
-int ALCportCapture::readCallback(const void *inputBuffer, void *UNUSED(outputBuffer),
+int PortCapture::readCallback(const void *inputBuffer, void *UNUSED(outputBuffer),
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo),
const PaStreamCallbackFlags UNUSED(statusFlags))
{
@@ -388,73 +347,66 @@ int ALCportCapture::readCallback(const void *inputBuffer, void *UNUSED(outputBuf
}
-ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
+ALCenum PortCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
- ALuint samples, frame_size;
- PaError err;
-
if(!name)
name = pa_device;
else if(strcmp(name, pa_device) != 0)
return ALC_INVALID_VALUE;
- samples = device->UpdateSize * device->NumUpdates;
- samples = maxu(samples, 100 * device->Frequency / 1000);
- frame_size = device->frameSizeFromFmt();
+ ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
+ samples = maxu(samples, 100 * mDevice->Frequency / 1000);
+ ALsizei frame_size{mDevice->frameSizeFromFmt()};
- self->mRing = CreateRingBuffer(samples, frame_size, false);
- if(!self->mRing) return ALC_INVALID_VALUE;
+ mRing = CreateRingBuffer(samples, frame_size, false);
+ if(!mRing) return ALC_INVALID_VALUE;
- self->mParams.device = -1;
- if(!ConfigValueInt(nullptr, "port", "capture", &self->mParams.device) ||
- self->mParams.device < 0)
- self->mParams.device = Pa_GetDefaultInputDevice();
- self->mParams.suggestedLatency = 0.0f;
- self->mParams.hostApiSpecificStreamInfo = nullptr;
+ mParams.device = -1;
+ if(!ConfigValueInt(nullptr, "port", "capture", &mParams.device) || mParams.device < 0)
+ mParams.device = Pa_GetDefaultInputDevice();
+ mParams.suggestedLatency = 0.0f;
+ mParams.hostApiSpecificStreamInfo = nullptr;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
- self->mParams.sampleFormat = paInt8;
+ mParams.sampleFormat = paInt8;
break;
case DevFmtUByte:
- self->mParams.sampleFormat = paUInt8;
+ mParams.sampleFormat = paUInt8;
break;
case DevFmtShort:
- self->mParams.sampleFormat = paInt16;
+ mParams.sampleFormat = paInt16;
break;
case DevFmtInt:
- self->mParams.sampleFormat = paInt32;
+ mParams.sampleFormat = paInt32;
break;
case DevFmtFloat:
- self->mParams.sampleFormat = paFloat32;
+ mParams.sampleFormat = paFloat32;
break;
case DevFmtUInt:
case DevFmtUShort:
- ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
+ ERR("%s samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_VALUE;
}
- self->mParams.channelCount = device->channelsFromFmt();
+ mParams.channelCount = mDevice->channelsFromFmt();
- err = Pa_OpenStream(&self->mStream, &self->mParams, nullptr,
- device->Frequency, paFramesPerBufferUnspecified, paNoFlag,
- &ALCportCapture::readCallbackC, self
- );
+ PaError err{Pa_OpenStream(&mStream, &mParams, nullptr, mDevice->Frequency,
+ paFramesPerBufferUnspecified, paNoFlag, &PortCapture::readCallbackC, this)};
if(err != paNoError)
{
ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean ALCportCapture_start(ALCportCapture *self)
+ALCboolean PortCapture::start()
{
- PaError err = Pa_StartStream(self->mStream);
+ PaError err{Pa_StartStream(mStream)};
if(err != paNoError)
{
ERR("Error starting stream: %s\n", Pa_GetErrorText(err));
@@ -463,24 +415,20 @@ ALCboolean ALCportCapture_start(ALCportCapture *self)
return ALC_TRUE;
}
-void ALCportCapture_stop(ALCportCapture *self)
+void PortCapture::stop()
{
- PaError err = Pa_StopStream(self->mStream);
+ PaError err{Pa_StopStream(mStream)};
if(err != paNoError)
ERR("Error stopping stream: %s\n", Pa_GetErrorText(err));
}
-ALCuint ALCportCapture_availableSamples(ALCportCapture *self)
-{
- RingBuffer *ring{self->mRing.get()};
- return ring->readSpace();
-}
+ALCuint PortCapture::availableSamples()
+{ return mRing->readSpace(); }
-ALCenum ALCportCapture_captureSamples(ALCportCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum PortCapture::captureSamples(ALCvoid *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
@@ -519,21 +467,12 @@ void PortBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *PortBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *PortBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCportPlayback *backend;
- NEW_OBJ(backend, ALCportPlayback)(device);
- return backend;
- }
+ return new PortPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCportCapture *backend;
- NEW_OBJ(backend, ALCportCapture)(device);
- return backend;
- }
-
+ return new PortCapture{device};
return nullptr;
}
diff --git a/Alc/backends/portaudio.h b/Alc/backends/portaudio.h
index 581d4901..7687c6b3 100644
--- a/Alc/backends/portaudio.h
+++ b/Alc/backends/portaudio.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/pulseaudio.cpp b/Alc/backends/pulseaudio.cpp
index a99503e1..c911e365 100644
--- a/Alc/backends/pulseaudio.cpp
+++ b/Alc/backends/pulseaudio.cpp
@@ -729,8 +729,8 @@ void probeCaptureDevices(void)
}
-struct PulsePlayback final : public ALCbackend {
- PulsePlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct PulsePlayback final : public BackendBase {
+ PulsePlayback(ALCdevice *device) noexcept : BackendBase{device} { }
~PulsePlayback() override;
static void bufferAttrCallbackC(pa_stream *stream, void *pdata);
@@ -754,6 +754,14 @@ struct PulsePlayback final : public ALCbackend {
static void streamMovedCallbackC(pa_stream *stream, void *pdata);
void streamMovedCallback(pa_stream *stream);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+ ClockLatency getClockLatency() override;
+ void lock() noexcept override;
+ void unlock() noexcept override;
+
std::string mDeviceName;
pa_buffer_attr mAttr;
@@ -768,33 +776,9 @@ struct PulsePlayback final : public ALCbackend {
ALuint mFrameSize{0u};
static constexpr inline const char *CurrentPrefix() noexcept { return "PulsePlayback::"; }
+ DEF_NEWDEL(PulsePlayback)
};
-void PulsePlayback_Construct(PulsePlayback *self, ALCdevice *device);
-void PulsePlayback_Destruct(PulsePlayback *self);
-ALCenum PulsePlayback_open(PulsePlayback *self, const ALCchar *name);
-ALCboolean PulsePlayback_reset(PulsePlayback *self);
-ALCboolean PulsePlayback_start(PulsePlayback *self);
-void PulsePlayback_stop(PulsePlayback *self);
-DECLARE_FORWARD2(PulsePlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
-DECLARE_FORWARD(PulsePlayback, ALCbackend, ALCuint, availableSamples)
-ClockLatency PulsePlayback_getClockLatency(PulsePlayback *self);
-void PulsePlayback_lock(PulsePlayback *self);
-void PulsePlayback_unlock(PulsePlayback *self);
-DECLARE_DEFAULT_ALLOCATORS(PulsePlayback)
-
-DEFINE_ALCBACKEND_VTABLE(PulsePlayback);
-
-
-void PulsePlayback_Construct(PulsePlayback *self, ALCdevice *device)
-{
- new (self) PulsePlayback{device};
- SET_VTABLE2(PulsePlayback, ALCbackend, self);
-}
-
-void PulsePlayback_Destruct(PulsePlayback *self)
-{ self->~PulsePlayback(); }
-
PulsePlayback::~PulsePlayback()
{
if(!mLoop)
@@ -960,7 +944,7 @@ void PulsePlayback::streamMovedCallback(pa_stream *stream)
}
-ALCenum PulsePlayback_open(PulsePlayback *self, const ALCchar *name)
+ALCenum PulsePlayback::open(const ALCchar *name)
{
const char *pulse_name{nullptr};
const char *dev_name{nullptr};
@@ -980,10 +964,10 @@ ALCenum PulsePlayback_open(PulsePlayback *self, const ALCchar *name)
dev_name = iter->name.c_str();
}
- std::tie(self->mLoop, self->mContext) = pulse_open(&PulsePlayback::contextStateCallbackC, self);
- if(!self->mLoop) return ALC_INVALID_VALUE;
+ std::tie(mLoop, mContext) = pulse_open(&PulsePlayback::contextStateCallbackC, this);
+ if(!mLoop) return ALC_INVALID_VALUE;
- unique_palock palock{self->mLoop};
+ unique_palock palock{mLoop};
pa_stream_flags_t flags{PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
PA_STREAM_FIX_CHANNELS};
@@ -1001,93 +985,89 @@ ALCenum PulsePlayback_open(PulsePlayback *self, const ALCchar *name)
pulse_name = getenv("ALSOFT_PULSE_DEFAULT");
if(pulse_name && !pulse_name[0]) pulse_name = nullptr;
}
- self->mStream = pulse_connect_stream(pulse_name, self->mLoop, self->mContext, flags, nullptr,
- &spec, nullptr, ALCbackend_Playback);
- if(!self->mStream)
+ mStream = pulse_connect_stream(pulse_name, mLoop, mContext, flags, nullptr, &spec, nullptr,
+ ALCbackend_Playback);
+ if(!mStream)
{
palock = unique_palock{};
- pulse_close(self->mLoop, self->mContext, self->mStream);
- self->mLoop = nullptr;
- self->mContext = nullptr;
+ pulse_close(mLoop, mContext, mStream);
+ mLoop = nullptr;
+ mContext = nullptr;
return ALC_INVALID_VALUE;
}
- pa_stream_set_moved_callback(self->mStream, &PulsePlayback::streamMovedCallbackC, self);
- self->mFrameSize = pa_frame_size(pa_stream_get_sample_spec(self->mStream));
+ pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
+ mFrameSize = pa_frame_size(pa_stream_get_sample_spec(mStream));
- self->mDeviceName = pa_stream_get_device_name(self->mStream);
+ mDeviceName = pa_stream_get_device_name(mStream);
if(!dev_name)
{
- pa_operation *op{pa_context_get_sink_info_by_name(self->mContext,
- self->mDeviceName.c_str(), &PulsePlayback::sinkNameCallbackC, self)};
- wait_for_operation(op, self->mLoop);
+ pa_operation *op{pa_context_get_sink_info_by_name(mContext, mDeviceName.c_str(),
+ &PulsePlayback::sinkNameCallbackC, this)};
+ wait_for_operation(op, mLoop);
}
else
- {
- ALCdevice *device{self->mDevice};
- device->DeviceName = dev_name;
- }
+ mDevice->DeviceName = dev_name;
return ALC_NO_ERROR;
}
-ALCboolean PulsePlayback_reset(PulsePlayback *self)
+ALCboolean PulsePlayback::reset()
{
- unique_palock palock{self->mLoop};
+ unique_palock palock{mLoop};
- if(self->mStream)
+ if(mStream)
{
- pa_stream_set_state_callback(self->mStream, nullptr, nullptr);
- pa_stream_set_moved_callback(self->mStream, nullptr, nullptr);
- pa_stream_set_write_callback(self->mStream, nullptr, nullptr);
- pa_stream_set_buffer_attr_callback(self->mStream, nullptr, nullptr);
- pa_stream_disconnect(self->mStream);
- pa_stream_unref(self->mStream);
- self->mStream = nullptr;
+ pa_stream_set_state_callback(mStream, nullptr, nullptr);
+ pa_stream_set_moved_callback(mStream, nullptr, nullptr);
+ pa_stream_set_write_callback(mStream, nullptr, nullptr);
+ pa_stream_set_buffer_attr_callback(mStream, nullptr, nullptr);
+ pa_stream_disconnect(mStream);
+ pa_stream_unref(mStream);
+ mStream = nullptr;
}
- pa_operation *op{pa_context_get_sink_info_by_name(self->mContext,
- self->mDeviceName.c_str(), &PulsePlayback::sinkInfoCallbackC, self)};
- wait_for_operation(op, self->mLoop);
+ pa_operation *op{pa_context_get_sink_info_by_name(mContext, mDeviceName.c_str(),
+ &PulsePlayback::sinkInfoCallbackC, this)};
+ wait_for_operation(op, mLoop);
- ALCdevice *device{self->mDevice};
pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING |
PA_STREAM_AUTO_TIMING_UPDATE};
if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", 0))
flags |= PA_STREAM_DONT_MOVE;
- if(GetConfigValueBool(device->DeviceName.c_str(), "pulse", "adjust-latency", 0))
+ if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "adjust-latency", 0))
flags |= PA_STREAM_ADJUST_LATENCY;
- if(GetConfigValueBool(device->DeviceName.c_str(), "pulse", "fix-rate", 0) ||
- !(device->Flags&DEVICE_FREQUENCY_REQUEST))
+ if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "fix-rate", 0) ||
+ !(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
flags |= PA_STREAM_FIX_RATE;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
- device->FmtType = DevFmtUByte;
+ mDevice->FmtType = DevFmtUByte;
/* fall-through */
case DevFmtUByte:
- self->mSpec.format = PA_SAMPLE_U8;
+ mSpec.format = PA_SAMPLE_U8;
break;
case DevFmtUShort:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
- self->mSpec.format = PA_SAMPLE_S16NE;
+ mSpec.format = PA_SAMPLE_S16NE;
break;
case DevFmtUInt:
- device->FmtType = DevFmtInt;
+ mDevice->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
- self->mSpec.format = PA_SAMPLE_S32NE;
+ mSpec.format = PA_SAMPLE_S32NE;
break;
case DevFmtFloat:
- self->mSpec.format = PA_SAMPLE_FLOAT32NE;
+ mSpec.format = PA_SAMPLE_FLOAT32NE;
break;
}
- self->mSpec.rate = device->Frequency;
- self->mSpec.channels = device->channelsFromFmt();
+ mSpec.rate = mDevice->Frequency;
+ mSpec.channels = mDevice->channelsFromFmt();
- if(pa_sample_spec_valid(&self->mSpec) == 0)
+ if(pa_sample_spec_valid(&mSpec) == 0)
{
ERR("Invalid sample format\n");
return ALC_FALSE;
@@ -1095,13 +1075,13 @@ ALCboolean PulsePlayback_reset(PulsePlayback *self)
const char *mapname{nullptr};
pa_channel_map chanmap;
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
mapname = "mono";
break;
case DevFmtAmbi3D:
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
/*fall-through*/
case DevFmtStereo:
mapname = "front-left,front-right";
@@ -1124,54 +1104,52 @@ ALCboolean PulsePlayback_reset(PulsePlayback *self)
}
if(!pa_channel_map_parse(&chanmap, mapname))
{
- ERR("Failed to build channel map for %s\n", DevFmtChannelsString(device->FmtChans));
+ ERR("Failed to build channel map for %s\n", DevFmtChannelsString(mDevice->FmtChans));
return ALC_FALSE;
}
- SetDefaultWFXChannelOrder(device);
+ SetDefaultWFXChannelOrder(mDevice);
- size_t period_size{device->UpdateSize * pa_frame_size(&self->mSpec)};
- self->mAttr.maxlength = -1;
- self->mAttr.tlength = period_size * maxu(device->NumUpdates, 2);
- self->mAttr.prebuf = 0;
- self->mAttr.minreq = period_size;
- self->mAttr.fragsize = -1;
+ size_t period_size{mDevice->UpdateSize * pa_frame_size(&mSpec)};
+ mAttr.maxlength = -1;
+ mAttr.tlength = period_size * maxu(mDevice->NumUpdates, 2);
+ mAttr.prebuf = 0;
+ mAttr.minreq = period_size;
+ mAttr.fragsize = -1;
- self->mStream = pulse_connect_stream(self->mDeviceName.c_str(), self->mLoop, self->mContext,
- flags, &self->mAttr, &self->mSpec, &chanmap, ALCbackend_Playback);
- if(!self->mStream) return ALC_FALSE;
+ mStream = pulse_connect_stream(mDeviceName.c_str(), mLoop, mContext, flags, &mAttr, &mSpec,
+ &chanmap, ALCbackend_Playback);
+ if(!mStream) return ALC_FALSE;
- pa_stream_set_state_callback(self->mStream, &PulsePlayback::streamStateCallbackC, self);
- pa_stream_set_moved_callback(self->mStream, &PulsePlayback::streamMovedCallbackC, self);
+ pa_stream_set_state_callback(mStream, &PulsePlayback::streamStateCallbackC, this);
+ pa_stream_set_moved_callback(mStream, &PulsePlayback::streamMovedCallbackC, this);
- self->mSpec = *(pa_stream_get_sample_spec(self->mStream));
- self->mFrameSize = pa_frame_size(&self->mSpec);
+ mSpec = *(pa_stream_get_sample_spec(mStream));
+ mFrameSize = pa_frame_size(&mSpec);
- if(device->Frequency != self->mSpec.rate)
+ if(mDevice->Frequency != mSpec.rate)
{
/* Server updated our playback rate, so modify the buffer attribs
* accordingly. */
- device->NumUpdates = static_cast<ALuint>(clampd(
- (ALdouble)self->mSpec.rate/device->Frequency*device->NumUpdates + 0.5, 2.0, 16.0));
+ mDevice->NumUpdates = static_cast<ALuint>(clampd(
+ (ALdouble)mSpec.rate/mDevice->Frequency*mDevice->NumUpdates + 0.5, 2.0, 16.0));
- period_size = device->UpdateSize * self->mFrameSize;
- self->mAttr.maxlength = -1;
- self->mAttr.tlength = period_size * maxu(device->NumUpdates, 2);
- self->mAttr.prebuf = 0;
- self->mAttr.minreq = period_size;
+ period_size = mDevice->UpdateSize * mFrameSize;
+ mAttr.maxlength = -1;
+ mAttr.tlength = period_size * maxu(mDevice->NumUpdates, 2);
+ mAttr.prebuf = 0;
+ mAttr.minreq = period_size;
- op = pa_stream_set_buffer_attr(self->mStream, &self->mAttr, stream_success_callback,
- self->mLoop);
- wait_for_operation(op, self->mLoop);
+ op = pa_stream_set_buffer_attr(mStream, &mAttr, stream_success_callback, mLoop);
+ wait_for_operation(op, mLoop);
- device->Frequency = self->mSpec.rate;
+ mDevice->Frequency = mSpec.rate;
}
- pa_stream_set_buffer_attr_callback(self->mStream, &PulsePlayback::bufferAttrCallbackC, self);
- self->bufferAttrCallback(self->mStream);
+ pa_stream_set_buffer_attr_callback(mStream, &PulsePlayback::bufferAttrCallbackC, this);
+ bufferAttrCallback(mStream);
- device->NumUpdates = clampu(
- (self->mAttr.tlength + self->mAttr.minreq/2u) / self->mAttr.minreq, 2u, 16u);
- device->UpdateSize = self->mAttr.minreq / self->mFrameSize;
+ mDevice->NumUpdates = clampu((mAttr.tlength + mAttr.minreq/2u) / mAttr.minreq, 2u, 16u);
+ mDevice->UpdateSize = mAttr.minreq / mFrameSize;
/* HACK: prebuf should be 0 as that's what we set it to. However on some
* systems it comes back as non-0, so we have to make sure the device will
@@ -1179,53 +1157,53 @@ ALCboolean PulsePlayback_reset(PulsePlayback *self)
* may have unintended consequences, but it's better than not starting at
* all.
*/
- if(self->mAttr.prebuf != 0)
+ if(mAttr.prebuf != 0)
{
- ALuint len{self->mAttr.prebuf / self->mFrameSize};
- if(len <= device->UpdateSize*device->NumUpdates)
+ ALuint len{mAttr.prebuf / mFrameSize};
+ if(len <= mDevice->UpdateSize*mDevice->NumUpdates)
ERR("Non-0 prebuf, %u samples (%u bytes), device has %u samples\n",
- len, self->mAttr.prebuf, device->UpdateSize*device->NumUpdates);
+ len, mAttr.prebuf, mDevice->UpdateSize*mDevice->NumUpdates);
else
{
ERR("Large prebuf, %u samples (%u bytes), increasing device from %u samples",
- len, self->mAttr.prebuf, device->UpdateSize*device->NumUpdates);
- device->NumUpdates = (len+device->UpdateSize-1) / device->UpdateSize;
+ len, mAttr.prebuf, mDevice->UpdateSize*mDevice->NumUpdates);
+ mDevice->NumUpdates = (len+mDevice->UpdateSize-1) / mDevice->UpdateSize;
}
}
return ALC_TRUE;
}
-ALCboolean PulsePlayback_start(PulsePlayback *self)
+ALCboolean PulsePlayback::start()
{
- unique_palock palock{self->mLoop};
+ unique_palock palock{mLoop};
- pa_stream_set_write_callback(self->mStream, &PulsePlayback::streamWriteCallbackC, self);
- pa_operation *op{pa_stream_cork(self->mStream, 0, stream_success_callback, self->mLoop)};
- wait_for_operation(op, self->mLoop);
+ pa_stream_set_write_callback(mStream, &PulsePlayback::streamWriteCallbackC, this);
+ pa_operation *op{pa_stream_cork(mStream, 0, stream_success_callback, mLoop)};
+ wait_for_operation(op, mLoop);
return ALC_TRUE;
}
-void PulsePlayback_stop(PulsePlayback *self)
+void PulsePlayback::stop()
{
- unique_palock palock{self->mLoop};
+ unique_palock palock{mLoop};
- pa_stream_set_write_callback(self->mStream, nullptr, nullptr);
- pa_operation *op{pa_stream_cork(self->mStream, 1, stream_success_callback, self->mLoop)};
- wait_for_operation(op, self->mLoop);
+ pa_stream_set_write_callback(mStream, nullptr, nullptr);
+ pa_operation *op{pa_stream_cork(mStream, 1, stream_success_callback, mLoop)};
+ wait_for_operation(op, mLoop);
}
-ClockLatency PulsePlayback_getClockLatency(PulsePlayback *self)
+ClockLatency PulsePlayback::getClockLatency()
{
ClockLatency ret;
pa_usec_t latency;
int neg, err;
- { palock_guard _{self->mLoop};
- ret.ClockTime = GetDeviceClockTime(self->mDevice);
- err = pa_stream_get_latency(self->mStream, &latency, &neg);
+ { palock_guard _{mLoop};
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ err = pa_stream_get_latency(mStream, &latency, &neg);
}
if(UNLIKELY(err != 0))
@@ -1247,19 +1225,15 @@ ClockLatency PulsePlayback_getClockLatency(PulsePlayback *self)
}
-void PulsePlayback_lock(PulsePlayback *self)
-{
- pa_threaded_mainloop_lock(self->mLoop);
-}
+void PulsePlayback::lock() noexcept
+{ pa_threaded_mainloop_lock(mLoop); }
-void PulsePlayback_unlock(PulsePlayback *self)
-{
- pa_threaded_mainloop_unlock(self->mLoop);
-}
+void PulsePlayback::unlock() noexcept
+{ pa_threaded_mainloop_unlock(mLoop); }
-struct PulseCapture final : public ALCbackend {
- PulseCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct PulseCapture final : public BackendBase {
+ PulseCapture(ALCdevice *device) noexcept : BackendBase{device} { }
~PulseCapture() override;
static void contextStateCallbackC(pa_context *context, void *pdata);
@@ -1274,6 +1248,15 @@ struct PulseCapture final : public ALCbackend {
static void streamMovedCallbackC(pa_stream *stream, void *pdata);
void streamMovedCallback(pa_stream *stream);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(ALCvoid *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+ ClockLatency getClockLatency() override;
+ void lock() noexcept override;
+ void unlock() noexcept override;
+
std::string mDeviceName;
const void *mCapStore{nullptr};
@@ -1291,33 +1274,9 @@ struct PulseCapture final : public ALCbackend {
pa_context *mContext{nullptr};
static constexpr inline const char *CurrentPrefix() noexcept { return "PulseCapture::"; }
+ DEF_NEWDEL(PulseCapture)
};
-void PulseCapture_Construct(PulseCapture *self, ALCdevice *device);
-void PulseCapture_Destruct(PulseCapture *self);
-ALCenum PulseCapture_open(PulseCapture *self, const ALCchar *name);
-DECLARE_FORWARD(PulseCapture, ALCbackend, ALCboolean, reset)
-ALCboolean PulseCapture_start(PulseCapture *self);
-void PulseCapture_stop(PulseCapture *self);
-ALCenum PulseCapture_captureSamples(PulseCapture *self, ALCvoid *buffer, ALCuint samples);
-ALCuint PulseCapture_availableSamples(PulseCapture *self);
-ClockLatency PulseCapture_getClockLatency(PulseCapture *self);
-void PulseCapture_lock(PulseCapture *self);
-void PulseCapture_unlock(PulseCapture *self);
-DECLARE_DEFAULT_ALLOCATORS(PulseCapture)
-
-DEFINE_ALCBACKEND_VTABLE(PulseCapture);
-
-
-void PulseCapture_Construct(PulseCapture *self, ALCdevice *device)
-{
- new (self) PulseCapture{device};
- SET_VTABLE2(PulseCapture, ALCbackend, self);
-}
-
-void PulseCapture_Destruct(PulseCapture *self)
-{ self->~PulseCapture(); }
-
PulseCapture::~PulseCapture()
{
if(!mLoop)
@@ -1377,11 +1336,9 @@ void PulseCapture::streamMovedCallback(pa_stream *stream)
}
-ALCenum PulseCapture_open(PulseCapture *self, const ALCchar *name)
+ALCenum PulseCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
const char *pulse_name{nullptr};
-
if(name)
{
if(CaptureDevices.empty())
@@ -1394,38 +1351,38 @@ ALCenum PulseCapture_open(PulseCapture *self, const ALCchar *name)
if(iter == CaptureDevices.cend())
return ALC_INVALID_VALUE;
pulse_name = iter->device_name.c_str();
- device->DeviceName = iter->name;
+ mDevice->DeviceName = iter->name;
}
- std::tie(self->mLoop, self->mContext) = pulse_open(&PulseCapture::contextStateCallbackC, self);
- if(!self->mLoop) return ALC_INVALID_VALUE;
+ std::tie(mLoop, mContext) = pulse_open(&PulseCapture::contextStateCallbackC, this);
+ if(!mLoop) return ALC_INVALID_VALUE;
- unique_palock palock{self->mLoop};
+ unique_palock palock{mLoop};
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtUByte:
- self->mSpec.format = PA_SAMPLE_U8;
+ mSpec.format = PA_SAMPLE_U8;
break;
case DevFmtShort:
- self->mSpec.format = PA_SAMPLE_S16NE;
+ mSpec.format = PA_SAMPLE_S16NE;
break;
case DevFmtInt:
- self->mSpec.format = PA_SAMPLE_S32NE;
+ mSpec.format = PA_SAMPLE_S32NE;
break;
case DevFmtFloat:
- self->mSpec.format = PA_SAMPLE_FLOAT32NE;
+ mSpec.format = PA_SAMPLE_FLOAT32NE;
break;
case DevFmtByte:
case DevFmtUShort:
case DevFmtUInt:
- ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
+ ERR("%s capture samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_VALUE;
}
const char *mapname{nullptr};
pa_channel_map chanmap;
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
mapname = "mono";
@@ -1449,166 +1406,161 @@ ALCenum PulseCapture_open(PulseCapture *self, const ALCchar *name)
mapname = "front-left,front-right,front-center,lfe,rear-left,rear-right,side-left,side-right";
break;
case DevFmtAmbi3D:
- ERR("%s capture samples not supported\n", DevFmtChannelsString(device->FmtChans));
+ ERR("%s capture samples not supported\n", DevFmtChannelsString(mDevice->FmtChans));
return ALC_INVALID_VALUE;
}
if(!pa_channel_map_parse(&chanmap, mapname))
{
- ERR("Failed to build channel map for %s\n", DevFmtChannelsString(device->FmtChans));
+ ERR("Failed to build channel map for %s\n", DevFmtChannelsString(mDevice->FmtChans));
return ALC_INVALID_VALUE;
}
- self->mSpec.rate = device->Frequency;
- self->mSpec.channels = device->channelsFromFmt();
+ mSpec.rate = mDevice->Frequency;
+ mSpec.channels = mDevice->channelsFromFmt();
- if(pa_sample_spec_valid(&self->mSpec) == 0)
+ if(pa_sample_spec_valid(&mSpec) == 0)
{
ERR("Invalid sample format\n");
return ALC_INVALID_VALUE;
}
- if(!pa_channel_map_init_auto(&chanmap, self->mSpec.channels, PA_CHANNEL_MAP_WAVEEX))
+ if(!pa_channel_map_init_auto(&chanmap, mSpec.channels, PA_CHANNEL_MAP_WAVEEX))
{
- ERR("Couldn't build map for channel count (%d)!\n", self->mSpec.channels);
+ ERR("Couldn't build map for channel count (%d)!\n", mSpec.channels);
return ALC_INVALID_VALUE;
}
- ALuint samples{device->UpdateSize * device->NumUpdates};
- samples = maxu(samples, 100 * device->Frequency / 1000);
+ ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
+ samples = maxu(samples, 100 * mDevice->Frequency / 1000);
- self->mAttr.minreq = -1;
- self->mAttr.prebuf = -1;
- self->mAttr.maxlength = samples * pa_frame_size(&self->mSpec);
- self->mAttr.tlength = -1;
- self->mAttr.fragsize = minu(samples, 50*device->Frequency/1000) *
- pa_frame_size(&self->mSpec);
+ mAttr.minreq = -1;
+ mAttr.prebuf = -1;
+ mAttr.maxlength = samples * pa_frame_size(&mSpec);
+ mAttr.tlength = -1;
+ mAttr.fragsize = minu(samples, 50*mDevice->Frequency/1000) * pa_frame_size(&mSpec);
pa_stream_flags_t flags{PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY};
if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", 0))
flags |= PA_STREAM_DONT_MOVE;
TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
- self->mStream = pulse_connect_stream(pulse_name, self->mLoop, self->mContext, flags,
- &self->mAttr, &self->mSpec, &chanmap, ALCbackend_Capture);
- if(!self->mStream) return ALC_INVALID_VALUE;
+ mStream = pulse_connect_stream(pulse_name, mLoop, mContext, flags, &mAttr, &mSpec, &chanmap,
+ ALCbackend_Capture);
+ if(!mStream) return ALC_INVALID_VALUE;
- pa_stream_set_moved_callback(self->mStream, &PulseCapture::streamMovedCallbackC, self);
- pa_stream_set_state_callback(self->mStream, &PulseCapture::streamStateCallbackC, self);
+ pa_stream_set_moved_callback(mStream, &PulseCapture::streamMovedCallbackC, this);
+ pa_stream_set_state_callback(mStream, &PulseCapture::streamStateCallbackC, this);
- self->mDeviceName = pa_stream_get_device_name(self->mStream);
- if(device->DeviceName.empty())
+ mDeviceName = pa_stream_get_device_name(mStream);
+ if(mDevice->DeviceName.empty())
{
- pa_operation *op{pa_context_get_source_info_by_name(self->mContext,
- self->mDeviceName.c_str(), &PulseCapture::sourceNameCallbackC, self
- )};
- wait_for_operation(op, self->mLoop);
+ pa_operation *op{pa_context_get_source_info_by_name(mContext, mDeviceName.c_str(),
+ &PulseCapture::sourceNameCallbackC, this)};
+ wait_for_operation(op, mLoop);
}
return ALC_NO_ERROR;
}
-ALCboolean PulseCapture_start(PulseCapture *self)
+ALCboolean PulseCapture::start()
{
- palock_guard _{self->mLoop};
- pa_operation *op{pa_stream_cork(self->mStream, 0, stream_success_callback, self->mLoop)};
- wait_for_operation(op, self->mLoop);
+ palock_guard _{mLoop};
+ pa_operation *op{pa_stream_cork(mStream, 0, stream_success_callback, mLoop)};
+ wait_for_operation(op, mLoop);
return ALC_TRUE;
}
-void PulseCapture_stop(PulseCapture *self)
+void PulseCapture::stop()
{
- palock_guard _{self->mLoop};
- pa_operation *op{pa_stream_cork(self->mStream, 1, stream_success_callback, self->mLoop)};
- wait_for_operation(op, self->mLoop);
+ palock_guard _{mLoop};
+ pa_operation *op{pa_stream_cork(mStream, 1, stream_success_callback, mLoop)};
+ wait_for_operation(op, mLoop);
}
-ALCenum PulseCapture_captureSamples(PulseCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum PulseCapture::captureSamples(ALCvoid *buffer, ALCuint samples)
{
- ALCdevice *device{self->mDevice};
- ALCuint todo{samples * static_cast<ALCuint>(pa_frame_size(&self->mSpec))};
+ ALCuint todo{samples * static_cast<ALCuint>(pa_frame_size(&mSpec))};
/* Capture is done in fragment-sized chunks, so we loop until we get all
* that's available */
- self->mLastReadable -= todo;
- unique_palock palock{self->mLoop};
+ mLastReadable -= todo;
+ unique_palock palock{mLoop};
while(todo > 0)
{
size_t rem{todo};
- if(self->mCapLen == 0)
+ if(mCapLen == 0)
{
- pa_stream_state_t state{pa_stream_get_state(self->mStream)};
+ pa_stream_state_t state{pa_stream_get_state(mStream)};
if(!PA_STREAM_IS_GOOD(state))
{
- aluHandleDisconnect(device, "Bad capture state: %u", state);
+ aluHandleDisconnect(mDevice, "Bad capture state: %u", state);
return ALC_INVALID_DEVICE;
}
- if(pa_stream_peek(self->mStream, &self->mCapStore, &self->mCapLen) < 0)
+ if(pa_stream_peek(mStream, &mCapStore, &mCapLen) < 0)
{
ERR("pa_stream_peek() failed: %s\n",
- pa_strerror(pa_context_errno(self->mContext)));
- aluHandleDisconnect(device, "Failed retrieving capture samples: %s",
- pa_strerror(pa_context_errno(self->mContext)));
+ pa_strerror(pa_context_errno(mContext)));
+ aluHandleDisconnect(mDevice, "Failed retrieving capture samples: %s",
+ pa_strerror(pa_context_errno(mContext)));
return ALC_INVALID_DEVICE;
}
- self->mCapRemain = self->mCapLen;
+ mCapRemain = mCapLen;
}
- if(rem > self->mCapRemain)
- rem = self->mCapRemain;
+ rem = minz(rem, mCapRemain);
- memcpy(buffer, self->mCapStore, rem);
+ memcpy(buffer, mCapStore, rem);
buffer = (ALbyte*)buffer + rem;
todo -= rem;
- self->mCapStore = (ALbyte*)self->mCapStore + rem;
- self->mCapRemain -= rem;
- if(self->mCapRemain == 0)
+ mCapStore = (ALbyte*)mCapStore + rem;
+ mCapRemain -= rem;
+ if(mCapRemain == 0)
{
- pa_stream_drop(self->mStream);
- self->mCapLen = 0;
+ pa_stream_drop(mStream);
+ mCapLen = 0;
}
}
palock.unlock();
if(todo > 0)
- memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo);
+ memset(buffer, ((mDevice->FmtType==DevFmtUByte) ? 0x80 : 0), todo);
return ALC_NO_ERROR;
}
-ALCuint PulseCapture_availableSamples(PulseCapture *self)
+ALCuint PulseCapture::availableSamples()
{
- ALCdevice *device{self->mDevice};
- size_t readable{self->mCapRemain};
+ size_t readable{mCapRemain};
- if(device->Connected.load(std::memory_order_acquire))
+ if(mDevice->Connected.load(std::memory_order_acquire))
{
- palock_guard _{self->mLoop};
- size_t got{pa_stream_readable_size(self->mStream)};
+ palock_guard _{mLoop};
+ size_t got{pa_stream_readable_size(mStream)};
if(static_cast<ssize_t>(got) < 0)
{
ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got));
- aluHandleDisconnect(device, "Failed getting readable size: %s", pa_strerror(got));
+ aluHandleDisconnect(mDevice, "Failed getting readable size: %s", pa_strerror(got));
}
- else if(got > self->mCapLen)
- readable += got - self->mCapLen;
+ else if(got > mCapLen)
+ readable += got - mCapLen;
}
- if(self->mLastReadable < readable)
- self->mLastReadable = readable;
- return self->mLastReadable / pa_frame_size(&self->mSpec);
+ if(mLastReadable < readable)
+ mLastReadable = readable;
+ return mLastReadable / pa_frame_size(&mSpec);
}
-ClockLatency PulseCapture_getClockLatency(PulseCapture *self)
+ClockLatency PulseCapture::getClockLatency()
{
ClockLatency ret;
pa_usec_t latency;
int neg, err;
- { palock_guard _{self->mLoop};
- ret.ClockTime = GetDeviceClockTime(self->mDevice);
- err = pa_stream_get_latency(self->mStream, &latency, &neg);
+ { palock_guard _{mLoop};
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ err = pa_stream_get_latency(mStream, &latency, &neg);
}
if(UNLIKELY(err != 0))
@@ -1625,15 +1577,11 @@ ClockLatency PulseCapture_getClockLatency(PulseCapture *self)
}
-void PulseCapture_lock(PulseCapture *self)
-{
- pa_threaded_mainloop_lock(self->mLoop);
-}
+void PulseCapture::lock() noexcept
+{ pa_threaded_mainloop_lock(mLoop); }
-void PulseCapture_unlock(PulseCapture *self)
-{
- pa_threaded_mainloop_unlock(self->mLoop);
-}
+void PulseCapture::unlock() noexcept
+{ pa_threaded_mainloop_unlock(mLoop); }
} // namespace
@@ -1720,21 +1668,12 @@ void PulseBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *PulseBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *PulseBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- PulsePlayback *backend;
- NEW_OBJ(backend, PulsePlayback)(device);
- return backend;
- }
+ return new PulsePlayback{device};
if(type == ALCbackend_Capture)
- {
- PulseCapture *backend;
- NEW_OBJ(backend, PulseCapture)(device);
- return backend;
- }
-
+ return new PulseCapture{device};
return nullptr;
}
diff --git a/Alc/backends/pulseaudio.h b/Alc/backends/pulseaudio.h
index eb7045dc..07d74b64 100644
--- a/Alc/backends/pulseaudio.h
+++ b/Alc/backends/pulseaudio.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/qsa.cpp b/Alc/backends/qsa.cpp
index c7c8e90b..7641ad57 100644
--- a/Alc/backends/qsa.cpp
+++ b/Alc/backends/qsa.cpp
@@ -170,26 +170,20 @@ void deviceList(int type, al::vector<DevMap> *devmap)
/* Wrappers to use an old-style backend with the new interface. */
-struct PlaybackWrapper final : public ALCbackend {
- PlaybackWrapper(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct PlaybackWrapper final : public BackendBase {
+ PlaybackWrapper(ALCdevice *device) noexcept : BackendBase{device} { }
~PlaybackWrapper() override;
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
std::unique_ptr<qsa_data> mExtraData;
-};
-static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device);
-static void PlaybackWrapper_Destruct(PlaybackWrapper *self);
-static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name);
-static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self);
-static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self);
-static void PlaybackWrapper_stop(PlaybackWrapper *self);
-static DECLARE_FORWARD2(PlaybackWrapper, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALCuint, availableSamples)
-static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, lock)
-static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(PlaybackWrapper)
-DEFINE_ALCBACKEND_VTABLE(PlaybackWrapper);
+ static constexpr inline const char *CurrentPrefix() noexcept { return "PlaybackWrapper::"; }
+ DEF_NEWDEL(PlaybackWrapper)
+};
FORCE_ALIGN static int qsa_proc_playback(void *ptr)
@@ -213,7 +207,7 @@ FORCE_ALIGN static int qsa_proc_playback(void *ptr)
const ALint frame_size = device->frameSizeFromFmt();
- PlaybackWrapper_lock(self);
+ self->lock();
while(!data->mKillNow.load(std::memory_order_acquire))
{
pollfd pollitem{};
@@ -221,9 +215,9 @@ FORCE_ALIGN static int qsa_proc_playback(void *ptr)
pollitem.events = POLLOUT;
/* Select also works like time slice to OS */
- PlaybackWrapper_unlock(self);
+ self->unlock();
sret = poll(&pollitem, 1, 2000);
- PlaybackWrapper_lock(self);
+ self->lock();
if(sret == -1)
{
if(errno == EINTR || errno == EAGAIN)
@@ -272,7 +266,7 @@ FORCE_ALIGN static int qsa_proc_playback(void *ptr)
}
}
}
- PlaybackWrapper_unlock(self);
+ self->unlock();
return 0;
}
@@ -614,68 +608,44 @@ static void qsa_stop_playback(PlaybackWrapper *self)
}
-static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device)
-{
- new (self) PlaybackWrapper{device};
- SET_VTABLE2(PlaybackWrapper, ALCbackend, self);
-}
-
-static void PlaybackWrapper_Destruct(PlaybackWrapper *self)
-{ self->~PlaybackWrapper(); }
-
PlaybackWrapper::~PlaybackWrapper()
{
if(mExtraData)
qsa_close_playback(this);
}
-static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name)
-{
- return qsa_open_playback(self, name);
-}
-
-static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self)
-{
- return qsa_reset_playback(self);
-}
+ALCenum PlaybackWrapper::open(const ALCchar *name)
+{ return qsa_open_playback(this, name); }
-static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self)
-{
- return qsa_start_playback(self);
-}
+ALCboolean PlaybackWrapper::reset()
+{ return qsa_reset_playback(this); }
-static void PlaybackWrapper_stop(PlaybackWrapper *self)
-{
- qsa_stop_playback(self);
-}
+ALCboolean PlaybackWrapper::start()
+{ return qsa_start_playback(this); }
+void PlaybackWrapper::stop()
+{ qsa_stop_playback(this); }
/***********/
/* Capture */
/***********/
-struct CaptureWrapper final : public ALCbackend {
- CaptureWrapper(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct CaptureWrapper final : public BackendBase {
+ CaptureWrapper(ALCdevice *device) noexcept : BackendBase{device} { }
~CaptureWrapper() override;
- std::unique_ptr<qsa_data> mExtraData;
-};
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
-static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device);
-static void CaptureWrapper_Destruct(CaptureWrapper *self);
-static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name);
-static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ALCboolean, reset)
-static ALCboolean CaptureWrapper_start(CaptureWrapper *self);
-static void CaptureWrapper_stop(CaptureWrapper *self);
-static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples);
-static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self);
-static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, lock)
-static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(CaptureWrapper)
-DEFINE_ALCBACKEND_VTABLE(CaptureWrapper);
+ std::unique_ptr<qsa_data> mExtraData;
+ static constexpr inline const char *CurrentPrefix() noexcept { return "CaptureWrapper::"; }
+ DEF_NEWDEL(CaptureWrapper)
+};
static ALCenum qsa_open_capture(CaptureWrapper *self, const ALCchar *deviceName)
{
@@ -917,46 +887,26 @@ static ALCenum qsa_capture_samples(CaptureWrapper *self, ALCvoid *buffer, ALCuin
}
-static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device)
-{
- new (self) CaptureWrapper{device};
- SET_VTABLE2(CaptureWrapper, ALCbackend, self);
-}
-
-static void CaptureWrapper_Destruct(CaptureWrapper *self)
-{ self->~CaptureWrapper(); }
-
CaptureWrapper::~CaptureWrapper()
{
if(mExtraData)
qsa_close_capture(this);
}
-static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name)
-{
- return qsa_open_capture(self, name);
-}
+ALCenum CaptureWrapper::open(const ALCchar *name)
+{ return qsa_open_capture(this, name); }
-static ALCboolean CaptureWrapper_start(CaptureWrapper *self)
-{
- qsa_start_capture(self);
- return ALC_TRUE;
-}
+ALCboolean CaptureWrapper::start()
+{ qsa_start_capture(this); return ALC_TRUE; }
-static void CaptureWrapper_stop(CaptureWrapper *self)
-{
- qsa_stop_capture(self);
-}
+void CaptureWrapper::stop()
+{ qsa_stop_capture(this); }
-static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples)
-{
- return qsa_capture_samples(self, buffer, samples);
-}
+ALCenum CaptureWrapper::captureSamples(void *buffer, ALCuint samples)
+{ return qsa_capture_samples(this, buffer, samples); }
-static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self)
-{
- return qsa_available_samples(self);
-}
+ALCuint CaptureWrapper::availableSamples()
+{ return qsa_available_samples(this); }
} // namespace
@@ -1002,22 +952,13 @@ void QSABackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *QSABackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *QSABackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- PlaybackWrapper *backend;
- NEW_OBJ(backend, PlaybackWrapper)(device);
- return backend;
- }
+ return new PlaybackWrapper{device};
if(type == ALCbackend_Capture)
- {
- CaptureWrapper *backend;
- NEW_OBJ(backend, CaptureWrapper)(device);
- return backend;
- }
-
- return NULL;
+ return new CaptureWrapper{device};
+ return nullptr;
}
BackendFactory &QSABackendFactory::getFactory()
diff --git a/Alc/backends/qsa.h b/Alc/backends/qsa.h
index 99d80106..46cc7dd1 100644
--- a/Alc/backends/qsa.h
+++ b/Alc/backends/qsa.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/sdl2.cpp b/Alc/backends/sdl2.cpp
index 985afa2e..91d1cece 100644
--- a/Alc/backends/sdl2.cpp
+++ b/Alc/backends/sdl2.cpp
@@ -43,13 +43,20 @@ namespace {
constexpr ALCchar defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
-struct ALCsdl2Backend final : public ALCbackend {
- ALCsdl2Backend(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCsdl2Backend() override;
+struct Sdl2Backend final : public BackendBase {
+ Sdl2Backend(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~Sdl2Backend() override;
static void audioCallbackC(void *ptr, Uint8 *stream, int len);
void audioCallback(Uint8 *stream, int len);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+ void lock() noexcept override;
+ void unlock() noexcept override;
+
SDL_AudioDeviceID mDeviceID{0u};
ALsizei mFrameSize{0};
@@ -57,55 +64,32 @@ struct ALCsdl2Backend final : public ALCbackend {
DevFmtChannels mFmtChans{};
DevFmtType mFmtType{};
ALuint mUpdateSize{0u};
-};
-
-void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device);
-void ALCsdl2Backend_Destruct(ALCsdl2Backend *self);
-ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name);
-ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self);
-ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self);
-void ALCsdl2Backend_stop(ALCsdl2Backend *self);
-DECLARE_FORWARD2(ALCsdl2Backend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(ALCsdl2Backend, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(ALCsdl2Backend, ALCbackend, ClockLatency, getClockLatency)
-void ALCsdl2Backend_lock(ALCsdl2Backend *self);
-void ALCsdl2Backend_unlock(ALCsdl2Backend *self);
-DECLARE_DEFAULT_ALLOCATORS(ALCsdl2Backend)
-
-DEFINE_ALCBACKEND_VTABLE(ALCsdl2Backend);
-
-void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device)
-{
- new (self) ALCsdl2Backend{device};
- SET_VTABLE2(ALCsdl2Backend, ALCbackend, self);
-}
-void ALCsdl2Backend_Destruct(ALCsdl2Backend *self)
-{ self->~ALCsdl2Backend(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "ALCsdl2Playback::"; }
+ DEF_NEWDEL(Sdl2Backend)
+};
-ALCsdl2Backend::~ALCsdl2Backend()
+Sdl2Backend::~Sdl2Backend()
{
if(mDeviceID)
SDL_CloseAudioDevice(mDeviceID);
mDeviceID = 0;
}
-void ALCsdl2Backend::audioCallbackC(void *ptr, Uint8 *stream, int len)
-{ static_cast<ALCsdl2Backend*>(ptr)->audioCallback(stream, len); }
+void Sdl2Backend::audioCallbackC(void *ptr, Uint8 *stream, int len)
+{ static_cast<Sdl2Backend*>(ptr)->audioCallback(stream, len); }
-void ALCsdl2Backend::audioCallback(Uint8 *stream, int len)
+void Sdl2Backend::audioCallback(Uint8 *stream, int len)
{
assert((len % mFrameSize) == 0);
aluMixData(mDevice, stream, len / mFrameSize);
}
-ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
+ALCenum Sdl2Backend::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
SDL_AudioSpec want{}, have{};
-
- want.freq = device->Frequency;
- switch(device->FmtType)
+ want.freq = mDevice->Frequency;
+ switch(mDevice->FmtType)
{
case DevFmtUByte: want.format = AUDIO_U8; break;
case DevFmtByte: want.format = AUDIO_S8; break;
@@ -115,35 +99,35 @@ ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
case DevFmtInt: want.format = AUDIO_S32SYS; break;
case DevFmtFloat: want.format = AUDIO_F32; break;
}
- want.channels = (device->FmtChans == DevFmtMono) ? 1 : 2;
- want.samples = device->UpdateSize;
- want.callback = &ALCsdl2Backend::audioCallbackC;
- want.userdata = self;
+ want.channels = (mDevice->FmtChans == DevFmtMono) ? 1 : 2;
+ want.samples = mDevice->UpdateSize;
+ want.callback = &Sdl2Backend::audioCallbackC;
+ want.userdata = this;
/* Passing nullptr to SDL_OpenAudioDevice opens a default, which isn't
* necessarily the first in the list.
*/
if(!name || strcmp(name, defaultDeviceName) == 0)
- self->mDeviceID = SDL_OpenAudioDevice(nullptr, SDL_FALSE, &want, &have,
- SDL_AUDIO_ALLOW_ANY_CHANGE);
+ mDeviceID = SDL_OpenAudioDevice(nullptr, SDL_FALSE, &want, &have,
+ SDL_AUDIO_ALLOW_ANY_CHANGE);
else
{
const size_t prefix_len = strlen(DEVNAME_PREFIX);
if(strncmp(name, DEVNAME_PREFIX, prefix_len) == 0)
- self->mDeviceID = SDL_OpenAudioDevice(name+prefix_len, SDL_FALSE, &want, &have,
- SDL_AUDIO_ALLOW_ANY_CHANGE);
+ mDeviceID = SDL_OpenAudioDevice(name+prefix_len, SDL_FALSE, &want, &have,
+ SDL_AUDIO_ALLOW_ANY_CHANGE);
else
- self->mDeviceID = SDL_OpenAudioDevice(name, SDL_FALSE, &want, &have,
- SDL_AUDIO_ALLOW_ANY_CHANGE);
+ mDeviceID = SDL_OpenAudioDevice(name, SDL_FALSE, &want, &have,
+ SDL_AUDIO_ALLOW_ANY_CHANGE);
}
- if(self->mDeviceID == 0)
+ if(mDeviceID == 0)
return ALC_INVALID_VALUE;
- device->Frequency = have.freq;
+ mDevice->Frequency = have.freq;
if(have.channels == 1)
- device->FmtChans = DevFmtMono;
+ mDevice->FmtChans = DevFmtMono;
else if(have.channels == 2)
- device->FmtChans = DevFmtStereo;
+ mDevice->FmtChans = DevFmtStereo;
else
{
ERR("Got unhandled SDL channel count: %d\n", (int)have.channels);
@@ -151,61 +135,54 @@ ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
}
switch(have.format)
{
- case AUDIO_U8: device->FmtType = DevFmtUByte; break;
- case AUDIO_S8: device->FmtType = DevFmtByte; break;
- case AUDIO_U16SYS: device->FmtType = DevFmtUShort; break;
- case AUDIO_S16SYS: device->FmtType = DevFmtShort; break;
- case AUDIO_S32SYS: device->FmtType = DevFmtInt; break;
- case AUDIO_F32SYS: device->FmtType = DevFmtFloat; break;
+ case AUDIO_U8: mDevice->FmtType = DevFmtUByte; break;
+ case AUDIO_S8: mDevice->FmtType = DevFmtByte; break;
+ case AUDIO_U16SYS: mDevice->FmtType = DevFmtUShort; break;
+ case AUDIO_S16SYS: mDevice->FmtType = DevFmtShort; break;
+ case AUDIO_S32SYS: mDevice->FmtType = DevFmtInt; break;
+ case AUDIO_F32SYS: mDevice->FmtType = DevFmtFloat; break;
default:
ERR("Got unsupported SDL format: 0x%04x\n", have.format);
return ALC_INVALID_VALUE;
}
- device->UpdateSize = have.samples;
- device->NumUpdates = 2; /* SDL always (tries to) use two periods. */
+ mDevice->UpdateSize = have.samples;
+ mDevice->NumUpdates = 2; /* SDL always (tries to) use two periods. */
- self->mFrameSize = device->frameSizeFromFmt();
- self->mFrequency = device->Frequency;
- self->mFmtChans = device->FmtChans;
- self->mFmtType = device->FmtType;
- self->mUpdateSize = device->UpdateSize;
+ mFrameSize = mDevice->frameSizeFromFmt();
+ mFrequency = mDevice->Frequency;
+ mFmtChans = mDevice->FmtChans;
+ mFmtType = mDevice->FmtType;
+ mUpdateSize = mDevice->UpdateSize;
- device->DeviceName = name ? name : defaultDeviceName;
+ mDevice->DeviceName = name ? name : defaultDeviceName;
return ALC_NO_ERROR;
}
-ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self)
+ALCboolean Sdl2Backend::reset()
{
- ALCdevice *device{self->mDevice};
- device->Frequency = self->mFrequency;
- device->FmtChans = self->mFmtChans;
- device->FmtType = self->mFmtType;
- device->UpdateSize = self->mUpdateSize;
- device->NumUpdates = 2;
- SetDefaultWFXChannelOrder(device);
+ mDevice->Frequency = mFrequency;
+ mDevice->FmtChans = mFmtChans;
+ mDevice->FmtType = mFmtType;
+ mDevice->UpdateSize = mUpdateSize;
+ mDevice->NumUpdates = 2;
+ SetDefaultWFXChannelOrder(mDevice);
return ALC_TRUE;
}
-ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self)
+ALCboolean Sdl2Backend::start()
{
- SDL_PauseAudioDevice(self->mDeviceID, 0);
+ SDL_PauseAudioDevice(mDeviceID, 0);
return ALC_TRUE;
}
-void ALCsdl2Backend_stop(ALCsdl2Backend *self)
-{
- SDL_PauseAudioDevice(self->mDeviceID, 1);
-}
+void Sdl2Backend::stop()
+{ SDL_PauseAudioDevice(mDeviceID, 1); }
-void ALCsdl2Backend_lock(ALCsdl2Backend *self)
-{
- SDL_LockAudioDevice(self->mDeviceID);
-}
+void Sdl2Backend::lock() noexcept
+{ SDL_LockAudioDevice(mDeviceID); }
-void ALCsdl2Backend_unlock(ALCsdl2Backend *self)
-{
- SDL_UnlockAudioDevice(self->mDeviceID);
-}
+void Sdl2Backend::unlock() noexcept
+{ SDL_UnlockAudioDevice(mDeviceID); }
} // namespace
@@ -248,14 +225,9 @@ void SDL2BackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *SDL2BackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *SDL2BackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCsdl2Backend *backend;
- NEW_OBJ(backend, ALCsdl2Backend)(device);
- return backend;
- }
-
+ return new Sdl2Backend{device};
return nullptr;
}
diff --git a/Alc/backends/sdl2.h b/Alc/backends/sdl2.h
index 7bf4d0e4..7a4ae9eb 100644
--- a/Alc/backends/sdl2.h
+++ b/Alc/backends/sdl2.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/sndio.cpp b/Alc/backends/sndio.cpp
index d185adab..2c2397e6 100644
--- a/Alc/backends/sndio.cpp
+++ b/Alc/backends/sndio.cpp
@@ -42,12 +42,17 @@ namespace {
static const ALCchar sndio_device[] = "SndIO Default";
-struct SndioPlayback final : public ALCbackend {
- SndioPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct SndioPlayback final : public BackendBase {
+ SndioPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
~SndioPlayback() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
sio_hdl *mSndHandle{nullptr};
al::vector<ALubyte> mBuffer;
@@ -56,32 +61,9 @@ struct SndioPlayback final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "SndioPlayback::"; }
+ DEF_NEWDEL(SndioPlayback)
};
-void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device);
-void SndioPlayback_Destruct(SndioPlayback *self);
-ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name);
-ALCboolean SndioPlayback_reset(SndioPlayback *self);
-ALCboolean SndioPlayback_start(SndioPlayback *self);
-void SndioPlayback_stop(SndioPlayback *self);
-DECLARE_FORWARD2(SndioPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(SndioPlayback, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(SndioPlayback, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(SndioPlayback, ALCbackend, void, lock)
-DECLARE_FORWARD(SndioPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(SndioPlayback)
-
-DEFINE_ALCBACKEND_VTABLE(SndioPlayback);
-
-void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device)
-{
- new (self) SndioPlayback{device};
- SET_VTABLE2(SndioPlayback, ALCbackend, self);
-}
-
-void SndioPlayback_Destruct(SndioPlayback *self)
-{ self->~SndioPlayback(); }
-
SndioPlayback::~SndioPlayback()
{
if(mSndHandle)
@@ -102,18 +84,18 @@ int SndioPlayback::mixerProc()
auto WritePtr = static_cast<ALubyte*>(mBuffer.data());
size_t len{mBuffer.size()};
- SndioPlayback_lock(this);
+ lock();
aluMixData(mDevice, WritePtr, len/frameSize);
- SndioPlayback_unlock(this);
+ unlock();
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
{
size_t wrote{sio_write(mSndHandle, WritePtr, len)};
if(wrote == 0)
{
ERR("sio_write failed\n");
- SndioPlayback_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to write playback samples");
- SndioPlayback_unlock(this);
+ unlock();
break;
}
@@ -126,37 +108,33 @@ int SndioPlayback::mixerProc()
}
-ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name)
+ALCenum SndioPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
if(!name)
name = sndio_device;
else if(strcmp(name, sndio_device) != 0)
return ALC_INVALID_VALUE;
- self->mSndHandle = sio_open(nullptr, SIO_PLAY, 0);
- if(self->mSndHandle == nullptr)
+ mSndHandle = sio_open(nullptr, SIO_PLAY, 0);
+ if(mSndHandle == nullptr)
{
ERR("Could not open device\n");
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean SndioPlayback_reset(SndioPlayback *self)
+ALCboolean SndioPlayback::reset()
{
- ALCdevice *device{self->mDevice};
sio_par par;
-
sio_initpar(&par);
- par.rate = device->Frequency;
- par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1);
+ par.rate = mDevice->Frequency;
+ par.pchan = ((mDevice->FmtChans != DevFmtMono) ? 2 : 1);
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
par.bits = 8;
@@ -186,11 +164,11 @@ ALCboolean SndioPlayback_reset(SndioPlayback *self)
}
par.le = SIO_LE_NATIVE;
- par.round = device->UpdateSize;
- par.appbufsz = device->UpdateSize * (device->NumUpdates-1);
- if(!par.appbufsz) par.appbufsz = device->UpdateSize;
+ par.round = mDevice->UpdateSize;
+ par.appbufsz = mDevice->UpdateSize * (mDevice->NumUpdates-1);
+ if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
- if(!sio_setpar(self->mSndHandle, &par) || !sio_getpar(self->mSndHandle, &par))
+ if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
{
ERR("Failed to set device parameters\n");
return ALC_FALSE;
@@ -202,49 +180,49 @@ ALCboolean SndioPlayback_reset(SndioPlayback *self)
return ALC_FALSE;
}
- device->Frequency = par.rate;
- device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo);
+ mDevice->Frequency = par.rate;
+ mDevice->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo);
if(par.bits == 8 && par.sig == 1)
- device->FmtType = DevFmtByte;
+ mDevice->FmtType = DevFmtByte;
else if(par.bits == 8 && par.sig == 0)
- device->FmtType = DevFmtUByte;
+ mDevice->FmtType = DevFmtUByte;
else if(par.bits == 16 && par.sig == 1)
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
else if(par.bits == 16 && par.sig == 0)
- device->FmtType = DevFmtUShort;
+ mDevice->FmtType = DevFmtUShort;
else if(par.bits == 32 && par.sig == 1)
- device->FmtType = DevFmtInt;
+ mDevice->FmtType = DevFmtInt;
else if(par.bits == 32 && par.sig == 0)
- device->FmtType = DevFmtUInt;
+ mDevice->FmtType = DevFmtUInt;
else
{
ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);
return ALC_FALSE;
}
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
- device->UpdateSize = par.round;
- device->NumUpdates = (par.bufsz/par.round) + 1;
+ mDevice->UpdateSize = par.round;
+ mDevice->NumUpdates = (par.bufsz/par.round) + 1;
- self->mBuffer.resize(device->UpdateSize * device->frameSizeFromFmt());
- std::fill(self->mBuffer.begin(), self->mBuffer.end(), 0);
+ mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
+ std::fill(mBuffer.begin(), mBuffer.end(), 0);
return ALC_TRUE;
}
-ALCboolean SndioPlayback_start(SndioPlayback *self)
+ALCboolean SndioPlayback::start()
{
- if(!sio_start(self->mSndHandle))
+ if(!sio_start(mSndHandle))
{
ERR("Error starting playback\n");
return ALC_FALSE;
}
try {
- self->mKillNow.store(false, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&SndioPlayback::mixerProc), self};
+ mKillNow.store(false, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&SndioPlayback::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -252,27 +230,33 @@ ALCboolean SndioPlayback_start(SndioPlayback *self)
}
catch(...) {
}
- sio_stop(self->mSndHandle);
+ sio_stop(mSndHandle);
return ALC_FALSE;
}
-void SndioPlayback_stop(SndioPlayback *self)
+void SndioPlayback::stop()
{
- if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
- if(!sio_stop(self->mSndHandle))
+ if(!sio_stop(mSndHandle))
ERR("Error stopping device\n");
}
-struct SndioCapture final : public ALCbackend {
- SndioCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct SndioCapture final : public BackendBase {
+ SndioCapture(ALCdevice *device) noexcept : BackendBase{device} { }
~SndioCapture() override;
int recordProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
sio_hdl *mSndHandle{nullptr};
RingBufferPtr mRing;
@@ -281,32 +265,9 @@ struct SndioCapture final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "SndioCapture::"; }
+ DEF_NEWDEL(SndioCapture)
};
-void SndioCapture_Construct(SndioCapture *self, ALCdevice *device);
-void SndioCapture_Destruct(SndioCapture *self);
-ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name);
-DECLARE_FORWARD(SndioCapture, ALCbackend, ALCboolean, reset)
-ALCboolean SndioCapture_start(SndioCapture *self);
-void SndioCapture_stop(SndioCapture *self);
-ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples);
-ALCuint SndioCapture_availableSamples(SndioCapture *self);
-DECLARE_FORWARD(SndioCapture, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(SndioCapture, ALCbackend, void, lock)
-DECLARE_FORWARD(SndioCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(SndioCapture)
-
-DEFINE_ALCBACKEND_VTABLE(SndioCapture);
-
-void SndioCapture_Construct(SndioCapture *self, ALCdevice *device)
-{
- new (self) SndioCapture{device};
- SET_VTABLE2(SndioCapture, ALCbackend, self);
-}
-
-void SndioCapture_Destruct(SndioCapture *self)
-{ self->~SndioCapture(); }
-
SndioCapture::~SndioCapture()
{
if(mSndHandle)
@@ -346,9 +307,9 @@ int SndioCapture::recordProc()
size_t got{sio_read(mSndHandle, data.first.buf, minz(todo-total, data.first.len))};
if(!got)
{
- SndioCapture_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to read capture samples");
- SndioCapture_unlock(this);
+ unlock();
break;
}
@@ -363,26 +324,24 @@ int SndioCapture::recordProc()
}
-ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
+ALCenum SndioCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
- sio_par par;
-
if(!name)
name = sndio_device;
else if(strcmp(name, sndio_device) != 0)
return ALC_INVALID_VALUE;
- self->mSndHandle = sio_open(nullptr, SIO_REC, 0);
- if(self->mSndHandle == nullptr)
+ mSndHandle = sio_open(nullptr, SIO_REC, 0);
+ if(mSndHandle == nullptr)
{
ERR("Could not open device\n");
return ALC_INVALID_VALUE;
}
+ sio_par par;
sio_initpar(&par);
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
par.bps = 1;
@@ -409,23 +368,23 @@ ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
par.sig = 0;
break;
case DevFmtFloat:
- ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
+ ERR("%s capture samples not supported\n", DevFmtTypeString(mDevice->FmtType));
return ALC_INVALID_VALUE;
}
par.bits = par.bps * 8;
par.le = SIO_LE_NATIVE;
par.msb = SIO_LE_NATIVE ? 0 : 1;
- par.rchan = device->channelsFromFmt();
- par.rate = device->Frequency;
+ par.rchan = mDevice->channelsFromFmt();
+ par.rate = mDevice->Frequency;
- par.appbufsz = maxu(device->UpdateSize*device->NumUpdates, (device->Frequency+9)/10);
- par.round = clampu(par.appbufsz/device->NumUpdates, (device->Frequency+99)/100,
- (device->Frequency+19)/20);
+ par.appbufsz = maxu(mDevice->UpdateSize*mDevice->NumUpdates, (mDevice->Frequency+9)/10);
+ par.round = clampu(par.appbufsz/mDevice->NumUpdates, (mDevice->Frequency+99)/100,
+ (mDevice->Frequency+19)/20);
- device->UpdateSize = par.round;
- device->NumUpdates = maxu(par.appbufsz/par.round, 1);
+ mDevice->UpdateSize = par.round;
+ mDevice->NumUpdates = maxu(par.appbufsz/par.round, 1);
- if(!sio_setpar(self->mSndHandle, &par) || !sio_getpar(self->mSndHandle, &par))
+ if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
{
ERR("Failed to set device parameters\n");
return ALC_INVALID_VALUE;
@@ -437,46 +396,46 @@ ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
return ALC_INVALID_VALUE;
}
- if(!((device->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0) ||
- (device->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0) ||
- (device->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0) ||
- (device->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0) ||
- (device->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0) ||
- (device->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0)) ||
- device->channelsFromFmt() != (ALsizei)par.rchan ||
- device->Frequency != par.rate)
+ if(!((mDevice->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0) ||
+ (mDevice->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0) ||
+ (mDevice->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0) ||
+ (mDevice->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0) ||
+ (mDevice->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0) ||
+ (mDevice->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0)) ||
+ mDevice->channelsFromFmt() != (ALsizei)par.rchan ||
+ mDevice->Frequency != par.rate)
{
ERR("Failed to set format %s %s %uhz, got %c%u %u-channel %uhz instead\n",
- DevFmtTypeString(device->FmtType), DevFmtChannelsString(device->FmtChans),
- device->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate);
+ DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
+ mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate);
return ALC_INVALID_VALUE;
}
- self->mRing = CreateRingBuffer(device->UpdateSize*device->NumUpdates, par.bps*par.rchan, false);
- if(!self->mRing)
+ mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates, par.bps*par.rchan, false);
+ if(!mRing)
{
ERR("Failed to allocate %u-byte ringbuffer\n",
- device->UpdateSize*device->NumUpdates*par.bps*par.rchan);
+ mDevice->UpdateSize*mDevice->NumUpdates*par.bps*par.rchan);
return ALC_OUT_OF_MEMORY;
}
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean SndioCapture_start(SndioCapture *self)
+ALCboolean SndioCapture::start()
{
- if(!sio_start(self->mSndHandle))
+ if(!sio_start(mSndHandle))
{
ERR("Error starting playback\n");
return ALC_FALSE;
}
try {
- self->mKillNow.store(false, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&SndioCapture::recordProc), self};
+ mKillNow.store(false, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&SndioCapture::recordProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -484,32 +443,28 @@ ALCboolean SndioCapture_start(SndioCapture *self)
}
catch(...) {
}
- sio_stop(self->mSndHandle);
+ sio_stop(mSndHandle);
return ALC_FALSE;
}
-void SndioCapture_stop(SndioCapture *self)
+void SndioCapture::stop()
{
- if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
- if(!sio_stop(self->mSndHandle))
+ if(!sio_stop(mSndHandle))
ERR("Error stopping device\n");
}
-ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
+ALCenum SndioCapture::captureSamples(void *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
-ALCuint SndioCapture_availableSamples(SndioCapture *self)
-{
- RingBuffer *ring{self->mRing.get()};
- return ring->readSpace();
-}
+ALCuint SndioCapture::availableSamples()
+{ return mRing->readSpace(); }
} // namespace
@@ -537,20 +492,11 @@ void SndIOBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *SndIOBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *SndIOBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- SndioPlayback *backend;
- NEW_OBJ(backend, SndioPlayback)(device);
- return backend;
- }
+ return new SndioPlayback{device};
if(type == ALCbackend_Capture)
- {
- SndioCapture *backend;
- NEW_OBJ(backend, SndioCapture)(device);
- return backend;
- }
-
+ return new SndioCapture{device};
return nullptr;
}
diff --git a/Alc/backends/sndio.h b/Alc/backends/sndio.h
index 20e99afb..bf8d833d 100644
--- a/Alc/backends/sndio.h
+++ b/Alc/backends/sndio.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/solaris.cpp b/Alc/backends/solaris.cpp
index 7d7e3883..6463c225 100644
--- a/Alc/backends/solaris.cpp
+++ b/Alc/backends/solaris.cpp
@@ -54,12 +54,17 @@ constexpr ALCchar solaris_device[] = "Solaris Default";
const char *solaris_driver = "/dev/audio";
-struct SolarisBackend final : public ALCbackend {
- SolarisBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct SolarisBackend final : public BackendBase {
+ SolarisBackend(ALCdevice *device) noexcept : BackendBase{device} { }
~SolarisBackend() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
int mFd{-1};
al::vector<ALubyte> mBuffer;
@@ -68,32 +73,9 @@ struct SolarisBackend final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "SolarisBackend::"; }
+ DEF_NEWDEL(SolarisBackend)
};
-void SolarisBackend_Construct(SolarisBackend *self, ALCdevice *device);
-void SolarisBackend_Destruct(SolarisBackend *self);
-ALCenum SolarisBackend_open(SolarisBackend *self, const ALCchar *name);
-ALCboolean SolarisBackend_reset(SolarisBackend *self);
-ALCboolean SolarisBackend_start(SolarisBackend *self);
-void SolarisBackend_stop(SolarisBackend *self);
-DECLARE_FORWARD2(SolarisBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(SolarisBackend, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(SolarisBackend, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(SolarisBackend, ALCbackend, void, lock)
-DECLARE_FORWARD(SolarisBackend, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(SolarisBackend)
-
-DEFINE_ALCBACKEND_VTABLE(SolarisBackend);
-
-void SolarisBackend_Construct(SolarisBackend *self, ALCdevice *device)
-{
- new (self) SolarisBackend{device};
- SET_VTABLE2(SolarisBackend, ALCbackend, self);
-}
-
-void SolarisBackend_Destruct(SolarisBackend *self)
-{ self->~SolarisBackend(); }
-
SolarisBackend::~SolarisBackend()
{
if(mFd != -1)
@@ -108,7 +90,7 @@ int SolarisBackend::mixerProc()
const int frame_size{mDevice->frameSizeFromFmt()};
- SolarisBackend_lock(this);
+ lock();
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
{
@@ -116,9 +98,9 @@ int SolarisBackend::mixerProc()
pollitem.fd = mFd;
pollitem.events = POLLOUT;
- SolarisBackend_unlock(this);
+ unlock();
int pret{poll(&pollitem, 1, 1000)};
- SolarisBackend_lock(this);
+ lock();
if(pret < 0)
{
if(errno == EINTR || errno == EAGAIN)
@@ -154,49 +136,43 @@ int SolarisBackend::mixerProc()
write_ptr += wrote;
}
}
- SolarisBackend_unlock(this);
+ unlock();
return 0;
}
-ALCenum SolarisBackend_open(SolarisBackend *self, const ALCchar *name)
+ALCenum SolarisBackend::open(const ALCchar *name)
{
if(!name)
name = solaris_device;
else if(strcmp(name, solaris_device) != 0)
return ALC_INVALID_VALUE;
- self->mFd = open(solaris_driver, O_WRONLY);
- if(self->mFd == -1)
+ mFd = ::open(solaris_driver, O_WRONLY);
+ if(mFd == -1)
{
ERR("Could not open %s: %s\n", solaris_driver, strerror(errno));
return ALC_INVALID_VALUE;
}
- ALCdevice *device{self->mDevice};
- device->DeviceName = name;
-
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean SolarisBackend_reset(SolarisBackend *self)
+ALCboolean SolarisBackend::reset()
{
- ALCdevice *device{self->mDevice};
audio_info_t info;
- ALsizei frameSize;
- ALsizei numChannels;
-
AUDIO_INITINFO(&info);
- info.play.sample_rate = device->Frequency;
+ info.play.sample_rate = mDevice->Frequency;
- if(device->FmtChans != DevFmtMono)
- device->FmtChans = DevFmtStereo;
- numChannels = device->channelsFromFmt();
+ if(mDevice->FmtChans != DevFmtMono)
+ mDevice->FmtChans = DevFmtStereo;
+ ALsizei numChannels{mDevice->channelsFromFmt()};
info.play.channels = numChannels;
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
info.play.precision = 8;
@@ -210,7 +186,7 @@ ALCboolean SolarisBackend_reset(SolarisBackend *self)
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
info.play.precision = 16;
@@ -218,48 +194,48 @@ ALCboolean SolarisBackend_reset(SolarisBackend *self)
break;
}
- frameSize = numChannels * device->bytesFromFmt();
- info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize;
+ ALsizei frameSize{numChannels * mDevice->bytesFromFmt()};
+ info.play.buffer_size = mDevice->UpdateSize*mDevice->NumUpdates * frameSize;
- if(ioctl(self->mFd, AUDIO_SETINFO, &info) < 0)
+ if(ioctl(mFd, AUDIO_SETINFO, &info) < 0)
{
ERR("ioctl failed: %s\n", strerror(errno));
return ALC_FALSE;
}
- if(device->channelsFromFmt() != (ALsizei)info.play.channels)
+ if(mDevice->channelsFromFmt() != (ALsizei)info.play.channels)
{
- ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans),
+ ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(mDevice->FmtChans),
info.play.channels);
return ALC_FALSE;
}
- if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && device->FmtType == DevFmtUByte) ||
- (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtByte) ||
- (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtShort) ||
- (info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtInt)))
+ if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && mDevice->FmtType == DevFmtUByte) ||
+ (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && mDevice->FmtType == DevFmtByte) ||
+ (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && mDevice->FmtType == DevFmtShort) ||
+ (info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR && mDevice->FmtType == DevFmtInt)))
{
- ERR("Could not set %s samples, got %d (0x%x)\n", DevFmtTypeString(device->FmtType),
+ ERR("Could not set %s samples, got %d (0x%x)\n", DevFmtTypeString(mDevice->FmtType),
info.play.precision, info.play.encoding);
return ALC_FALSE;
}
- device->Frequency = info.play.sample_rate;
- device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1;
+ mDevice->Frequency = info.play.sample_rate;
+ mDevice->UpdateSize = (info.play.buffer_size/mDevice->NumUpdates) + 1;
- SetDefaultChannelOrder(device);
+ SetDefaultChannelOrder(mDevice);
- self->mBuffer.resize(device->UpdateSize * device->frameSizeFromFmt());
- std::fill(self->mBuffer.begin(), self->mBuffer.end(), 0);
+ mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
+ std::fill(mBuffer.begin(), mBuffer.end(), 0);
return ALC_TRUE;
}
-ALCboolean SolarisBackend_start(SolarisBackend *self)
+ALCboolean SolarisBackend::start()
{
try {
- self->mKillNow.store(false, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&SolarisBackend::mixerProc), self};
+ mKillNow.store(false, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&SolarisBackend::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -270,14 +246,13 @@ ALCboolean SolarisBackend_start(SolarisBackend *self)
return ALC_FALSE;
}
-void SolarisBackend_stop(SolarisBackend *self)
+void SolarisBackend::stop()
{
- if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
return;
+ mThread.join();
- self->mThread.join();
-
- if(ioctl(self->mFd, AUDIO_DRAIN) < 0)
+ if(ioctl(mFd, AUDIO_DRAIN) < 0)
ERR("Error draining device: %s\n", strerror(errno));
}
@@ -317,14 +292,9 @@ void SolarisBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *SolarisBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *SolarisBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- SolarisBackend *backend;
- NEW_OBJ(backend, SolarisBackend)(device);
- return backend;
- }
-
+ return new SolarisBackend{device};
return nullptr;
}
diff --git a/Alc/backends/solaris.h b/Alc/backends/solaris.h
index 73f4a467..f675d6d7 100644
--- a/Alc/backends/solaris.h
+++ b/Alc/backends/solaris.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
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;
}
diff --git a/Alc/backends/wasapi.h b/Alc/backends/wasapi.h
index a94f85df..47bd0e0c 100644
--- a/Alc/backends/wasapi.h
+++ b/Alc/backends/wasapi.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/wave.cpp b/Alc/backends/wave.cpp
index a1951c7b..01948b20 100644
--- a/Alc/backends/wave.cpp
+++ b/Alc/backends/wave.cpp
@@ -78,12 +78,17 @@ void fwrite32le(ALuint val, FILE *f)
}
-struct WaveBackend final : public ALCbackend {
- WaveBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct WaveBackend final : public BackendBase {
+ WaveBackend(ALCdevice *device) noexcept : BackendBase{device} { }
~WaveBackend() override;
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
FILE *mFile{nullptr};
long mDataStart{-1};
@@ -93,32 +98,9 @@ struct WaveBackend final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "WaveBackend::"; }
+ DEF_NEWDEL(WaveBackend)
};
-void WaveBackend_Construct(WaveBackend *self, ALCdevice *device);
-void WaveBackend_Destruct(WaveBackend *self);
-ALCenum WaveBackend_open(WaveBackend *self, const ALCchar *name);
-ALCboolean WaveBackend_reset(WaveBackend *self);
-ALCboolean WaveBackend_start(WaveBackend *self);
-void WaveBackend_stop(WaveBackend *self);
-DECLARE_FORWARD2(WaveBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-DECLARE_FORWARD(WaveBackend, ALCbackend, ALCuint, availableSamples)
-DECLARE_FORWARD(WaveBackend, ALCbackend, ClockLatency, getClockLatency)
-DECLARE_FORWARD(WaveBackend, ALCbackend, void, lock)
-DECLARE_FORWARD(WaveBackend, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(WaveBackend)
-
-DEFINE_ALCBACKEND_VTABLE(WaveBackend);
-
-void WaveBackend_Construct(WaveBackend *self, ALCdevice *device)
-{
- new (self) WaveBackend{device};
- SET_VTABLE2(WaveBackend, ALCbackend, self);
-}
-
-void WaveBackend_Destruct(WaveBackend *self)
-{ self->~WaveBackend(); }
-
WaveBackend::~WaveBackend()
{
if(mFile)
@@ -151,9 +133,9 @@ int WaveBackend::mixerProc()
}
while(avail-done >= mDevice->UpdateSize)
{
- WaveBackend_lock(this);
+ lock();
aluMixData(mDevice, mBuffer.data(), mDevice->UpdateSize);
- WaveBackend_unlock(this);
+ unlock();
done += mDevice->UpdateSize;
if(!IS_LITTLE_ENDIAN)
@@ -189,9 +171,9 @@ int WaveBackend::mixerProc()
if(ferror(mFile))
{
ERR("Error writing to file\n");
- WaveBackend_lock(this);
+ lock();
aluHandleDisconnect(mDevice, "Failed to write playback samples");
- WaveBackend_unlock(this);
+ unlock();
break;
}
}
@@ -212,8 +194,7 @@ int WaveBackend::mixerProc()
return 0;
}
-
-ALCenum WaveBackend_open(WaveBackend *self, const ALCchar *name)
+ALCenum WaveBackend::open(const ALCchar *name)
{
const char *fname{GetConfigValue(nullptr, "wave", "file", "")};
if(!fname[0]) return ALC_INVALID_VALUE;
@@ -226,49 +207,47 @@ ALCenum WaveBackend_open(WaveBackend *self, const ALCchar *name)
#ifdef _WIN32
{
std::wstring wname = utf8_to_wstr(fname);
- self->mFile = _wfopen(wname.c_str(), L"wb");
+ mFile = _wfopen(wname.c_str(), L"wb");
}
#else
- self->mFile = fopen(fname, "wb");
+ mFile = fopen(fname, "wb");
#endif
- if(!self->mFile)
+ if(!mFile)
{
ERR("Could not open file '%s': %s\n", fname, strerror(errno));
return ALC_INVALID_VALUE;
}
- ALCdevice *device{self->mDevice};
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-ALCboolean WaveBackend_reset(WaveBackend *self)
+ALCboolean WaveBackend::reset()
{
- ALCdevice *device{self->mDevice};
ALuint channels=0, bits=0, chanmask=0;
int isbformat = 0;
size_t val;
- fseek(self->mFile, 0, SEEK_SET);
- clearerr(self->mFile);
+ fseek(mFile, 0, SEEK_SET);
+ clearerr(mFile);
if(GetConfigValueBool(nullptr, "wave", "bformat", 0))
{
- device->FmtChans = DevFmtAmbi3D;
- device->mAmbiOrder = 1;
+ mDevice->FmtChans = DevFmtAmbi3D;
+ mDevice->mAmbiOrder = 1;
}
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtByte:
- device->FmtType = DevFmtUByte;
+ mDevice->FmtType = DevFmtUByte;
break;
case DevFmtUShort:
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
break;
case DevFmtUInt:
- device->FmtType = DevFmtInt;
+ mDevice->FmtType = DevFmtInt;
break;
case DevFmtUByte:
case DevFmtShort:
@@ -276,7 +255,7 @@ ALCboolean WaveBackend_reset(WaveBackend *self)
case DevFmtFloat:
break;
}
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono: chanmask = 0x04; break;
case DevFmtStereo: chanmask = 0x01 | 0x02; break;
@@ -287,71 +266,71 @@ ALCboolean WaveBackend_reset(WaveBackend *self)
case DevFmtX71: chanmask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x200 | 0x400; break;
case DevFmtAmbi3D:
/* .amb output requires FuMa */
- device->mAmbiOrder = mini(device->mAmbiOrder, 3);
- device->mAmbiLayout = AmbiLayout::FuMa;
- device->mAmbiScale = AmbiNorm::FuMa;
+ mDevice->mAmbiOrder = mini(mDevice->mAmbiOrder, 3);
+ mDevice->mAmbiLayout = AmbiLayout::FuMa;
+ mDevice->mAmbiScale = AmbiNorm::FuMa;
isbformat = 1;
chanmask = 0;
break;
}
- bits = device->bytesFromFmt() * 8;
- channels = device->channelsFromFmt();
+ bits = mDevice->bytesFromFmt() * 8;
+ channels = mDevice->channelsFromFmt();
- fputs("RIFF", self->mFile);
- fwrite32le(0xFFFFFFFF, self->mFile); // 'RIFF' header len; filled in at close
+ fputs("RIFF", mFile);
+ fwrite32le(0xFFFFFFFF, mFile); // 'RIFF' header len; filled in at close
- fputs("WAVE", self->mFile);
+ fputs("WAVE", mFile);
- fputs("fmt ", self->mFile);
- fwrite32le(40, self->mFile); // 'fmt ' header len; 40 bytes for EXTENSIBLE
+ fputs("fmt ", mFile);
+ fwrite32le(40, mFile); // 'fmt ' header len; 40 bytes for EXTENSIBLE
// 16-bit val, format type id (extensible: 0xFFFE)
- fwrite16le(0xFFFE, self->mFile);
+ fwrite16le(0xFFFE, mFile);
// 16-bit val, channel count
- fwrite16le(channels, self->mFile);
+ fwrite16le(channels, mFile);
// 32-bit val, frequency
- fwrite32le(device->Frequency, self->mFile);
+ fwrite32le(mDevice->Frequency, mFile);
// 32-bit val, bytes per second
- fwrite32le(device->Frequency * channels * bits / 8, self->mFile);
+ fwrite32le(mDevice->Frequency * channels * bits / 8, mFile);
// 16-bit val, frame size
- fwrite16le(channels * bits / 8, self->mFile);
+ fwrite16le(channels * bits / 8, mFile);
// 16-bit val, bits per sample
- fwrite16le(bits, self->mFile);
+ fwrite16le(bits, mFile);
// 16-bit val, extra byte count
- fwrite16le(22, self->mFile);
+ fwrite16le(22, mFile);
// 16-bit val, valid bits per sample
- fwrite16le(bits, self->mFile);
+ fwrite16le(bits, mFile);
// 32-bit val, channel mask
- fwrite32le(chanmask, self->mFile);
+ fwrite32le(chanmask, mFile);
// 16 byte GUID, sub-type format
- val = fwrite((device->FmtType == DevFmtFloat) ?
+ val = fwrite((mDevice->FmtType == DevFmtFloat) ?
(isbformat ? SUBTYPE_BFORMAT_FLOAT : SUBTYPE_FLOAT) :
- (isbformat ? SUBTYPE_BFORMAT_PCM : SUBTYPE_PCM), 1, 16, self->mFile);
+ (isbformat ? SUBTYPE_BFORMAT_PCM : SUBTYPE_PCM), 1, 16, mFile);
(void)val;
- fputs("data", self->mFile);
- fwrite32le(0xFFFFFFFF, self->mFile); // 'data' header len; filled in at close
+ fputs("data", mFile);
+ fwrite32le(0xFFFFFFFF, mFile); // 'data' header len; filled in at close
- if(ferror(self->mFile))
+ if(ferror(mFile))
{
ERR("Error writing header: %s\n", strerror(errno));
return ALC_FALSE;
}
- self->mDataStart = ftell(self->mFile);
+ mDataStart = ftell(mFile);
- SetDefaultWFXChannelOrder(device);
+ SetDefaultWFXChannelOrder(mDevice);
- const ALuint bufsize{device->frameSizeFromFmt() * device->UpdateSize};
- self->mBuffer.resize(bufsize);
+ const ALuint bufsize{mDevice->frameSizeFromFmt() * mDevice->UpdateSize};
+ mBuffer.resize(bufsize);
return ALC_TRUE;
}
-ALCboolean WaveBackend_start(WaveBackend *self)
+ALCboolean WaveBackend::start()
{
try {
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&WaveBackend::mixerProc), self};
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&WaveBackend::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -362,20 +341,20 @@ ALCboolean WaveBackend_start(WaveBackend *self)
return ALC_FALSE;
}
-void WaveBackend_stop(WaveBackend *self)
+void WaveBackend::stop()
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
- long size{ftell(self->mFile)};
+ long size{ftell(mFile)};
if(size > 0)
{
- long dataLen{size - self->mDataStart};
- if(fseek(self->mFile, self->mDataStart-4, SEEK_SET) == 0)
- fwrite32le(dataLen, self->mFile); // 'data' header len
- if(fseek(self->mFile, 4, SEEK_SET) == 0)
- fwrite32le(size-8, self->mFile); // 'WAVE' header len
+ long dataLen{size - mDataStart};
+ if(fseek(mFile, mDataStart-4, SEEK_SET) == 0)
+ fwrite32le(dataLen, mFile); // 'data' header len
+ if(fseek(mFile, 4, SEEK_SET) == 0)
+ fwrite32le(size-8, mFile); // 'WAVE' header len
}
}
@@ -401,15 +380,10 @@ void WaveBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *WaveBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *WaveBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- WaveBackend *backend;
- NEW_OBJ(backend, WaveBackend)(device);
- return backend;
- }
-
+ return new WaveBackend{device};
return nullptr;
}
diff --git a/Alc/backends/wave.h b/Alc/backends/wave.h
index bb51cc71..08d3f0c2 100644
--- a/Alc/backends/wave.h
+++ b/Alc/backends/wave.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};
diff --git a/Alc/backends/winmm.cpp b/Alc/backends/winmm.cpp
index 09b7a2e2..5051aa00 100644
--- a/Alc/backends/winmm.cpp
+++ b/Alc/backends/winmm.cpp
@@ -120,8 +120,8 @@ void ProbeCaptureDevices(void)
}
-struct WinMMPlayback final : public ALCbackend {
- WinMMPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct WinMMPlayback final : public BackendBase {
+ WinMMPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
~WinMMPlayback() override;
static void CALLBACK waveOutProcC(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
@@ -129,6 +129,11 @@ struct WinMMPlayback final : public ALCbackend {
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+
std::atomic<ALuint> mWritable{0u};
al::semaphore mSem;
int mIdx{0};
@@ -142,32 +147,9 @@ struct WinMMPlayback final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "WinMMPlayback::"; }
+ DEF_NEWDEL(WinMMPlayback)
};
-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) WinMMPlayback{device};
- SET_VTABLE2(WinMMPlayback, ALCbackend, self);
-}
-
-void WinMMPlayback_Destruct(WinMMPlayback *self)
-{ self->~WinMMPlayback(); }
-
WinMMPlayback::~WinMMPlayback()
{
if(mOutHdl)
@@ -200,16 +182,16 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
- WinMMPlayback_lock(this);
+ lock();
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
{
ALsizei todo = mWritable.load(std::memory_order_acquire);
if(todo < 1)
{
- WinMMPlayback_unlock(this);
+ unlock();
mSem.wait();
- WinMMPlayback_lock(this);
+ lock();
continue;
}
@@ -224,146 +206,137 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
} while(--todo);
mIdx = widx;
}
- WinMMPlayback_unlock(this);
+ unlock();
return 0;
}
-ALCenum WinMMPlayback_open(WinMMPlayback *self, const ALCchar *deviceName)
+ALCenum WinMMPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
if(PlaybackDevices.empty())
ProbePlaybackDevices();
// Find the Device ID matching the deviceName if valid
- auto iter = deviceName ?
- std::find(PlaybackDevices.cbegin(), PlaybackDevices.cend(), deviceName) :
+ auto iter = name ?
+ std::find(PlaybackDevices.cbegin(), PlaybackDevices.cend(), name) :
PlaybackDevices.cbegin();
if(iter == PlaybackDevices.cend()) return ALC_INVALID_VALUE;
auto DeviceID = static_cast<UINT>(std::distance(PlaybackDevices.cbegin(), iter));
retry_open:
- self->mFormat = WAVEFORMATEX{};
- if(device->FmtType == DevFmtFloat)
+ mFormat = WAVEFORMATEX{};
+ if(mDevice->FmtType == DevFmtFloat)
{
- self->mFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
- self->mFormat.wBitsPerSample = 32;
+ mFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+ mFormat.wBitsPerSample = 32;
}
else
{
- self->mFormat.wFormatTag = WAVE_FORMAT_PCM;
- if(device->FmtType == DevFmtUByte || device->FmtType == DevFmtByte)
- self->mFormat.wBitsPerSample = 8;
+ mFormat.wFormatTag = WAVE_FORMAT_PCM;
+ if(mDevice->FmtType == DevFmtUByte || mDevice->FmtType == DevFmtByte)
+ mFormat.wBitsPerSample = 8;
else
- self->mFormat.wBitsPerSample = 16;
+ mFormat.wBitsPerSample = 16;
}
- self->mFormat.nChannels = ((device->FmtChans == DevFmtMono) ? 1 : 2);
- self->mFormat.nBlockAlign = self->mFormat.wBitsPerSample *
- self->mFormat.nChannels / 8;
- self->mFormat.nSamplesPerSec = device->Frequency;
- self->mFormat.nAvgBytesPerSec = self->mFormat.nSamplesPerSec *
- self->mFormat.nBlockAlign;
- self->mFormat.cbSize = 0;
-
- MMRESULT res{waveOutOpen(&self->mOutHdl, DeviceID, &self->mFormat,
- (DWORD_PTR)&WinMMPlayback::waveOutProcC, (DWORD_PTR)self, CALLBACK_FUNCTION)};
+ mFormat.nChannels = ((mDevice->FmtChans == DevFmtMono) ? 1 : 2);
+ mFormat.nBlockAlign = mFormat.wBitsPerSample * mFormat.nChannels / 8;
+ mFormat.nSamplesPerSec = mDevice->Frequency;
+ mFormat.nAvgBytesPerSec = mFormat.nSamplesPerSec * mFormat.nBlockAlign;
+ mFormat.cbSize = 0;
+
+ MMRESULT res{waveOutOpen(&mOutHdl, DeviceID, &mFormat, (DWORD_PTR)&WinMMPlayback::waveOutProcC,
+ reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION)};
if(res != MMSYSERR_NOERROR)
{
- if(device->FmtType == DevFmtFloat)
+ if(mDevice->FmtType == DevFmtFloat)
{
- device->FmtType = DevFmtShort;
+ mDevice->FmtType = DevFmtShort;
goto retry_open;
}
ERR("waveOutOpen failed: %u\n", res);
return ALC_INVALID_VALUE;
}
- device->DeviceName = PlaybackDevices[DeviceID];
+ mDevice->DeviceName = PlaybackDevices[DeviceID];
return ALC_NO_ERROR;
}
-ALCboolean WinMMPlayback_reset(WinMMPlayback *self)
+ALCboolean WinMMPlayback::reset()
{
- ALCdevice *device{self->mDevice};
+ mDevice->UpdateSize = static_cast<ALuint>(
+ (ALuint64)mDevice->UpdateSize * mFormat.nSamplesPerSec / mDevice->Frequency);
+ mDevice->UpdateSize = (mDevice->UpdateSize*mDevice->NumUpdates + 3) / 4;
+ mDevice->NumUpdates = 4;
+ mDevice->Frequency = mFormat.nSamplesPerSec;
- device->UpdateSize = static_cast<ALuint>(
- (ALuint64)device->UpdateSize * self->mFormat.nSamplesPerSec / device->Frequency);
- device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4;
- device->NumUpdates = 4;
- device->Frequency = self->mFormat.nSamplesPerSec;
-
- if(self->mFormat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
+ if(mFormat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
{
- if(self->mFormat.wBitsPerSample == 32)
- device->FmtType = DevFmtFloat;
+ if(mFormat.wBitsPerSample == 32)
+ mDevice->FmtType = DevFmtFloat;
else
{
- ERR("Unhandled IEEE float sample depth: %d\n", self->mFormat.wBitsPerSample);
+ ERR("Unhandled IEEE float sample depth: %d\n", mFormat.wBitsPerSample);
return ALC_FALSE;
}
}
- else if(self->mFormat.wFormatTag == WAVE_FORMAT_PCM)
+ else if(mFormat.wFormatTag == WAVE_FORMAT_PCM)
{
- if(self->mFormat.wBitsPerSample == 16)
- device->FmtType = DevFmtShort;
- else if(self->mFormat.wBitsPerSample == 8)
- device->FmtType = DevFmtUByte;
+ if(mFormat.wBitsPerSample == 16)
+ mDevice->FmtType = DevFmtShort;
+ else if(mFormat.wBitsPerSample == 8)
+ mDevice->FmtType = DevFmtUByte;
else
{
- ERR("Unhandled PCM sample depth: %d\n", self->mFormat.wBitsPerSample);
+ ERR("Unhandled PCM sample depth: %d\n", mFormat.wBitsPerSample);
return ALC_FALSE;
}
}
else
{
- ERR("Unhandled format tag: 0x%04x\n", self->mFormat.wFormatTag);
+ ERR("Unhandled format tag: 0x%04x\n", mFormat.wFormatTag);
return ALC_FALSE;
}
- if(self->mFormat.nChannels == 2)
- device->FmtChans = DevFmtStereo;
- else if(self->mFormat.nChannels == 1)
- device->FmtChans = DevFmtMono;
+ if(mFormat.nChannels == 2)
+ mDevice->FmtChans = DevFmtStereo;
+ else if(mFormat.nChannels == 1)
+ mDevice->FmtChans = DevFmtMono;
else
{
- ERR("Unhandled channel count: %d\n", self->mFormat.nChannels);
+ ERR("Unhandled channel count: %d\n", mFormat.nChannels);
return ALC_FALSE;
}
- SetDefaultWFXChannelOrder(device);
+ SetDefaultWFXChannelOrder(mDevice);
- ALuint BufferSize{device->UpdateSize * device->frameSizeFromFmt()};
+ ALuint BufferSize{mDevice->UpdateSize * mDevice->frameSizeFromFmt()};
- al_free(self->mWaveBuffer[0].lpData);
- self->mWaveBuffer[0] = WAVEHDR{};
- self->mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16,
- BufferSize * self->mWaveBuffer.size()));
- self->mWaveBuffer[0].dwBufferLength = BufferSize;
- for(size_t i{1};i < self->mWaveBuffer.size();i++)
+ al_free(mWaveBuffer[0].lpData);
+ mWaveBuffer[0] = WAVEHDR{};
+ mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16, BufferSize * mWaveBuffer.size()));
+ mWaveBuffer[0].dwBufferLength = BufferSize;
+ for(size_t i{1};i < mWaveBuffer.size();i++)
{
- self->mWaveBuffer[i] = WAVEHDR{};
- self->mWaveBuffer[i].lpData = self->mWaveBuffer[i-1].lpData +
- self->mWaveBuffer[i-1].dwBufferLength;
- self->mWaveBuffer[i].dwBufferLength = BufferSize;
+ mWaveBuffer[i] = WAVEHDR{};
+ mWaveBuffer[i].lpData = mWaveBuffer[i-1].lpData + mWaveBuffer[i-1].dwBufferLength;
+ mWaveBuffer[i].dwBufferLength = BufferSize;
}
- self->mIdx = 0;
+ mIdx = 0;
return ALC_TRUE;
}
-ALCboolean WinMMPlayback_start(WinMMPlayback *self)
+ALCboolean WinMMPlayback::start()
{
try {
- std::for_each(self->mWaveBuffer.begin(), self->mWaveBuffer.end(),
- [self](WAVEHDR &waveHdr) -> void
- { waveOutPrepareHeader(self->mOutHdl, &waveHdr, static_cast<UINT>(sizeof(WAVEHDR))); }
+ std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
+ [this](WAVEHDR &waveHdr) -> void
+ { waveOutPrepareHeader(mOutHdl, &waveHdr, static_cast<UINT>(sizeof(WAVEHDR))); }
);
- self->mWritable.store(static_cast<ALuint>(self->mWaveBuffer.size()),
- std::memory_order_release);
+ mWritable.store(static_cast<ALuint>(mWaveBuffer.size()), std::memory_order_release);
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&WinMMPlayback::mixerProc), self};
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&WinMMPlayback::mixerProc), this};
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -374,24 +347,24 @@ ALCboolean WinMMPlayback_start(WinMMPlayback *self)
return ALC_FALSE;
}
-void WinMMPlayback_stop(WinMMPlayback *self)
+void WinMMPlayback::stop()
{
- if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !mThread.joinable())
return;
- self->mThread.join();
+ mThread.join();
- while(self->mWritable.load(std::memory_order_acquire) < self->mWaveBuffer.size())
- self->mSem.wait();
- std::for_each(self->mWaveBuffer.begin(), self->mWaveBuffer.end(),
- [self](WAVEHDR &waveHdr) -> void
- { waveOutUnprepareHeader(self->mOutHdl, &waveHdr, sizeof(WAVEHDR)); }
+ while(mWritable.load(std::memory_order_acquire) < mWaveBuffer.size())
+ mSem.wait();
+ std::for_each(mWaveBuffer.begin(), mWaveBuffer.end(),
+ [this](WAVEHDR &waveHdr) -> void
+ { waveOutUnprepareHeader(mOutHdl, &waveHdr, sizeof(WAVEHDR)); }
);
- self->mWritable.store(0, std::memory_order_release);
+ mWritable.store(0, std::memory_order_release);
}
-struct WinMMCapture final : public ALCbackend {
- WinMMCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
+struct WinMMCapture final : public BackendBase {
+ WinMMCapture(ALCdevice *device) noexcept : BackendBase{device} { }
~WinMMCapture() override;
static void CALLBACK waveInProcC(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
@@ -399,6 +372,12 @@ struct WinMMCapture final : public ALCbackend {
int captureProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
std::atomic<ALuint> mReadable{0u};
al::semaphore mSem;
int mIdx{0};
@@ -414,32 +393,9 @@ struct WinMMCapture final : public ALCbackend {
std::thread mThread;
static constexpr inline const char *CurrentPrefix() noexcept { return "WinMMCapture::"; }
+ DEF_NEWDEL(WinMMCapture)
};
-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) WinMMCapture{device};
- SET_VTABLE2(WinMMCapture, ALCbackend, self);
-}
-
-void WinMMCapture_Destruct(WinMMCapture *self)
-{ self->~WinMMCapture(); }
-
WinMMCapture::~WinMMCapture()
{
// Close the Wave device
@@ -471,16 +427,16 @@ int WinMMCapture::captureProc()
{
althrd_setname(RECORD_THREAD_NAME);
- WinMMCapture_lock(this);
+ lock();
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
{
ALuint todo{mReadable.load(std::memory_order_acquire)};
if(todo < 1)
{
- WinMMCapture_unlock(this);
+ unlock();
mSem.wait();
- WinMMCapture_lock(this);
+ lock();
continue;
}
@@ -495,27 +451,25 @@ int WinMMCapture::captureProc()
} while(--todo);
mIdx = widx;
}
- WinMMCapture_unlock(this);
+ unlock();
return 0;
}
-ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName)
+ALCenum WinMMCapture::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
-
if(CaptureDevices.empty())
ProbeCaptureDevices();
// Find the Device ID matching the deviceName if valid
- auto iter = deviceName ?
- std::find(CaptureDevices.cbegin(), CaptureDevices.cend(), deviceName) :
+ auto iter = name ?
+ std::find(CaptureDevices.cbegin(), CaptureDevices.cend(), name) :
CaptureDevices.cbegin();
if(iter == CaptureDevices.cend()) return ALC_INVALID_VALUE;
auto DeviceID = static_cast<UINT>(std::distance(CaptureDevices.cbegin(), iter));
- switch(device->FmtChans)
+ switch(mDevice->FmtChans)
{
case DevFmtMono:
case DevFmtStereo:
@@ -530,7 +484,7 @@ ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName)
return ALC_INVALID_ENUM;
}
- switch(device->FmtType)
+ switch(mDevice->FmtType)
{
case DevFmtUByte:
case DevFmtShort:
@@ -544,21 +498,18 @@ ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName)
return ALC_INVALID_ENUM;
}
- self->mFormat = WAVEFORMATEX{};
- self->mFormat.wFormatTag = (device->FmtType == DevFmtFloat) ?
- WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM;
- self->mFormat.nChannels = device->channelsFromFmt();
- self->mFormat.wBitsPerSample = device->bytesFromFmt() * 8;
- self->mFormat.nBlockAlign = self->mFormat.wBitsPerSample *
- self->mFormat.nChannels / 8;
- self->mFormat.nSamplesPerSec = device->Frequency;
- self->mFormat.nAvgBytesPerSec = self->mFormat.nSamplesPerSec *
- self->mFormat.nBlockAlign;
- self->mFormat.cbSize = 0;
-
- MMRESULT res{waveInOpen(&self->mInHdl, DeviceID, &self->mFormat,
- (DWORD_PTR)&WinMMCapture::waveInProcC, (DWORD_PTR)self, CALLBACK_FUNCTION
- )};
+ mFormat = WAVEFORMATEX{};
+ mFormat.wFormatTag = (mDevice->FmtType == DevFmtFloat) ?
+ WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM;
+ mFormat.nChannels = mDevice->channelsFromFmt();
+ mFormat.wBitsPerSample = mDevice->bytesFromFmt() * 8;
+ mFormat.nBlockAlign = mFormat.wBitsPerSample * mFormat.nChannels / 8;
+ mFormat.nSamplesPerSec = mDevice->Frequency;
+ mFormat.nAvgBytesPerSec = mFormat.nSamplesPerSec * mFormat.nBlockAlign;
+ mFormat.cbSize = 0;
+
+ MMRESULT res{waveInOpen(&mInHdl, DeviceID, &mFormat, (DWORD_PTR)&WinMMCapture::waveInProcC,
+ reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION)};
if(res != MMSYSERR_NOERROR)
{
ERR("waveInOpen failed: %u\n", res);
@@ -566,47 +517,46 @@ ALCenum WinMMCapture_open(WinMMCapture *self, const ALCchar *deviceName)
}
// Ensure each buffer is 50ms each
- DWORD BufferSize{self->mFormat.nAvgBytesPerSec / 20u};
- BufferSize -= (BufferSize % self->mFormat.nBlockAlign);
+ DWORD BufferSize{mFormat.nAvgBytesPerSec / 20u};
+ BufferSize -= (BufferSize % mFormat.nBlockAlign);
// Allocate circular memory buffer for the captured audio
// Make sure circular buffer is at least 100ms in size
- ALuint CapturedDataSize{device->UpdateSize*device->NumUpdates};
+ ALuint CapturedDataSize{mDevice->UpdateSize*mDevice->NumUpdates};
CapturedDataSize = static_cast<ALuint>(
- std::max<size_t>(CapturedDataSize, BufferSize*self->mWaveBuffer.size()));
+ std::max<size_t>(CapturedDataSize, BufferSize*mWaveBuffer.size()));
- self->mRing = CreateRingBuffer(CapturedDataSize, self->mFormat.nBlockAlign, false);
- if(!self->mRing) return ALC_INVALID_VALUE;
+ mRing = CreateRingBuffer(CapturedDataSize, mFormat.nBlockAlign, false);
+ if(!mRing) return ALC_INVALID_VALUE;
- al_free(self->mWaveBuffer[0].lpData);
- self->mWaveBuffer[0] = WAVEHDR{};
- self->mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16, BufferSize*4));
- self->mWaveBuffer[0].dwBufferLength = BufferSize;
- for(size_t i{1};i < self->mWaveBuffer.size();++i)
+ al_free(mWaveBuffer[0].lpData);
+ mWaveBuffer[0] = WAVEHDR{};
+ mWaveBuffer[0].lpData = static_cast<char*>(al_calloc(16, BufferSize*4));
+ mWaveBuffer[0].dwBufferLength = BufferSize;
+ for(size_t i{1};i < mWaveBuffer.size();++i)
{
- self->mWaveBuffer[i] = WAVEHDR{};
- self->mWaveBuffer[i].lpData = self->mWaveBuffer[i-1].lpData +
- self->mWaveBuffer[i-1].dwBufferLength;
- self->mWaveBuffer[i].dwBufferLength = self->mWaveBuffer[i-1].dwBufferLength;
+ mWaveBuffer[i] = WAVEHDR{};
+ mWaveBuffer[i].lpData = mWaveBuffer[i-1].lpData + mWaveBuffer[i-1].dwBufferLength;
+ mWaveBuffer[i].dwBufferLength = mWaveBuffer[i-1].dwBufferLength;
}
- device->DeviceName = CaptureDevices[DeviceID];
+ mDevice->DeviceName = CaptureDevices[DeviceID];
return ALC_NO_ERROR;
}
-ALCboolean WinMMCapture_start(WinMMCapture *self)
+ALCboolean WinMMCapture::start()
{
try {
- for(size_t i{0};i < self->mWaveBuffer.size();++i)
+ for(size_t i{0};i < mWaveBuffer.size();++i)
{
- waveInPrepareHeader(self->mInHdl, &self->mWaveBuffer[i], sizeof(WAVEHDR));
- waveInAddBuffer(self->mInHdl, &self->mWaveBuffer[i], sizeof(WAVEHDR));
+ waveInPrepareHeader(mInHdl, &mWaveBuffer[i], sizeof(WAVEHDR));
+ waveInAddBuffer(mInHdl, &mWaveBuffer[i], sizeof(WAVEHDR));
}
- self->mKillNow.store(AL_FALSE, std::memory_order_release);
- self->mThread = std::thread{std::mem_fn(&WinMMCapture::captureProc), self};
+ mKillNow.store(AL_FALSE, std::memory_order_release);
+ mThread = std::thread{std::mem_fn(&WinMMCapture::captureProc), this};
- waveInStart(self->mInHdl);
+ waveInStart(mInHdl);
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -617,37 +567,33 @@ ALCboolean WinMMCapture_start(WinMMCapture *self)
return ALC_FALSE;
}
-void WinMMCapture_stop(WinMMCapture *self)
+void WinMMCapture::stop()
{
- waveInStop(self->mInHdl);
+ waveInStop(mInHdl);
- self->mKillNow.store(AL_TRUE, std::memory_order_release);
- if(self->mThread.joinable())
+ mKillNow.store(AL_TRUE, std::memory_order_release);
+ if(mThread.joinable())
{
- self->mSem.post();
- self->mThread.join();
+ mSem.post();
+ mThread.join();
}
- waveInReset(self->mInHdl);
- for(size_t i{0};i < self->mWaveBuffer.size();++i)
- waveInUnprepareHeader(self->mInHdl, &self->mWaveBuffer[i], sizeof(WAVEHDR));
+ waveInReset(mInHdl);
+ for(size_t i{0};i < mWaveBuffer.size();++i)
+ waveInUnprepareHeader(mInHdl, &mWaveBuffer[i], sizeof(WAVEHDR));
- self->mReadable.store(0, std::memory_order_release);
- self->mIdx = 0;
+ mReadable.store(0, std::memory_order_release);
+ mIdx = 0;
}
-ALCenum WinMMCapture_captureSamples(WinMMCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum WinMMCapture::captureSamples(void *buffer, ALCuint samples)
{
- RingBuffer *ring{self->mRing.get()};
- ring->read(buffer, samples);
+ mRing->read(buffer, samples);
return ALC_NO_ERROR;
}
-ALCuint WinMMCapture_availableSamples(WinMMCapture *self)
-{
- RingBuffer *ring{self->mRing.get()};
- return (ALCuint)ring->readSpace();
-}
+ALCuint WinMMCapture::availableSamples()
+{ return (ALCuint)mRing->readSpace(); }
} // namespace
@@ -688,21 +634,12 @@ void WinMMBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *WinMMBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *WinMMBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- WinMMPlayback *backend;
- NEW_OBJ(backend, WinMMPlayback)(device);
- return backend;
- }
+ return new WinMMPlayback{device};
if(type == ALCbackend_Capture)
- {
- WinMMCapture *backend;
- NEW_OBJ(backend, WinMMCapture)(device);
- return backend;
- }
-
+ return new WinMMCapture{device};
return nullptr;
}
diff --git a/Alc/backends/winmm.h b/Alc/backends/winmm.h
index e5801c01..63be6598 100644
--- a/Alc/backends/winmm.h
+++ b/Alc/backends/winmm.h
@@ -12,7 +12,7 @@ public:
void probe(DevProbe type, std::string *outnames) override;
- ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
+ BackendBase *createBackend(ALCdevice *device, ALCbackend_Type type) override;
static BackendFactory &getFactory();
};