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