aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alc.cpp2
-rw-r--r--Alc/backends/alsa.cpp18
-rw-r--r--Alc/backends/coreaudio.cpp20
-rw-r--r--Alc/backends/dsound.cpp22
-rw-r--r--Alc/backends/opensl.cpp48
-rw-r--r--Alc/backends/oss.cpp15
-rw-r--r--Alc/backends/portaudio.cpp18
-rw-r--r--Alc/backends/sndio.cpp16
-rw-r--r--Alc/backends/wasapi.cpp18
-rw-r--r--Alc/backends/winmm.cpp13
-rw-r--r--Alc/ringbuffer.cpp45
-rw-r--r--Alc/ringbuffer.h53
12 files changed, 119 insertions, 169 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index cbd586b8..fb7f9c67 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2459,7 +2459,7 @@ ALCcontext_struct::~ALCcontext_struct()
}
TRACE("Freed " SZFMT " listener property object%s\n", count, (count==1)?"":"s");
- ll_ringbuffer_free(AsyncEvents);
+ delete AsyncEvents;
AsyncEvents = nullptr;
ALCdevice_DecRef(Device);
diff --git a/Alc/backends/alsa.cpp b/Alc/backends/alsa.cpp
index 606877a8..228cafe0 100644
--- a/Alc/backends/alsa.cpp
+++ b/Alc/backends/alsa.cpp
@@ -929,7 +929,7 @@ struct ALCcaptureAlsa final : public ALCbackend {
al::vector<char> Buffer;
bool DoCapture{false};
- ll_ringbuffer_t *Ring{nullptr};
+ RingBufferPtr Ring{nullptr};
snd_pcm_sframes_t mLastAvail{0};
};
@@ -963,9 +963,6 @@ void ALCcaptureAlsa_Destruct(ALCcaptureAlsa *self)
snd_pcm_close(self->PcmHandle);
self->PcmHandle = nullptr;
- ll_ringbuffer_free(self->Ring);
- self->Ring = nullptr;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCcaptureAlsa();
}
@@ -1068,8 +1065,8 @@ ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
if(needring)
{
- self->Ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates,
- device->frameSizeFromFmt(), false);
+ self->Ring.reset(ll_ringbuffer_create(device->UpdateSize*device->NumUpdates,
+ device->frameSizeFromFmt(), false));
if(!self->Ring)
{
ERR("ring buffer create failed\n");
@@ -1086,7 +1083,6 @@ error:
if(hp) snd_pcm_hw_params_free(hp);
error2:
- ll_ringbuffer_free(self->Ring);
self->Ring = nullptr;
snd_pcm_close(self->PcmHandle);
self->PcmHandle = nullptr;
@@ -1142,7 +1138,7 @@ ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALC
if(self->Ring)
{
- ll_ringbuffer_read(self->Ring, static_cast<char*>(buffer), samples);
+ ll_ringbuffer_read(self->Ring.get(), static_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
@@ -1235,7 +1231,7 @@ ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
while(avail > 0)
{
- auto vec = ll_ringbuffer_get_write_vector(self->Ring);
+ auto vec = ll_ringbuffer_get_write_vector(self->Ring.get());
if(vec.first.len == 0) break;
snd_pcm_sframes_t amt{std::min<snd_pcm_sframes_t>(vec.first.len, avail)};
@@ -1263,11 +1259,11 @@ ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
continue;
}
- ll_ringbuffer_write_advance(self->Ring, amt);
+ ll_ringbuffer_write_advance(self->Ring.get(), amt);
avail -= amt;
}
- return ll_ringbuffer_read_space(self->Ring);
+ return ll_ringbuffer_read_space(self->Ring.get());
}
ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
diff --git a/Alc/backends/coreaudio.cpp b/Alc/backends/coreaudio.cpp
index 228d1d76..aaaf6221 100644
--- a/Alc/backends/coreaudio.cpp
+++ b/Alc/backends/coreaudio.cpp
@@ -324,7 +324,7 @@ struct ALCcoreAudioCapture final : public ALCbackend {
AudioBufferList *BufferList; // Buffer for data coming from the input device
ALCvoid *ResampleBuffer; // Buffer for returned RingBuffer data when resampling
- ll_ringbuffer_t *Ring;
+ RingBufferPtr Ring{nullptr};
};
static void ALCcoreAudioCapture_Construct(ALCcoreAudioCapture *self, ALCdevice *device);
@@ -376,14 +376,10 @@ static void ALCcoreAudioCapture_Construct(ALCcoreAudioCapture *self, ALCdevice *
self->AudioConverter = NULL;
self->BufferList = NULL;
self->ResampleBuffer = NULL;
- self->Ring = NULL;
}
static void ALCcoreAudioCapture_Destruct(ALCcoreAudioCapture *self)
{
- ll_ringbuffer_free(self->Ring);
- self->Ring = NULL;
-
free(self->ResampleBuffer);
self->ResampleBuffer = NULL;
@@ -420,7 +416,7 @@ static OSStatus ALCcoreAudioCapture_RecordProc(void *inRefCon,
return err;
}
- ll_ringbuffer_write(self->Ring, self->BufferList->mBuffers[0].mData, inNumberFrames);
+ ll_ringbuffer_write(self->Ring.get(), self->BufferList->mBuffers[0].mData, inNumberFrames);
return noErr;
}
@@ -432,7 +428,7 @@ static OSStatus ALCcoreAudioCapture_ConvertCallback(AudioConverterRef UNUSED(inA
ALCcoreAudioCapture *self = reinterpret_cast<ALCcoreAudioCapture*>(inUserData);
// Read from the ring buffer and store temporarily in a large buffer
- ll_ringbuffer_read(self->Ring, self->ResampleBuffer, *ioNumberDataPackets);
+ ll_ringbuffer_read(self->Ring.get(), self->ResampleBuffer, *ioNumberDataPackets);
// Set the input data
ioData->mNumberBuffers = 1;
@@ -666,18 +662,16 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
if(self->BufferList == NULL)
goto error;
- self->Ring = ll_ringbuffer_create(
+ self->Ring.reset(ll_ringbuffer_create(
(size_t)ceil(device->UpdateSize*self->SampleRateRatio*device->NumUpdates),
- self->FrameSize, false
- );
+ self->FrameSize, false));
if(!self->Ring) goto error;
device->DeviceName = name;
return ALC_NO_ERROR;
error:
- ll_ringbuffer_free(self->Ring);
- self->Ring = NULL;
+ self->Ring = nullptr;
free(self->ResampleBuffer);
self->ResampleBuffer = NULL;
destroy_buffer_list(self->BufferList);
@@ -745,7 +739,7 @@ static ALCenum ALCcoreAudioCapture_captureSamples(ALCcoreAudioCapture *self, ALC
static ALCuint ALCcoreAudioCapture_availableSamples(ALCcoreAudioCapture *self)
{
- return ll_ringbuffer_read_space(self->Ring) / self->SampleRateRatio;
+ return ll_ringbuffer_read_space(self->Ring.get()) / self->SampleRateRatio;
}
diff --git a/Alc/backends/dsound.cpp b/Alc/backends/dsound.cpp
index 5aa95f0f..26e561bf 100644
--- a/Alc/backends/dsound.cpp
+++ b/Alc/backends/dsound.cpp
@@ -655,7 +655,7 @@ struct ALCdsoundCapture final : public ALCbackend {
DWORD BufferBytes{0u};
DWORD Cursor{0u};
- ll_ringbuffer_t *Ring{nullptr};
+ RingBufferPtr Ring{nullptr};
};
void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device);
@@ -681,9 +681,6 @@ void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device)
void ALCdsoundCapture_Destruct(ALCdsoundCapture *self)
{
- ll_ringbuffer_free(self->Ring);
- self->Ring = nullptr;
-
if(self->DSCbuffer)
{
self->DSCbuffer->Stop();
@@ -838,8 +835,8 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
self->DSC->CreateCaptureBuffer(&DSCBDescription, &self->DSCbuffer, nullptr);
if(SUCCEEDED(hr))
{
- self->Ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates,
- InputType.Format.nBlockAlign, false);
+ self->Ring.reset(ll_ringbuffer_create(device->UpdateSize*device->NumUpdates,
+ InputType.Format.nBlockAlign, false));
if(!self->Ring) hr = DSERR_OUTOFMEMORY;
}
@@ -847,7 +844,6 @@ ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
{
ERR("Device init failed: 0x%08lx\n", hr);
- ll_ringbuffer_free(self->Ring);
self->Ring = nullptr;
if(self->DSCbuffer)
self->DSCbuffer->Release();
@@ -893,7 +889,7 @@ void ALCdsoundCapture_stop(ALCdsoundCapture *self)
ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring, buffer, samples);
+ ll_ringbuffer_read(self->Ring.get(), buffer, samples);
return ALC_NO_ERROR;
}
@@ -902,7 +898,7 @@ ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
if(!device->Connected.load(std::memory_order_acquire))
- return static_cast<ALCuint>(ll_ringbuffer_read_space(self->Ring));
+ return static_cast<ALCuint>(ll_ringbuffer_read_space(self->Ring.get()));
ALsizei FrameSize{device->frameSizeFromFmt()};
DWORD BufferBytes{self->BufferBytes};
@@ -915,15 +911,15 @@ ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
if(SUCCEEDED(hr))
{
DWORD NumBytes{(ReadCursor-LastCursor + BufferBytes) % BufferBytes};
- if(!NumBytes) return static_cast<ALCubyte>(ll_ringbuffer_read_space(self->Ring));
+ if(!NumBytes) return static_cast<ALCubyte>(ll_ringbuffer_read_space(self->Ring.get()));
hr = self->DSCbuffer->Lock(LastCursor, NumBytes, &ReadPtr1, &ReadCnt1,
&ReadPtr2, &ReadCnt2, 0);
}
if(SUCCEEDED(hr))
{
- ll_ringbuffer_write(self->Ring, ReadPtr1, ReadCnt1/FrameSize);
+ ll_ringbuffer_write(self->Ring.get(), ReadPtr1, ReadCnt1/FrameSize);
if(ReadPtr2 != nullptr)
- ll_ringbuffer_write(self->Ring, ReadPtr2, ReadCnt2/FrameSize);
+ ll_ringbuffer_write(self->Ring.get(), ReadPtr2, ReadCnt2/FrameSize);
hr = self->DSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
self->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
}
@@ -934,7 +930,7 @@ ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
aluHandleDisconnect(device, "Failure retrieving capture data: 0x%lx", hr);
}
- return static_cast<ALCuint>(ll_ringbuffer_read_space(self->Ring));
+ return static_cast<ALCuint>(ll_ringbuffer_read_space(self->Ring.get()));
}
} // namespace
diff --git a/Alc/backends/opensl.cpp b/Alc/backends/opensl.cpp
index 78212791..ab829e05 100644
--- a/Alc/backends/opensl.cpp
+++ b/Alc/backends/opensl.cpp
@@ -145,7 +145,7 @@ struct ALCopenslPlayback final : public ALCbackend {
/* buffer queue player interfaces */
SLObjectItf mBufferQueueObj{nullptr};
- ll_ringbuffer_t *mRing{nullptr};
+ RingBufferPtr mRing{nullptr};
al::semaphore mSem;
ALsizei mFrameSize{0};
@@ -195,9 +195,6 @@ static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
self->mEngineObj = NULL;
self->mEngine = NULL;
- ll_ringbuffer_free(self->mRing);
- self->mRing = NULL;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCopenslPlayback();
}
@@ -216,7 +213,7 @@ static void ALCopenslPlayback_process(SLAndroidSimpleBufferQueueItf UNUSED(bq),
* available for writing again, and wake up the mixer thread to mix and
* queue more audio.
*/
- ll_ringbuffer_read_advance(self->mRing, 1);
+ ll_ringbuffer_read_advance(self->mRing.get(), 1);
self->mSem.post();
}
@@ -250,7 +247,7 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
{
size_t todo;
- if(ll_ringbuffer_write_space(self->mRing) == 0)
+ if(ll_ringbuffer_write_space(self->mRing.get()) == 0)
{
SLuint32 state = 0;
@@ -267,7 +264,7 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
break;
}
- if(ll_ringbuffer_write_space(self->mRing) == 0)
+ if(ll_ringbuffer_write_space(self->mRing.get()) == 0)
{
ALCopenslPlayback_unlock(self);
self->mSem.wait();
@@ -276,13 +273,13 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
}
}
- auto data = ll_ringbuffer_get_write_vector(self->mRing);
+ auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
aluMixData(device, data.first.buf, data.first.len*device->UpdateSize);
if(data.second.len > 0)
aluMixData(device, data.second.buf, data.second.len*device->UpdateSize);
todo = data.first.len+data.second.len;
- ll_ringbuffer_write_advance(self->mRing, todo);
+ ll_ringbuffer_write_advance(self->mRing.get(), todo);
for(size_t i = 0;i < todo;i++)
{
@@ -380,8 +377,7 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
VCALL0(self->mBufferQueueObj,Destroy)();
self->mBufferQueueObj = NULL;
- ll_ringbuffer_free(self->mRing);
- self->mRing = NULL;
+ self->mRing = nullptr;
sampleRate = device->Frequency;
#if 0
@@ -536,9 +532,8 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
}
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = ll_ringbuffer_create(device->NumUpdates,
- self->mFrameSize*device->UpdateSize, true
- );
+ self->mRing.reset(ll_ringbuffer_create(device->NumUpdates,
+ self->mFrameSize*device->UpdateSize, true));
if(!self->mRing)
{
ERR("Out of memory allocating ring buffer %ux%u %u\n", device->UpdateSize,
@@ -564,7 +559,7 @@ static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
SLAndroidSimpleBufferQueueItf bufferQueue;
SLresult result;
- ll_ringbuffer_reset(self->mRing);
+ ll_ringbuffer_reset(self->mRing.get());
result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
@@ -642,7 +637,8 @@ static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
ALCopenslPlayback_lock(self);
ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing)*device->UpdateSize};
+ ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing.get()) *
+ device->UpdateSize};
ret.Latency /= device->Frequency;
ALCopenslPlayback_unlock(self);
@@ -658,7 +654,7 @@ struct ALCopenslCapture final : public ALCbackend {
/* recording interfaces */
SLObjectItf mRecordObj{nullptr};
- ll_ringbuffer_t *mRing{nullptr};
+ RingBufferPtr mRing{nullptr};
ALCuint mSplOffset{0u};
ALsizei mFrameSize{0};
@@ -699,9 +695,6 @@ static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
self->mEngineObj = NULL;
self->mEngine = NULL;
- ll_ringbuffer_free(self->mRing);
- self->mRing = NULL;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCopenslCapture();
}
@@ -711,7 +704,7 @@ static void ALCopenslCapture_process(SLAndroidSimpleBufferQueueItf UNUSED(bq), v
{
ALCopenslCapture *self = static_cast<ALCopenslCapture*>(context);
/* A new chunk has been written into the ring buffer, advance it. */
- ll_ringbuffer_write_advance(self->mRing, 1);
+ ll_ringbuffer_write_advance(self->mRing.get(), 1);
}
@@ -830,9 +823,8 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = ll_ringbuffer_create(device->NumUpdates,
- device->UpdateSize*self->mFrameSize, false
- );
+ self->mRing.reset(ll_ringbuffer_create(device->NumUpdates,
+ device->UpdateSize*self->mFrameSize, false));
result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
@@ -848,7 +840,7 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
size_t i;
- auto data = ll_ringbuffer_get_write_vector(self->mRing);
+ auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
for(i = 0;i < data.first.len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data.first.buf + chunk_size*i, chunk_size);
@@ -935,7 +927,7 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
/* Read the desired samples from the ring buffer then advance its read
* pointer.
*/
- auto data = ll_ringbuffer_get_read_vector(self->mRing);
+ auto data = ll_ringbuffer_get_read_vector(self->mRing.get());
for(i = 0;i < samples;)
{
ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
@@ -949,7 +941,7 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
/* Finished a chunk, reset the offset and advance the read pointer. */
self->mSplOffset = 0;
- ll_ringbuffer_read_advance(self->mRing, 1);
+ ll_ringbuffer_read_advance(self->mRing.get(), 1);
result = VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS != result) break;
@@ -978,7 +970,7 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- return ll_ringbuffer_read_space(self->mRing) * device->UpdateSize;
+ return ll_ringbuffer_read_space(self->mRing.get()) * device->UpdateSize;
}
diff --git a/Alc/backends/oss.cpp b/Alc/backends/oss.cpp
index 110672c7..065f159a 100644
--- a/Alc/backends/oss.cpp
+++ b/Alc/backends/oss.cpp
@@ -501,7 +501,7 @@ void ALCplaybackOSS_stop(ALCplaybackOSS *self)
struct ALCcaptureOSS final : public ALCbackend {
int fd{-1};
- ll_ringbuffer_t *mRing{nullptr};
+ RingBufferPtr mRing{nullptr};
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
@@ -537,8 +537,6 @@ void ALCcaptureOSS_Destruct(ALCcaptureOSS *self)
close(self->fd);
self->fd = -1;
- ll_ringbuffer_free(self->mRing);
- self->mRing = nullptr;
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCcaptureOSS();
}
@@ -580,7 +578,7 @@ int ALCcaptureOSS_recordProc(ALCcaptureOSS *self)
continue;
}
- auto vec = ll_ringbuffer_get_write_vector(self->mRing);
+ auto vec = ll_ringbuffer_get_write_vector(self->mRing.get());
if(vec.first.len > 0)
{
amt = read(self->fd, vec.first.buf, vec.first.len*frame_size);
@@ -592,7 +590,7 @@ int ALCcaptureOSS_recordProc(ALCcaptureOSS *self)
ALCcaptureOSS_unlock(self);
break;
}
- ll_ringbuffer_write_advance(self->mRing, amt/frame_size);
+ ll_ringbuffer_write_advance(self->mRing.get(), amt/frame_size);
}
}
@@ -698,7 +696,8 @@ ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
return ALC_INVALID_VALUE;
}
- self->mRing = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates, frameSize, false);
+ self->mRing.reset(ll_ringbuffer_create(device->UpdateSize*device->NumUpdates, frameSize,
+ false));
if(!self->mRing)
{
ERR("Ring buffer create failed\n");
@@ -739,13 +738,13 @@ void ALCcaptureOSS_stop(ALCcaptureOSS *self)
ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->mRing, static_cast<char*>(buffer), samples);
+ ll_ringbuffer_read(self->mRing.get(), static_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self)
{
- return ll_ringbuffer_read_space(self->mRing);
+ return ll_ringbuffer_read_space(self->mRing.get());
}
} // namespace
diff --git a/Alc/backends/portaudio.cpp b/Alc/backends/portaudio.cpp
index 93384489..a89959b6 100644
--- a/Alc/backends/portaudio.cpp
+++ b/Alc/backends/portaudio.cpp
@@ -319,7 +319,7 @@ struct ALCportCapture final : public ALCbackend {
PaStream *Stream{nullptr};
PaStreamParameters Params;
- ll_ringbuffer_t *Ring{nullptr};
+ RingBufferPtr Ring{nullptr};
};
int ALCportCapture_ReadCallback(const void *inputBuffer, void *outputBuffer,
@@ -356,9 +356,6 @@ void ALCportCapture_Destruct(ALCportCapture *self)
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
self->Stream = nullptr;
- ll_ringbuffer_free(self->Ring);
- self->Ring = nullptr;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCportCapture();
}
@@ -369,10 +366,7 @@ int ALCportCapture_ReadCallback(const void *inputBuffer, void *UNUSED(outputBuff
const PaStreamCallbackFlags UNUSED(statusFlags), void *userData)
{
ALCportCapture *self = static_cast<ALCportCapture*>(userData);
- size_t writable = ll_ringbuffer_write_space(self->Ring);
-
- if(framesPerBuffer > writable) framesPerBuffer = writable;
- ll_ringbuffer_write(self->Ring, inputBuffer, framesPerBuffer);
+ ll_ringbuffer_write(self->Ring.get(), inputBuffer, framesPerBuffer);
return 0;
}
@@ -392,8 +386,8 @@ ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
samples = maxu(samples, 100 * device->Frequency / 1000);
frame_size = device->frameSizeFromFmt();
- self->Ring = ll_ringbuffer_create(samples, frame_size, false);
- if(self->Ring == nullptr) return ALC_INVALID_VALUE;
+ self->Ring.reset(ll_ringbuffer_create(samples, frame_size, false));
+ if(!self->Ring) return ALC_INVALID_VALUE;
self->Params.device = -1;
if(!ConfigValueInt(nullptr, "port", "capture", &self->Params.device) ||
@@ -462,12 +456,12 @@ void ALCportCapture_stop(ALCportCapture *self)
ALCuint ALCportCapture_availableSamples(ALCportCapture *self)
{
- return ll_ringbuffer_read_space(self->Ring);
+ return ll_ringbuffer_read_space(self->Ring.get());
}
ALCenum ALCportCapture_captureSamples(ALCportCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring, buffer, samples);
+ ll_ringbuffer_read(self->Ring.get(), buffer, samples);
return ALC_NO_ERROR;
}
diff --git a/Alc/backends/sndio.cpp b/Alc/backends/sndio.cpp
index 9ebad671..25566490 100644
--- a/Alc/backends/sndio.cpp
+++ b/Alc/backends/sndio.cpp
@@ -279,7 +279,7 @@ static void SndioPlayback_stop(SndioPlayback *self)
struct SndioCapture final : public ALCbackend {
struct sio_hdl *sndHandle{nullptr};
- ll_ringbuffer_t *ring{nullptr};
+ RingBufferPtr ring{nullptr};
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
@@ -316,9 +316,6 @@ static void SndioCapture_Destruct(SndioCapture *self)
sio_close(self->sndHandle);
self->sndHandle = nullptr;
- ll_ringbuffer_free(self->ring);
- self->ring = nullptr;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~SndioCapture();
}
@@ -339,7 +336,7 @@ static int SndioCapture_recordProc(SndioCapture *self)
{
size_t total, todo;
- auto data = ll_ringbuffer_get_write_vector(self->ring);
+ auto data = ll_ringbuffer_get_write_vector(self->ring.get());
todo = data.first.len + data.second.len;
if(todo == 0)
{
@@ -372,7 +369,7 @@ static int SndioCapture_recordProc(SndioCapture *self)
data.first.len -= got;
total += got;
}
- ll_ringbuffer_write_advance(self->ring, total / frameSize);
+ ll_ringbuffer_write_advance(self->ring.get(), total / frameSize);
}
return 0;
@@ -468,7 +465,8 @@ static ALCenum SndioCapture_open(SndioCapture *self, const ALCchar *name)
return ALC_INVALID_VALUE;
}
- self->ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates, par.bps*par.rchan, 0);
+ self->ring.reset(ll_ringbuffer_create(device->UpdateSize*device->NumUpdates,
+ par.bps*par.rchan, false));
if(!self->ring)
{
ERR("Failed to allocate %u-byte ringbuffer\n",
@@ -516,13 +514,13 @@ static void SndioCapture_stop(SndioCapture *self)
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->ring, static_cast<char*>(buffer), samples);
+ ll_ringbuffer_read(self->ring.get(), static_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
static ALCuint SndioCapture_availableSamples(SndioCapture *self)
{
- return ll_ringbuffer_read_space(self->ring);
+ return ll_ringbuffer_read_space(self->ring.get());
}
diff --git a/Alc/backends/wasapi.cpp b/Alc/backends/wasapi.cpp
index 79e4af04..3f8cad23 100644
--- a/Alc/backends/wasapi.cpp
+++ b/Alc/backends/wasapi.cpp
@@ -1172,7 +1172,7 @@ struct ALCwasapiCapture final : public ALCbackend, WasapiProxy {
ChannelConverter *mChannelConv{nullptr};
SampleConverter *mSampleConv{nullptr};
- ll_ringbuffer_t *mRing{nullptr};
+ RingBufferPtr mRing{nullptr};
std::atomic<int> mKillNow{AL_TRUE};
std::thread mThread;
@@ -1220,9 +1220,6 @@ void ALCwasapiCapture_Destruct(ALCwasapiCapture *self)
CloseHandle(self->mNotifyEvent);
self->mNotifyEvent = nullptr;
- ll_ringbuffer_free(self->mRing);
- self->mRing = nullptr;
-
DestroySampleConverter(&self->mSampleConv);
DestroyChannelConverter(&self->mChannelConv);
@@ -1275,7 +1272,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
rdata = reinterpret_cast<BYTE*>(samples.data());
}
- auto data = ll_ringbuffer_get_write_vector(self->mRing);
+ auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
size_t dstframes;
if(self->mSampleConv)
@@ -1311,7 +1308,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
dstframes = len1 + len2;
}
- ll_ringbuffer_write_advance(self->mRing, dstframes);
+ ll_ringbuffer_write_advance(self->mRing.get(), dstframes);
hr = capture->ReleaseBuffer(numsamples);
if(FAILED(hr)) ERR("Failed to release capture buffer: 0x%08lx\n", hr);
@@ -1696,8 +1693,7 @@ HRESULT ALCwasapiCapture::resetProxy()
}
buffer_len = maxu(device->UpdateSize*device->NumUpdates, buffer_len);
- ll_ringbuffer_free(mRing);
- mRing = ll_ringbuffer_create(buffer_len, device->frameSizeFromFmt(), false);
+ mRing.reset(ll_ringbuffer_create(buffer_len, device->frameSizeFromFmt(), false));
if(!mRing)
{
ERR("Failed to allocate capture ring buffer\n");
@@ -1790,14 +1786,12 @@ void ALCwasapiCapture::stopProxy()
ALuint ALCwasapiCapture_availableSamples(ALCwasapiCapture *self)
{
- return (ALuint)ll_ringbuffer_read_space(self->mRing);
+ return (ALuint)ll_ringbuffer_read_space(self->mRing.get());
}
ALCenum ALCwasapiCapture_captureSamples(ALCwasapiCapture *self, ALCvoid *buffer, ALCuint samples)
{
- if(ALCwasapiCapture_availableSamples(self) < samples)
- return ALC_INVALID_VALUE;
- ll_ringbuffer_read(self->mRing, reinterpret_cast<char*>(buffer), samples);
+ ll_ringbuffer_read(self->mRing.get(), reinterpret_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
diff --git a/Alc/backends/winmm.cpp b/Alc/backends/winmm.cpp
index 362b2e5e..38766869 100644
--- a/Alc/backends/winmm.cpp
+++ b/Alc/backends/winmm.cpp
@@ -401,7 +401,7 @@ struct ALCwinmmCapture final : public ALCbackend {
HWAVEIN InHdl{nullptr};
- ll_ringbuffer_t *Ring{nullptr};
+ RingBufferPtr Ring{nullptr};
WAVEFORMATEX Format{};
@@ -448,9 +448,6 @@ void ALCwinmmCapture_Destruct(ALCwinmmCapture *self)
al_free(self->WaveBuffer[0].lpData);
std::fill(self->WaveBuffer.begin(), self->WaveBuffer.end(), WAVEHDR{});
- ll_ringbuffer_free(self->Ring);
- self->Ring = nullptr;
-
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
self->~ALCwinmmCapture();
}
@@ -497,7 +494,7 @@ int ALCwinmmCapture_captureProc(ALCwinmmCapture *self)
WAVEHDR &waveHdr = self->WaveBuffer[widx];
widx = (widx+1) % self->WaveBuffer.size();
- ll_ringbuffer_write(self->Ring, waveHdr.lpData,
+ ll_ringbuffer_write(self->Ring.get(), waveHdr.lpData,
waveHdr.dwBytesRecorded / self->Format.nBlockAlign
);
self->Readable.fetch_sub(1, std::memory_order_acq_rel);
@@ -585,7 +582,7 @@ ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *deviceName)
std::max<size_t>(device->UpdateSize*device->NumUpdates, BufferSize*self->WaveBuffer.size())
);
- self->Ring = ll_ringbuffer_create(CapturedDataSize, self->Format.nBlockAlign, false);
+ self->Ring.reset(ll_ringbuffer_create(CapturedDataSize, self->Format.nBlockAlign, false));
if(!self->Ring) return ALC_INVALID_VALUE;
al_free(self->WaveBuffer[0].lpData);
@@ -648,13 +645,13 @@ void ALCwinmmCapture_stop(ALCwinmmCapture *self)
ALCenum ALCwinmmCapture_captureSamples(ALCwinmmCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring, buffer, samples);
+ ll_ringbuffer_read(self->Ring.get(), buffer, samples);
return ALC_NO_ERROR;
}
ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self)
{
- return (ALCuint)ll_ringbuffer_read_space(self->Ring);
+ return (ALCuint)ll_ringbuffer_read_space(self->Ring.get());
}
} // namespace
diff --git a/Alc/ringbuffer.cpp b/Alc/ringbuffer.cpp
index 5ee2616f..a298ff43 100644
--- a/Alc/ringbuffer.cpp
+++ b/Alc/ringbuffer.cpp
@@ -31,25 +31,9 @@
#include "compat.h"
-/* NOTE: This lockless ringbuffer implementation is copied from JACK, extended
- * to include an element size. Consequently, parameters and return values for a
- * size or count is in 'elements', not bytes. Additionally, it only supports
- * single-consumer/single-provider operation. */
-struct ll_ringbuffer {
- std::atomic<size_t> write_ptr{0u};
- std::atomic<size_t> read_ptr{0u};
- size_t size{0u};
- size_t size_mask{0u};
- size_t elem_size{0u};
-
- alignas(16) char buf[];
-
- DEF_PLACE_NEWDEL()
-};
-
-ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
+ll_ringbuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
{
- ll_ringbuffer_t *rb;
+ ll_ringbuffer *rb;
size_t power_of_two = 0;
if(sz > 0)
@@ -75,12 +59,7 @@ ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_write
return rb;
}
-void ll_ringbuffer_free(ll_ringbuffer_t *rb)
-{
- delete rb;
-}
-
-void ll_ringbuffer_reset(ll_ringbuffer_t *rb)
+void ll_ringbuffer_reset(ll_ringbuffer *rb)
{
rb->write_ptr.store(0, std::memory_order_relaxed);
rb->read_ptr.store(0, std::memory_order_relaxed);
@@ -88,14 +67,14 @@ void ll_ringbuffer_reset(ll_ringbuffer_t *rb)
}
-size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb)
+size_t ll_ringbuffer_read_space(const ll_ringbuffer *rb)
{
size_t w = rb->write_ptr.load(std::memory_order_acquire);
size_t r = rb->read_ptr.load(std::memory_order_acquire);
return (w-r) & rb->size_mask;
}
-size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb)
+size_t ll_ringbuffer_write_space(const ll_ringbuffer *rb)
{
size_t w = rb->write_ptr.load(std::memory_order_acquire);
size_t r = rb->read_ptr.load(std::memory_order_acquire);
@@ -104,7 +83,7 @@ size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb)
}
-size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, void *dest, size_t cnt)
+size_t ll_ringbuffer_read(ll_ringbuffer *rb, void *dest, size_t cnt)
{
size_t read_ptr;
size_t free_cnt;
@@ -143,7 +122,7 @@ size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, void *dest, size_t cnt)
return to_read;
}
-size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, void *dest, size_t cnt)
+size_t ll_ringbuffer_peek(ll_ringbuffer *rb, void *dest, size_t cnt)
{
size_t free_cnt;
size_t cnt2;
@@ -180,7 +159,7 @@ size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, void *dest, size_t cnt)
return to_read;
}
-size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const void *src, size_t cnt)
+size_t ll_ringbuffer_write(ll_ringbuffer *rb, const void *src, size_t cnt)
{
size_t write_ptr;
size_t free_cnt;
@@ -220,18 +199,18 @@ size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const void *src, size_t cnt)
}
-void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt)
+void ll_ringbuffer_read_advance(ll_ringbuffer *rb, size_t cnt)
{
rb->read_ptr.fetch_add(cnt, std::memory_order_acq_rel);
}
-void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt)
+void ll_ringbuffer_write_advance(ll_ringbuffer *rb, size_t cnt)
{
rb->write_ptr.fetch_add(cnt, std::memory_order_acq_rel);
}
-ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb)
+ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer *rb)
{
ll_ringbuffer_data_pair ret;
size_t free_cnt;
@@ -265,7 +244,7 @@ ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb)
return ret;
}
-ll_ringbuffer_data_pair ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb)
+ll_ringbuffer_data_pair ll_ringbuffer_get_write_vector(const ll_ringbuffer *rb)
{
ll_ringbuffer_data_pair ret;
size_t free_cnt;
diff --git a/Alc/ringbuffer.h b/Alc/ringbuffer.h
index cb2077f8..5111023e 100644
--- a/Alc/ringbuffer.h
+++ b/Alc/ringbuffer.h
@@ -3,19 +3,36 @@
#include <stddef.h>
+#include <atomic>
#include <memory>
#include <utility>
+#include "almalloc.h"
+
+
+/* NOTE: This lockless ringbuffer implementation is copied from JACK, extended
+ * to include an element size. Consequently, parameters and return values for a
+ * size or count is in 'elements', not bytes. Additionally, it only supports
+ * single-consumer/single-provider operation.
+ */
+struct ll_ringbuffer {
+ std::atomic<size_t> write_ptr{0u};
+ std::atomic<size_t> read_ptr{0u};
+ size_t size{0u};
+ size_t size_mask{0u};
+ size_t elem_size{0u};
+
+ alignas(16) char buf[];
+
+ DEF_PLACE_NEWDEL()
+};
-struct ll_ringbuffer;
-using ll_ringbuffer_t = struct ll_ringbuffer;
struct ll_ringbuffer_data {
char *buf;
size_t len;
};
using ll_ringbuffer_data_pair = std::pair<ll_ringbuffer_data,ll_ringbuffer_data>;
-using ll_ringbuffer_data_t = struct ll_ringbuffer_data;
/**
@@ -23,61 +40,55 @@ using ll_ringbuffer_data_t = struct ll_ringbuffer_data;
* The number of elements is rounded up to the next power of two (even if it is
* already a power of two, to ensure the requested amount can be written).
*/
-ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes);
-/** Free all data associated with the ringbuffer `rb'. */
-void ll_ringbuffer_free(ll_ringbuffer_t *rb);
+ll_ringbuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes);
/** Reset the read and write pointers to zero. This is not thread safe. */
-void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
+void ll_ringbuffer_reset(ll_ringbuffer *rb);
/**
* The non-copying data reader. Returns two ringbuffer data pointers that hold
* the current readable data at `rb'. If the readable data is in one segment
* the second segment has zero length.
*/
-ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb);
+ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer *rb);
/**
* The non-copying data writer. Returns two ringbuffer data pointers that hold
* the current writeable data at `rb'. If the writeable data is in one segment
* the second segment has zero length.
*/
-ll_ringbuffer_data_pair ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb);
+ll_ringbuffer_data_pair ll_ringbuffer_get_write_vector(const ll_ringbuffer *rb);
/**
* Return the number of elements available for reading. This is the number of
* elements in front of the read pointer and behind the write pointer.
*/
-size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
+size_t ll_ringbuffer_read_space(const ll_ringbuffer *rb);
/**
* The copying data reader. Copy at most `cnt' elements from `rb' to `dest'.
* Returns the actual number of elements copied.
*/
-size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, void *dest, size_t cnt);
+size_t ll_ringbuffer_read(ll_ringbuffer *rb, void *dest, size_t cnt);
/**
* The copying data reader w/o read pointer advance. Copy at most `cnt'
* elements from `rb' to `dest'. Returns the actual number of elements copied.
*/
-size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, void *dest, size_t cnt);
+size_t ll_ringbuffer_peek(ll_ringbuffer *rb, void *dest, size_t cnt);
/** Advance the read pointer `cnt' places. */
-void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
+void ll_ringbuffer_read_advance(ll_ringbuffer *rb, size_t cnt);
/**
* Return the number of elements available for writing. This is the number of
* elements in front of the write pointer and behind the read pointer.
*/
-size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
+size_t ll_ringbuffer_write_space(const ll_ringbuffer *rb);
/**
* The copying data writer. Copy at most `cnt' elements to `rb' from `src'.
* Returns the actual number of elements copied.
*/
-size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const void *src, size_t cnt);
+size_t ll_ringbuffer_write(ll_ringbuffer *rb, const void *src, size_t cnt);
/** Advance the write pointer `cnt' places. */
-void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
+void ll_ringbuffer_write_advance(ll_ringbuffer *rb, size_t cnt);
-struct RingBufferDeleter {
- void operator()(ll_ringbuffer_t *ring) const
- { ll_ringbuffer_free(ring); }
-};
-using RingBufferPtr = std::unique_ptr<ll_ringbuffer_t,RingBufferDeleter>;
+using RingBufferPtr = std::unique_ptr<ll_ringbuffer>;
#endif /* RINGBUFFER_H */