Turn even more methods into member functions
This commit is contained in:
+17
-13
@@ -171,9 +171,10 @@ void deviceList(int type, al::vector<DevMap> *devmap)
|
||||
|
||||
/* Wrappers to use an old-style backend with the new interface. */
|
||||
struct PlaybackWrapper final : public ALCbackend {
|
||||
std::unique_ptr<qsa_data> mExtraData;
|
||||
|
||||
PlaybackWrapper(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~PlaybackWrapper() override;
|
||||
|
||||
std::unique_ptr<qsa_data> mExtraData;
|
||||
};
|
||||
|
||||
static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device);
|
||||
@@ -620,11 +621,12 @@ static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device)
|
||||
}
|
||||
|
||||
static void PlaybackWrapper_Destruct(PlaybackWrapper *self)
|
||||
{
|
||||
if(self->mExtraData)
|
||||
qsa_close_playback(self);
|
||||
{ self->~PlaybackWrapper(); }
|
||||
|
||||
self->~PlaybackWrapper();
|
||||
PlaybackWrapper::~PlaybackWrapper()
|
||||
{
|
||||
if(mExtraData)
|
||||
qsa_close_playback(this);
|
||||
}
|
||||
|
||||
static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name)
|
||||
@@ -654,9 +656,10 @@ static void PlaybackWrapper_stop(PlaybackWrapper *self)
|
||||
/***********/
|
||||
|
||||
struct CaptureWrapper final : public ALCbackend {
|
||||
std::unique_ptr<qsa_data> mExtraData;
|
||||
|
||||
CaptureWrapper(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~CaptureWrapper() override;
|
||||
|
||||
std::unique_ptr<qsa_data> mExtraData;
|
||||
};
|
||||
|
||||
static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device);
|
||||
@@ -778,7 +781,7 @@ static void qsa_close_capture(CaptureWrapper *self)
|
||||
|
||||
if (data->pcmHandle!=nullptr)
|
||||
snd_pcm_close(data->pcmHandle);
|
||||
data->pcmHandle = nullptr
|
||||
data->pcmHandle = nullptr;
|
||||
|
||||
self->mExtraData = nullptr;
|
||||
}
|
||||
@@ -921,11 +924,12 @@ static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device)
|
||||
}
|
||||
|
||||
static void CaptureWrapper_Destruct(CaptureWrapper *self)
|
||||
{
|
||||
if(self->mExtraData)
|
||||
qsa_close_capture(self);
|
||||
{ self->~CaptureWrapper(); }
|
||||
|
||||
self->~CaptureWrapper();
|
||||
CaptureWrapper::~CaptureWrapper()
|
||||
{
|
||||
if(mExtraData)
|
||||
qsa_close_capture(this);
|
||||
}
|
||||
|
||||
static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name)
|
||||
|
||||
+43
-38
@@ -33,13 +33,23 @@
|
||||
#include "compat.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DEVNAME_PREFIX "OpenAL Soft on "
|
||||
#else
|
||||
#define DEVNAME_PREFIX ""
|
||||
#endif
|
||||
|
||||
constexpr ALCchar defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
|
||||
|
||||
struct ALCsdl2Backend final : public ALCbackend {
|
||||
ALCsdl2Backend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~ALCsdl2Backend() override;
|
||||
|
||||
static void audioCallbackC(void *ptr, Uint8 *stream, int len);
|
||||
void audioCallback(Uint8 *stream, int len);
|
||||
|
||||
SDL_AudioDeviceID mDeviceID{0u};
|
||||
ALsizei mFrameSize{0};
|
||||
|
||||
@@ -47,58 +57,52 @@ struct ALCsdl2Backend final : public ALCbackend {
|
||||
DevFmtChannels mFmtChans{};
|
||||
DevFmtType mFmtType{};
|
||||
ALuint mUpdateSize{0u};
|
||||
|
||||
ALCsdl2Backend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
};
|
||||
|
||||
static void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device);
|
||||
static void ALCsdl2Backend_Destruct(ALCsdl2Backend *self);
|
||||
static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name);
|
||||
static ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self);
|
||||
static ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self);
|
||||
static void ALCsdl2Backend_stop(ALCsdl2Backend *self);
|
||||
static DECLARE_FORWARD2(ALCsdl2Backend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
|
||||
static DECLARE_FORWARD(ALCsdl2Backend, ALCbackend, ALCuint, availableSamples)
|
||||
static DECLARE_FORWARD(ALCsdl2Backend, ALCbackend, ClockLatency, getClockLatency)
|
||||
static void ALCsdl2Backend_lock(ALCsdl2Backend *self);
|
||||
static void ALCsdl2Backend_unlock(ALCsdl2Backend *self);
|
||||
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);
|
||||
|
||||
static const ALCchar defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
|
||||
|
||||
static void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device)
|
||||
void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device)
|
||||
{
|
||||
new (self) ALCsdl2Backend{device};
|
||||
SET_VTABLE2(ALCsdl2Backend, ALCbackend, self);
|
||||
}
|
||||
|
||||
static void ALCsdl2Backend_Destruct(ALCsdl2Backend *self)
|
||||
{
|
||||
if(self->mDeviceID)
|
||||
SDL_CloseAudioDevice(self->mDeviceID);
|
||||
self->mDeviceID = 0;
|
||||
void ALCsdl2Backend_Destruct(ALCsdl2Backend *self)
|
||||
{ self->~ALCsdl2Backend(); }
|
||||
|
||||
self->~ALCsdl2Backend();
|
||||
ALCsdl2Backend::~ALCsdl2Backend()
|
||||
{
|
||||
if(mDeviceID)
|
||||
SDL_CloseAudioDevice(mDeviceID);
|
||||
mDeviceID = 0;
|
||||
}
|
||||
|
||||
void ALCsdl2Backend::audioCallbackC(void *ptr, Uint8 *stream, int len)
|
||||
{ static_cast<ALCsdl2Backend*>(ptr)->audioCallback(stream, len); }
|
||||
|
||||
static void ALCsdl2Backend_audioCallback(void *ptr, Uint8 *stream, int len)
|
||||
void ALCsdl2Backend::audioCallback(Uint8 *stream, int len)
|
||||
{
|
||||
auto self = static_cast<ALCsdl2Backend*>(ptr);
|
||||
|
||||
assert((len % self->mFrameSize) == 0);
|
||||
aluMixData(self->mDevice, stream, len / self->mFrameSize);
|
||||
assert((len % mFrameSize) == 0);
|
||||
aluMixData(mDevice, stream, len / mFrameSize);
|
||||
}
|
||||
|
||||
static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
|
||||
ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
SDL_AudioSpec want, have;
|
||||
|
||||
SDL_zero(want);
|
||||
SDL_zero(have);
|
||||
SDL_AudioSpec want{}, have{};
|
||||
|
||||
want.freq = device->Frequency;
|
||||
switch(device->FmtType)
|
||||
@@ -113,7 +117,7 @@ static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
|
||||
}
|
||||
want.channels = (device->FmtChans == DevFmtMono) ? 1 : 2;
|
||||
want.samples = device->UpdateSize;
|
||||
want.callback = ALCsdl2Backend_audioCallback;
|
||||
want.callback = &ALCsdl2Backend::audioCallbackC;
|
||||
want.userdata = self;
|
||||
|
||||
/* Passing nullptr to SDL_OpenAudioDevice opens a default, which isn't
|
||||
@@ -170,7 +174,7 @@ static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self)
|
||||
ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
device->Frequency = self->mFrequency;
|
||||
@@ -182,27 +186,28 @@ static ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self)
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self)
|
||||
ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self)
|
||||
{
|
||||
SDL_PauseAudioDevice(self->mDeviceID, 0);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void ALCsdl2Backend_stop(ALCsdl2Backend *self)
|
||||
void ALCsdl2Backend_stop(ALCsdl2Backend *self)
|
||||
{
|
||||
SDL_PauseAudioDevice(self->mDeviceID, 1);
|
||||
}
|
||||
|
||||
static void ALCsdl2Backend_lock(ALCsdl2Backend *self)
|
||||
void ALCsdl2Backend_lock(ALCsdl2Backend *self)
|
||||
{
|
||||
SDL_LockAudioDevice(self->mDeviceID);
|
||||
}
|
||||
|
||||
static void ALCsdl2Backend_unlock(ALCsdl2Backend *self)
|
||||
void ALCsdl2Backend_unlock(ALCsdl2Backend *self)
|
||||
{
|
||||
SDL_UnlockAudioDevice(self->mDeviceID);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BackendFactory &SDL2BackendFactory::getFactory()
|
||||
{
|
||||
|
||||
+90
-94
@@ -43,6 +43,11 @@ static const ALCchar sndio_device[] = "SndIO Default";
|
||||
|
||||
|
||||
struct SndioPlayback final : public ALCbackend {
|
||||
SndioPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~SndioPlayback() override;
|
||||
|
||||
int mixerProc();
|
||||
|
||||
sio_hdl *mSndHandle{nullptr};
|
||||
|
||||
al::vector<ALubyte> mBuffer;
|
||||
@@ -50,70 +55,65 @@ struct SndioPlayback final : public ALCbackend {
|
||||
std::atomic<bool> mKillNow{true};
|
||||
std::thread mThread;
|
||||
|
||||
SndioPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
static constexpr inline const char *CurrentPrefix() noexcept { return "SndioPlayback::"; }
|
||||
};
|
||||
|
||||
static int SndioPlayback_mixerProc(SndioPlayback *self);
|
||||
|
||||
static void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device);
|
||||
static void SndioPlayback_Destruct(SndioPlayback *self);
|
||||
static ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name);
|
||||
static ALCboolean SndioPlayback_reset(SndioPlayback *self);
|
||||
static ALCboolean SndioPlayback_start(SndioPlayback *self);
|
||||
static void SndioPlayback_stop(SndioPlayback *self);
|
||||
static DECLARE_FORWARD2(SndioPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
|
||||
static DECLARE_FORWARD(SndioPlayback, ALCbackend, ALCuint, availableSamples)
|
||||
static DECLARE_FORWARD(SndioPlayback, ALCbackend, ClockLatency, getClockLatency)
|
||||
static DECLARE_FORWARD(SndioPlayback, ALCbackend, void, lock)
|
||||
static DECLARE_FORWARD(SndioPlayback, ALCbackend, void, unlock)
|
||||
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);
|
||||
|
||||
|
||||
static void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device)
|
||||
void SndioPlayback_Construct(SndioPlayback *self, ALCdevice *device)
|
||||
{
|
||||
new (self) SndioPlayback{device};
|
||||
SET_VTABLE2(SndioPlayback, ALCbackend, self);
|
||||
}
|
||||
|
||||
static void SndioPlayback_Destruct(SndioPlayback *self)
|
||||
{
|
||||
if(self->mSndHandle)
|
||||
sio_close(self->mSndHandle);
|
||||
self->mSndHandle = nullptr;
|
||||
void SndioPlayback_Destruct(SndioPlayback *self)
|
||||
{ self->~SndioPlayback(); }
|
||||
|
||||
self->~SndioPlayback();
|
||||
SndioPlayback::~SndioPlayback()
|
||||
{
|
||||
if(mSndHandle)
|
||||
sio_close(mSndHandle);
|
||||
mSndHandle = nullptr;
|
||||
}
|
||||
|
||||
|
||||
static int SndioPlayback_mixerProc(SndioPlayback *self)
|
||||
int SndioPlayback::mixerProc()
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
|
||||
SetRTPriority();
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
const ALsizei frameSize{device->frameSizeFromFmt()};
|
||||
const ALsizei frameSize{mDevice->frameSizeFromFmt()};
|
||||
|
||||
while(!self->mKillNow.load(std::memory_order_acquire) &&
|
||||
device->Connected.load(std::memory_order_acquire))
|
||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
||||
mDevice->Connected.load(std::memory_order_acquire))
|
||||
{
|
||||
auto WritePtr = static_cast<ALubyte*>(self->mBuffer.data());
|
||||
size_t len{self->mBuffer.size()};
|
||||
auto WritePtr = static_cast<ALubyte*>(mBuffer.data());
|
||||
size_t len{mBuffer.size()};
|
||||
|
||||
SndioPlayback_lock(self);
|
||||
aluMixData(device, WritePtr, len/frameSize);
|
||||
SndioPlayback_unlock(self);
|
||||
while(len > 0 && !self->mKillNow.load(std::memory_order_acquire))
|
||||
SndioPlayback_lock(this);
|
||||
aluMixData(mDevice, WritePtr, len/frameSize);
|
||||
SndioPlayback_unlock(this);
|
||||
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
|
||||
{
|
||||
size_t wrote{sio_write(self->mSndHandle, WritePtr, len)};
|
||||
size_t wrote{sio_write(mSndHandle, WritePtr, len)};
|
||||
if(wrote == 0)
|
||||
{
|
||||
ERR("sio_write failed\n");
|
||||
SndioPlayback_lock(self);
|
||||
aluHandleDisconnect(device, "Failed to write playback samples");
|
||||
SndioPlayback_unlock(self);
|
||||
SndioPlayback_lock(this);
|
||||
aluHandleDisconnect(mDevice, "Failed to write playback samples");
|
||||
SndioPlayback_unlock(this);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ static int SndioPlayback_mixerProc(SndioPlayback *self)
|
||||
}
|
||||
|
||||
|
||||
static ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name)
|
||||
ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
|
||||
@@ -146,7 +146,7 @@ static ALCenum SndioPlayback_open(SndioPlayback *self, const ALCchar *name)
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCboolean SndioPlayback_reset(SndioPlayback *self)
|
||||
ALCboolean SndioPlayback_reset(SndioPlayback *self)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
sio_par par;
|
||||
@@ -234,7 +234,7 @@ static ALCboolean SndioPlayback_reset(SndioPlayback *self)
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean SndioPlayback_start(SndioPlayback *self)
|
||||
ALCboolean SndioPlayback_start(SndioPlayback *self)
|
||||
{
|
||||
if(!sio_start(self->mSndHandle))
|
||||
{
|
||||
@@ -244,7 +244,7 @@ static ALCboolean SndioPlayback_start(SndioPlayback *self)
|
||||
|
||||
try {
|
||||
self->mKillNow.store(false, std::memory_order_release);
|
||||
self->mThread = std::thread(SndioPlayback_mixerProc, self);
|
||||
self->mThread = std::thread{std::mem_fn(&SndioPlayback::mixerProc), self};
|
||||
return ALC_TRUE;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
@@ -256,7 +256,7 @@ static ALCboolean SndioPlayback_start(SndioPlayback *self)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void SndioPlayback_stop(SndioPlayback *self)
|
||||
void SndioPlayback_stop(SndioPlayback *self)
|
||||
{
|
||||
if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
|
||||
return;
|
||||
@@ -268,6 +268,11 @@ static void SndioPlayback_stop(SndioPlayback *self)
|
||||
|
||||
|
||||
struct SndioCapture final : public ALCbackend {
|
||||
SndioCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~SndioCapture() override;
|
||||
|
||||
int recordProc();
|
||||
|
||||
sio_hdl *mSndHandle{nullptr};
|
||||
|
||||
RingBufferPtr mRing;
|
||||
@@ -275,84 +280,75 @@ struct SndioCapture final : public ALCbackend {
|
||||
std::atomic<bool> mKillNow{true};
|
||||
std::thread mThread;
|
||||
|
||||
SndioCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
static constexpr inline const char *CurrentPrefix() noexcept { return "SndioCapture::"; }
|
||||
};
|
||||
|
||||
static int SndioCapture_recordProc(SndioCapture *self);
|
||||
|
||||
static void SndioCapture_Construct(SndioCapture *self, ALCdevice *device);
|
||||
static void SndioCapture_Destruct(SndioCapture *self);
|
||||
static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name);
|
||||
static DECLARE_FORWARD(SndioCapture, ALCbackend, ALCboolean, reset)
|
||||
static ALCboolean SndioCapture_start(SndioCapture *self);
|
||||
static void SndioCapture_stop(SndioCapture *self);
|
||||
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples);
|
||||
static ALCuint SndioCapture_availableSamples(SndioCapture *self);
|
||||
static DECLARE_FORWARD(SndioCapture, ALCbackend, ClockLatency, getClockLatency)
|
||||
static DECLARE_FORWARD(SndioCapture, ALCbackend, void, lock)
|
||||
static DECLARE_FORWARD(SndioCapture, ALCbackend, void, unlock)
|
||||
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);
|
||||
|
||||
|
||||
static void SndioCapture_Construct(SndioCapture *self, ALCdevice *device)
|
||||
void SndioCapture_Construct(SndioCapture *self, ALCdevice *device)
|
||||
{
|
||||
new (self) SndioCapture{device};
|
||||
SET_VTABLE2(SndioCapture, ALCbackend, self);
|
||||
}
|
||||
|
||||
static void SndioCapture_Destruct(SndioCapture *self)
|
||||
{
|
||||
if(self->mSndHandle)
|
||||
sio_close(self->mSndHandle);
|
||||
self->mSndHandle = nullptr;
|
||||
void SndioCapture_Destruct(SndioCapture *self)
|
||||
{ self->~SndioCapture(); }
|
||||
|
||||
self->~SndioCapture();
|
||||
SndioCapture::~SndioCapture()
|
||||
{
|
||||
if(mSndHandle)
|
||||
sio_close(mSndHandle);
|
||||
mSndHandle = nullptr;
|
||||
}
|
||||
|
||||
|
||||
static int SndioCapture_recordProc(SndioCapture *self)
|
||||
int SndioCapture::recordProc()
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
RingBuffer *ring{self->mRing.get()};
|
||||
|
||||
SetRTPriority();
|
||||
althrd_setname(RECORD_THREAD_NAME);
|
||||
|
||||
const ALsizei frameSize{device->frameSizeFromFmt()};
|
||||
const ALsizei frameSize{mDevice->frameSizeFromFmt()};
|
||||
|
||||
while(!self->mKillNow.load(std::memory_order_acquire) &&
|
||||
device->Connected.load(std::memory_order_acquire))
|
||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
||||
mDevice->Connected.load(std::memory_order_acquire))
|
||||
{
|
||||
size_t total, todo;
|
||||
|
||||
auto data = ring->getWriteVector();
|
||||
todo = data.first.len + data.second.len;
|
||||
auto data = mRing->getWriteVector();
|
||||
size_t todo{data.first.len + data.second.len};
|
||||
if(todo == 0)
|
||||
{
|
||||
static char junk[4096];
|
||||
sio_read(self->mSndHandle, junk, minz(sizeof(junk)/frameSize, device->UpdateSize)*frameSize);
|
||||
sio_read(mSndHandle, junk,
|
||||
minz(sizeof(junk)/frameSize, mDevice->UpdateSize)*frameSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
size_t total{0u};
|
||||
data.first.len *= frameSize;
|
||||
data.second.len *= frameSize;
|
||||
todo = minz(todo, device->UpdateSize) * frameSize;
|
||||
todo = minz(todo, mDevice->UpdateSize) * frameSize;
|
||||
while(total < todo)
|
||||
{
|
||||
size_t got;
|
||||
|
||||
if(!data.first.len)
|
||||
data.first = data.second;
|
||||
|
||||
got = sio_read(self->mSndHandle, data.first.buf, minz(todo-total, data.first.len));
|
||||
size_t got{sio_read(mSndHandle, data.first.buf, minz(todo-total, data.first.len))};
|
||||
if(!got)
|
||||
{
|
||||
SndioCapture_lock(self);
|
||||
aluHandleDisconnect(device, "Failed to read capture samples");
|
||||
SndioCapture_unlock(self);
|
||||
SndioCapture_lock(this);
|
||||
aluHandleDisconnect(mDevice, "Failed to read capture samples");
|
||||
SndioCapture_unlock(this);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -360,14 +356,14 @@ static int SndioCapture_recordProc(SndioCapture *self)
|
||||
data.first.len -= got;
|
||||
total += got;
|
||||
}
|
||||
ring->writeAdvance(total / frameSize);
|
||||
mRing->writeAdvance(total / frameSize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
|
||||
ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
sio_par par;
|
||||
@@ -470,7 +466,7 @@ static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCboolean SndioCapture_start(SndioCapture *self)
|
||||
ALCboolean SndioCapture_start(SndioCapture *self)
|
||||
{
|
||||
if(!sio_start(self->mSndHandle))
|
||||
{
|
||||
@@ -480,7 +476,7 @@ static ALCboolean SndioCapture_start(SndioCapture *self)
|
||||
|
||||
try {
|
||||
self->mKillNow.store(false, std::memory_order_release);
|
||||
self->mThread = std::thread(SndioCapture_recordProc, self);
|
||||
self->mThread = std::thread{std::mem_fn(&SndioCapture::recordProc), self};
|
||||
return ALC_TRUE;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
@@ -492,7 +488,7 @@ static ALCboolean SndioCapture_start(SndioCapture *self)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void SndioCapture_stop(SndioCapture *self)
|
||||
void SndioCapture_stop(SndioCapture *self)
|
||||
{
|
||||
if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
|
||||
return;
|
||||
@@ -502,14 +498,14 @@ static void SndioCapture_stop(SndioCapture *self)
|
||||
ERR("Error stopping device\n");
|
||||
}
|
||||
|
||||
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
|
||||
ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
|
||||
{
|
||||
RingBuffer *ring{self->mRing.get()};
|
||||
ring->read(buffer, samples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint SndioCapture_availableSamples(SndioCapture *self)
|
||||
ALCuint SndioCapture_availableSamples(SndioCapture *self)
|
||||
{
|
||||
RingBuffer *ring{self->mRing.get()};
|
||||
return ring->readSpace();
|
||||
|
||||
+61
-62
@@ -49,7 +49,17 @@
|
||||
|
||||
namespace {
|
||||
|
||||
struct ALCsolarisBackend final : public ALCbackend {
|
||||
constexpr ALCchar solaris_device[] = "Solaris Default";
|
||||
|
||||
const char *solaris_driver = "/dev/audio";
|
||||
|
||||
|
||||
struct SolarisBackend final : public ALCbackend {
|
||||
SolarisBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~SolarisBackend() override;
|
||||
|
||||
int mixerProc();
|
||||
|
||||
int mFd{-1};
|
||||
|
||||
al::vector<ALubyte> mBuffer;
|
||||
@@ -57,74 +67,65 @@ struct ALCsolarisBackend final : public ALCbackend {
|
||||
std::atomic<bool> mKillNow{true};
|
||||
std::thread mThread;
|
||||
|
||||
ALCsolarisBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
static constexpr inline const char *CurrentPrefix() noexcept { return "SolarisBackend::"; }
|
||||
};
|
||||
|
||||
static int ALCsolarisBackend_mixerProc(ALCsolarisBackend *self);
|
||||
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)
|
||||
|
||||
static void ALCsolarisBackend_Construct(ALCsolarisBackend *self, ALCdevice *device);
|
||||
static void ALCsolarisBackend_Destruct(ALCsolarisBackend *self);
|
||||
static ALCenum ALCsolarisBackend_open(ALCsolarisBackend *self, const ALCchar *name);
|
||||
static ALCboolean ALCsolarisBackend_reset(ALCsolarisBackend *self);
|
||||
static ALCboolean ALCsolarisBackend_start(ALCsolarisBackend *self);
|
||||
static void ALCsolarisBackend_stop(ALCsolarisBackend *self);
|
||||
static DECLARE_FORWARD2(ALCsolarisBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
|
||||
static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, ALCuint, availableSamples)
|
||||
static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, ClockLatency, getClockLatency)
|
||||
static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, void, lock)
|
||||
static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, void, unlock)
|
||||
DECLARE_DEFAULT_ALLOCATORS(ALCsolarisBackend)
|
||||
DEFINE_ALCBACKEND_VTABLE(SolarisBackend);
|
||||
|
||||
DEFINE_ALCBACKEND_VTABLE(ALCsolarisBackend);
|
||||
|
||||
|
||||
static const ALCchar solaris_device[] = "Solaris Default";
|
||||
|
||||
static const char *solaris_driver = "/dev/audio";
|
||||
|
||||
|
||||
static void ALCsolarisBackend_Construct(ALCsolarisBackend *self, ALCdevice *device)
|
||||
void SolarisBackend_Construct(SolarisBackend *self, ALCdevice *device)
|
||||
{
|
||||
new (self) ALCsolarisBackend{device};
|
||||
SET_VTABLE2(ALCsolarisBackend, ALCbackend, self);
|
||||
new (self) SolarisBackend{device};
|
||||
SET_VTABLE2(SolarisBackend, ALCbackend, self);
|
||||
}
|
||||
|
||||
static void ALCsolarisBackend_Destruct(ALCsolarisBackend *self)
|
||||
{
|
||||
if(self->mFd != -1)
|
||||
close(self->mFd);
|
||||
self->mFd = -1;
|
||||
void SolarisBackend_Destruct(SolarisBackend *self)
|
||||
{ self->~SolarisBackend(); }
|
||||
|
||||
self->~ALCsolarisBackend();
|
||||
SolarisBackend::~SolarisBackend()
|
||||
{
|
||||
if(mFd != -1)
|
||||
close(mFd);
|
||||
mFd = -1;
|
||||
}
|
||||
|
||||
|
||||
static int ALCsolarisBackend_mixerProc(ALCsolarisBackend *self)
|
||||
int SolarisBackend::mixerProc()
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
|
||||
SetRTPriority();
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
const int frame_size{device->frameSizeFromFmt()};
|
||||
const int frame_size{mDevice->frameSizeFromFmt()};
|
||||
|
||||
ALCsolarisBackend_lock(self);
|
||||
while(!self->mKillNow.load(std::memory_order_acquire) &&
|
||||
device->Connected.load(std::memory_order_acquire))
|
||||
SolarisBackend_lock(this);
|
||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
||||
mDevice->Connected.load(std::memory_order_acquire))
|
||||
{
|
||||
pollfd pollitem{};
|
||||
pollitem.fd = self->mFd;
|
||||
pollitem.fd = mFd;
|
||||
pollitem.events = POLLOUT;
|
||||
|
||||
ALCsolarisBackend_unlock(self);
|
||||
SolarisBackend_unlock(this);
|
||||
int pret{poll(&pollitem, 1, 1000)};
|
||||
ALCsolarisBackend_lock(self);
|
||||
SolarisBackend_lock(this);
|
||||
if(pret < 0)
|
||||
{
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
ERR("poll failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(device, "Failed to wait for playback buffer: %s", strerror(errno));
|
||||
aluHandleDisconnect(mDevice, "Failed to wait for playback buffer: %s",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
else if(pret == 0)
|
||||
@@ -133,19 +134,19 @@ static int ALCsolarisBackend_mixerProc(ALCsolarisBackend *self)
|
||||
continue;
|
||||
}
|
||||
|
||||
ALubyte *write_ptr{self->mBuffer.data()};
|
||||
size_t to_write{self->mBuffer.size()};
|
||||
aluMixData(device, write_ptr, to_write/frame_size);
|
||||
while(to_write > 0 && !self->mKillNow.load(std::memory_order_acquire))
|
||||
ALubyte *write_ptr{mBuffer.data()};
|
||||
size_t to_write{mBuffer.size()};
|
||||
aluMixData(mDevice, write_ptr, to_write/frame_size);
|
||||
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
|
||||
{
|
||||
ssize_t wrote{write(self->mFd, write_ptr, to_write)};
|
||||
ssize_t wrote{write(mFd, write_ptr, to_write)};
|
||||
if(wrote < 0)
|
||||
{
|
||||
if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
|
||||
continue;
|
||||
ERR("write failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(device, "Failed to write playback samples: %s",
|
||||
strerror(errno));
|
||||
aluHandleDisconnect(mDevice, "Failed to write playback samples: %s",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -153,16 +154,14 @@ static int ALCsolarisBackend_mixerProc(ALCsolarisBackend *self)
|
||||
write_ptr += wrote;
|
||||
}
|
||||
}
|
||||
ALCsolarisBackend_unlock(self);
|
||||
SolarisBackend_unlock(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum ALCsolarisBackend_open(ALCsolarisBackend *self, const ALCchar *name)
|
||||
ALCenum SolarisBackend_open(SolarisBackend *self, const ALCchar *name)
|
||||
{
|
||||
ALCdevice *device;
|
||||
|
||||
if(!name)
|
||||
name = solaris_device;
|
||||
else if(strcmp(name, solaris_device) != 0)
|
||||
@@ -175,13 +174,13 @@ static ALCenum ALCsolarisBackend_open(ALCsolarisBackend *self, const ALCchar *na
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device = self->mDevice;
|
||||
ALCdevice *device{self->mDevice};
|
||||
device->DeviceName = name;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCboolean ALCsolarisBackend_reset(ALCsolarisBackend *self)
|
||||
ALCboolean SolarisBackend_reset(SolarisBackend *self)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
audio_info_t info;
|
||||
@@ -256,11 +255,11 @@ static ALCboolean ALCsolarisBackend_reset(ALCsolarisBackend *self)
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean ALCsolarisBackend_start(ALCsolarisBackend *self)
|
||||
ALCboolean SolarisBackend_start(SolarisBackend *self)
|
||||
{
|
||||
try {
|
||||
self->mKillNow.store(false, std::memory_order_release);
|
||||
self->mThread = std::thread(ALCsolarisBackend_mixerProc, self);
|
||||
self->mThread = std::thread{std::mem_fn(&SolarisBackend::mixerProc), self};
|
||||
return ALC_TRUE;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
@@ -271,7 +270,7 @@ static ALCboolean ALCsolarisBackend_start(ALCsolarisBackend *self)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void ALCsolarisBackend_stop(ALCsolarisBackend *self)
|
||||
void SolarisBackend_stop(SolarisBackend *self)
|
||||
{
|
||||
if(self->mKillNow.exchange(true, std::memory_order_acq_rel) || !self->mThread.joinable())
|
||||
return;
|
||||
@@ -322,8 +321,8 @@ ALCbackend *SolarisBackendFactory::createBackend(ALCdevice *device, ALCbackend_T
|
||||
{
|
||||
if(type == ALCbackend_Playback)
|
||||
{
|
||||
ALCsolarisBackend *backend;
|
||||
NEW_OBJ(backend, ALCsolarisBackend)(device);
|
||||
SolarisBackend *backend;
|
||||
NEW_OBJ(backend, SolarisBackend)(device);
|
||||
return backend;
|
||||
}
|
||||
|
||||
|
||||
+63
-60
@@ -78,7 +78,12 @@ void fwrite32le(ALuint val, FILE *f)
|
||||
}
|
||||
|
||||
|
||||
struct ALCwaveBackend final : public ALCbackend {
|
||||
struct WaveBackend final : public ALCbackend {
|
||||
WaveBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
~WaveBackend() override;
|
||||
|
||||
int mixerProc();
|
||||
|
||||
FILE *mFile{nullptr};
|
||||
long mDataStart{-1};
|
||||
|
||||
@@ -87,81 +92,79 @@ struct ALCwaveBackend final : public ALCbackend {
|
||||
std::atomic<ALenum> mKillNow{AL_TRUE};
|
||||
std::thread mThread;
|
||||
|
||||
ALCwaveBackend(ALCdevice *device) noexcept : ALCbackend{device} { }
|
||||
static constexpr inline const char *CurrentPrefix() noexcept { return "WaveBackend::"; }
|
||||
};
|
||||
|
||||
int ALCwaveBackend_mixerProc(ALCwaveBackend *self);
|
||||
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)
|
||||
|
||||
void ALCwaveBackend_Construct(ALCwaveBackend *self, ALCdevice *device);
|
||||
void ALCwaveBackend_Destruct(ALCwaveBackend *self);
|
||||
ALCenum ALCwaveBackend_open(ALCwaveBackend *self, const ALCchar *name);
|
||||
ALCboolean ALCwaveBackend_reset(ALCwaveBackend *self);
|
||||
ALCboolean ALCwaveBackend_start(ALCwaveBackend *self);
|
||||
void ALCwaveBackend_stop(ALCwaveBackend *self);
|
||||
DECLARE_FORWARD2(ALCwaveBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
|
||||
DECLARE_FORWARD(ALCwaveBackend, ALCbackend, ALCuint, availableSamples)
|
||||
DECLARE_FORWARD(ALCwaveBackend, ALCbackend, ClockLatency, getClockLatency)
|
||||
DECLARE_FORWARD(ALCwaveBackend, ALCbackend, void, lock)
|
||||
DECLARE_FORWARD(ALCwaveBackend, ALCbackend, void, unlock)
|
||||
DECLARE_DEFAULT_ALLOCATORS(ALCwaveBackend)
|
||||
DEFINE_ALCBACKEND_VTABLE(WaveBackend);
|
||||
|
||||
DEFINE_ALCBACKEND_VTABLE(ALCwaveBackend);
|
||||
|
||||
|
||||
void ALCwaveBackend_Construct(ALCwaveBackend *self, ALCdevice *device)
|
||||
void WaveBackend_Construct(WaveBackend *self, ALCdevice *device)
|
||||
{
|
||||
new (self) ALCwaveBackend{device};
|
||||
SET_VTABLE2(ALCwaveBackend, ALCbackend, self);
|
||||
new (self) WaveBackend{device};
|
||||
SET_VTABLE2(WaveBackend, ALCbackend, self);
|
||||
}
|
||||
|
||||
void ALCwaveBackend_Destruct(ALCwaveBackend *self)
|
||||
{
|
||||
if(self->mFile)
|
||||
fclose(self->mFile);
|
||||
self->mFile = nullptr;
|
||||
void WaveBackend_Destruct(WaveBackend *self)
|
||||
{ self->~WaveBackend(); }
|
||||
|
||||
self->~ALCwaveBackend();
|
||||
WaveBackend::~WaveBackend()
|
||||
{
|
||||
if(mFile)
|
||||
fclose(mFile);
|
||||
mFile = nullptr;
|
||||
}
|
||||
|
||||
int ALCwaveBackend_mixerProc(ALCwaveBackend *self)
|
||||
int WaveBackend::mixerProc()
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2};
|
||||
const milliseconds restTime{mDevice->UpdateSize*1000/mDevice->Frequency / 2};
|
||||
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
const ALsizei frameSize{device->frameSizeFromFmt()};
|
||||
const ALsizei frameSize{mDevice->frameSizeFromFmt()};
|
||||
|
||||
ALint64 done{0};
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
while(!self->mKillNow.load(std::memory_order_acquire) &&
|
||||
device->Connected.load(std::memory_order_acquire))
|
||||
while(!mKillNow.load(std::memory_order_acquire) &&
|
||||
mDevice->Connected.load(std::memory_order_acquire))
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
/* This converts from nanoseconds to nanosamples, then to samples. */
|
||||
ALint64 avail{std::chrono::duration_cast<seconds>((now-start) * device->Frequency).count()};
|
||||
if(avail-done < device->UpdateSize)
|
||||
ALint64 avail{std::chrono::duration_cast<seconds>((now-start) *
|
||||
mDevice->Frequency).count()};
|
||||
if(avail-done < mDevice->UpdateSize)
|
||||
{
|
||||
std::this_thread::sleep_for(restTime);
|
||||
continue;
|
||||
}
|
||||
while(avail-done >= device->UpdateSize)
|
||||
while(avail-done >= mDevice->UpdateSize)
|
||||
{
|
||||
ALCwaveBackend_lock(self);
|
||||
aluMixData(device, self->mBuffer.data(), device->UpdateSize);
|
||||
ALCwaveBackend_unlock(self);
|
||||
done += device->UpdateSize;
|
||||
WaveBackend_lock(this);
|
||||
aluMixData(mDevice, mBuffer.data(), mDevice->UpdateSize);
|
||||
WaveBackend_unlock(this);
|
||||
done += mDevice->UpdateSize;
|
||||
|
||||
if(!IS_LITTLE_ENDIAN)
|
||||
{
|
||||
const ALsizei bytesize{device->bytesFromFmt()};
|
||||
const ALsizei bytesize{mDevice->bytesFromFmt()};
|
||||
ALsizei i;
|
||||
|
||||
if(bytesize == 2)
|
||||
{
|
||||
ALushort *samples = reinterpret_cast<ALushort*>(self->mBuffer.data());
|
||||
const auto len = static_cast<ALsizei>(self->mBuffer.size() / 2);
|
||||
ALushort *samples = reinterpret_cast<ALushort*>(mBuffer.data());
|
||||
const auto len = static_cast<ALsizei>(mBuffer.size() / 2);
|
||||
for(i = 0;i < len;i++)
|
||||
{
|
||||
ALushort samp = samples[i];
|
||||
@@ -170,8 +173,8 @@ int ALCwaveBackend_mixerProc(ALCwaveBackend *self)
|
||||
}
|
||||
else if(bytesize == 4)
|
||||
{
|
||||
ALuint *samples = reinterpret_cast<ALuint*>(self->mBuffer.data());
|
||||
const auto len = static_cast<ALsizei>(self->mBuffer.size() / 4);
|
||||
ALuint *samples = reinterpret_cast<ALuint*>(mBuffer.data());
|
||||
const auto len = static_cast<ALsizei>(mBuffer.size() / 4);
|
||||
for(i = 0;i < len;i++)
|
||||
{
|
||||
ALuint samp = samples[i];
|
||||
@@ -181,14 +184,14 @@ int ALCwaveBackend_mixerProc(ALCwaveBackend *self)
|
||||
}
|
||||
}
|
||||
|
||||
size_t fs{fwrite(self->mBuffer.data(), frameSize, device->UpdateSize, self->mFile)};
|
||||
size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile)};
|
||||
(void)fs;
|
||||
if(ferror(self->mFile))
|
||||
if(ferror(mFile))
|
||||
{
|
||||
ERR("Error writing to file\n");
|
||||
ALCwaveBackend_lock(self);
|
||||
aluHandleDisconnect(device, "Failed to write playback samples");
|
||||
ALCwaveBackend_unlock(self);
|
||||
WaveBackend_lock(this);
|
||||
aluHandleDisconnect(mDevice, "Failed to write playback samples");
|
||||
WaveBackend_unlock(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,11 +201,11 @@ int ALCwaveBackend_mixerProc(ALCwaveBackend *self)
|
||||
* and current time from growing too large, while maintaining the
|
||||
* correct number of samples to render.
|
||||
*/
|
||||
if(done >= device->Frequency)
|
||||
if(done >= mDevice->Frequency)
|
||||
{
|
||||
seconds s{done/device->Frequency};
|
||||
seconds s{done/mDevice->Frequency};
|
||||
start += s;
|
||||
done -= device->Frequency*s.count();
|
||||
done -= mDevice->Frequency*s.count();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +213,7 @@ int ALCwaveBackend_mixerProc(ALCwaveBackend *self)
|
||||
}
|
||||
|
||||
|
||||
ALCenum ALCwaveBackend_open(ALCwaveBackend *self, const ALCchar *name)
|
||||
ALCenum WaveBackend_open(WaveBackend *self, const ALCchar *name)
|
||||
{
|
||||
const char *fname{GetConfigValue(nullptr, "wave", "file", "")};
|
||||
if(!fname[0]) return ALC_INVALID_VALUE;
|
||||
@@ -240,7 +243,7 @@ ALCenum ALCwaveBackend_open(ALCwaveBackend *self, const ALCchar *name)
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
ALCboolean ALCwaveBackend_reset(ALCwaveBackend *self)
|
||||
ALCboolean WaveBackend_reset(WaveBackend *self)
|
||||
{
|
||||
ALCdevice *device{self->mDevice};
|
||||
ALuint channels=0, bits=0, chanmask=0;
|
||||
@@ -344,11 +347,11 @@ ALCboolean ALCwaveBackend_reset(ALCwaveBackend *self)
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
ALCboolean ALCwaveBackend_start(ALCwaveBackend *self)
|
||||
ALCboolean WaveBackend_start(WaveBackend *self)
|
||||
{
|
||||
try {
|
||||
self->mKillNow.store(AL_FALSE, std::memory_order_release);
|
||||
self->mThread = std::thread(ALCwaveBackend_mixerProc, self);
|
||||
self->mThread = std::thread{std::mem_fn(&WaveBackend::mixerProc), self};
|
||||
return ALC_TRUE;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
@@ -359,7 +362,7 @@ ALCboolean ALCwaveBackend_start(ALCwaveBackend *self)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
void ALCwaveBackend_stop(ALCwaveBackend *self)
|
||||
void WaveBackend_stop(WaveBackend *self)
|
||||
{
|
||||
if(self->mKillNow.exchange(AL_TRUE, std::memory_order_acq_rel) || !self->mThread.joinable())
|
||||
return;
|
||||
@@ -402,8 +405,8 @@ ALCbackend *WaveBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type
|
||||
{
|
||||
if(type == ALCbackend_Playback)
|
||||
{
|
||||
ALCwaveBackend *backend;
|
||||
NEW_OBJ(backend, ALCwaveBackend)(device);
|
||||
WaveBackend *backend;
|
||||
NEW_OBJ(backend, WaveBackend)(device);
|
||||
return backend;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user