aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/sndio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends/sndio.cpp')
-rw-r--r--Alc/backends/sndio.cpp258
1 files changed, 102 insertions, 156 deletions
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;
}