aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/alc.cpp2
-rw-r--r--Alc/alcontext.h4
-rw-r--r--Alc/alu.cpp16
-rw-r--r--Alc/backends/alsa.cpp13
-rw-r--r--Alc/backends/coreaudio.cpp13
-rw-r--r--Alc/backends/dsound.cpp16
-rw-r--r--Alc/backends/jack.cpp17
-rw-r--r--Alc/backends/opensl.cpp54
-rw-r--r--Alc/backends/oss.cpp13
-rw-r--r--Alc/backends/portaudio.cpp11
-rw-r--r--Alc/backends/sndio.cpp16
-rw-r--r--Alc/backends/wasapi.cpp13
-rw-r--r--Alc/backends/winmm.cpp13
-rw-r--r--Alc/mixvoice.cpp5
-rw-r--r--Alc/ringbuffer.cpp203
-rw-r--r--Alc/ringbuffer.h122
-rw-r--r--OpenAL32/alSource.cpp9
-rw-r--r--OpenAL32/event.cpp14
18 files changed, 285 insertions, 269 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index d13cfc54..294ba394 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2466,7 +2466,7 @@ ALCcontext_struct::~ALCcontext_struct()
TRACE("Freed " SZFMT " listener property object%s\n", count, (count==1)?"":"s");
count = 0;
- auto evt_vec = ll_ringbuffer_get_read_vector(AsyncEvents);
+ auto evt_vec = AsyncEvents->getReadVector();
while(evt_vec.first.len > 0)
{
reinterpret_cast<AsyncEvent*>(evt_vec.first.buf)->~AsyncEvent();
diff --git a/Alc/alcontext.h b/Alc/alcontext.h
index 7b7688ac..dadb4f8f 100644
--- a/Alc/alcontext.h
+++ b/Alc/alcontext.h
@@ -27,7 +27,7 @@ struct ALvoiceProps;
struct ALeffectslotProps;
struct ALvoice;
struct ALeffectslotArray;
-struct ll_ringbuffer;
+struct RingBuffer;
enum class DistanceModel {
InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
@@ -112,7 +112,7 @@ struct ALCcontext_struct {
std::thread EventThread;
al::semaphore EventSem;
- ll_ringbuffer *AsyncEvents{nullptr};
+ RingBuffer *AsyncEvents{nullptr};
std::atomic<ALbitfieldSOFT> EnabledEvts{0u};
std::mutex EventCbLock;
ALEVENTPROCSOFT EventCb{};
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index 6655bd81..1ebf3adc 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -289,13 +289,15 @@ void SendSourceStoppedEvent(ALCcontext *context, ALuint id)
ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)};
if(!(enabledevt&EventType_SourceStateChange)) return;
- auto evt_data = ll_ringbuffer_get_write_vector(context->AsyncEvents).first;
+ RingBuffer *ring{context->AsyncEvents};
+ auto evt_data = ring->getWriteVector().first;
if(evt_data.len < 1) return;
AsyncEvent *evt{new (evt_data.buf) AsyncEvent{EventType_SourceStateChange}};
evt->u.srcstate.id = id;
evt->u.srcstate.state = AL_STOPPED;
- ll_ringbuffer_write_advance(context->AsyncEvents, 1);
+
+ ring->writeAdvance(1);
context->EventSem.post();
}
@@ -414,12 +416,13 @@ bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force)
/* Otherwise, if it would be deleted, send it off with a release
* event.
*/
- auto evt_vec = ll_ringbuffer_get_write_vector(context->AsyncEvents);
+ RingBuffer *ring{context->AsyncEvents};
+ auto evt_vec = ring->getWriteVector();
if(LIKELY(evt_vec.first.len > 0))
{
AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_ReleaseEffectState}};
evt->u.mEffectState = oldstate;
- ll_ringbuffer_write_advance(context->AsyncEvents, 1);
+ ring->writeAdvance(1);
context->EventSem.post();
}
else
@@ -1837,11 +1840,12 @@ void aluHandleDisconnect(ALCdevice *device, const char *msg, ...)
const ALbitfieldSOFT enabledevt{ctx->EnabledEvts.load(std::memory_order_acquire)};
if((enabledevt&EventType_Disconnected))
{
- auto evt_data = ll_ringbuffer_get_write_vector(ctx->AsyncEvents).first;
+ RingBuffer *ring{ctx->AsyncEvents};
+ auto evt_data = ring->getWriteVector().first;
if(evt_data.len > 0)
{
new (evt_data.buf) AsyncEvent{evt};
- ll_ringbuffer_write_advance(ctx->AsyncEvents, 1);
+ ring->writeAdvance(1);
ctx->EventSem.post();
}
}
diff --git a/Alc/backends/alsa.cpp b/Alc/backends/alsa.cpp
index cf3f7fff..fd6981f8 100644
--- a/Alc/backends/alsa.cpp
+++ b/Alc/backends/alsa.cpp
@@ -1136,9 +1136,9 @@ ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALC
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- if(self->Ring)
+ if(RingBuffer *ring{self->Ring.get()})
{
- ll_ringbuffer_read(self->Ring.get(), static_cast<char*>(buffer), samples);
+ ring->read(static_cast<char*>(buffer), samples);
return ALC_NO_ERROR;
}
@@ -1221,7 +1221,8 @@ ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
}
}
- if(!self->Ring)
+ RingBuffer *ring{self->Ring.get()};
+ if(!ring)
{
if(avail < 0) avail = 0;
avail += snd_pcm_bytes_to_frames(self->PcmHandle, self->Buffer.size());
@@ -1231,7 +1232,7 @@ ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
while(avail > 0)
{
- auto vec = ll_ringbuffer_get_write_vector(self->Ring.get());
+ auto vec = ring->getWriteVector();
if(vec.first.len == 0) break;
snd_pcm_sframes_t amt{std::min<snd_pcm_sframes_t>(vec.first.len, avail)};
@@ -1259,11 +1260,11 @@ ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self)
continue;
}
- ll_ringbuffer_write_advance(self->Ring.get(), amt);
+ ring->writeAdvance(amt);
avail -= amt;
}
- return ll_ringbuffer_read_space(self->Ring.get());
+ return ring->readSpace();
}
ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
diff --git a/Alc/backends/coreaudio.cpp b/Alc/backends/coreaudio.cpp
index c73a67f9..808e7cb8 100644
--- a/Alc/backends/coreaudio.cpp
+++ b/Alc/backends/coreaudio.cpp
@@ -404,7 +404,8 @@ static OSStatus ALCcoreAudioCapture_RecordProc(void *inRefCon,
const AudioTimeStamp *inTimeStamp, UInt32 UNUSED(inBusNumber),
UInt32 inNumberFrames, AudioBufferList* UNUSED(ioData))
{
- ALCcoreAudioCapture *self = static_cast<ALCcoreAudioCapture*>(inRefCon);
+ auto self = static_cast<ALCcoreAudioCapture*>(inRefCon);
+ RingBuffer *ring{self->Ring.get()};
AudioUnitRenderActionFlags flags = 0;
OSStatus err;
@@ -416,7 +417,7 @@ static OSStatus ALCcoreAudioCapture_RecordProc(void *inRefCon,
return err;
}
- ll_ringbuffer_write(self->Ring.get(), self->BufferList->mBuffers[0].mData, inNumberFrames);
+ ring->write(self->BufferList->mBuffers[0].mData, inNumberFrames);
return noErr;
}
@@ -425,10 +426,11 @@ static OSStatus ALCcoreAudioCapture_ConvertCallback(AudioConverterRef UNUSED(inA
AudioStreamPacketDescription** UNUSED(outDataPacketDescription),
void *inUserData)
{
- ALCcoreAudioCapture *self = reinterpret_cast<ALCcoreAudioCapture*>(inUserData);
+ auto self = reinterpret_cast<ALCcoreAudioCapture*>(inUserData);
+ RingBuffer *ring{self->Ring.get()};
// Read from the ring buffer and store temporarily in a large buffer
- ll_ringbuffer_read(self->Ring.get(), self->ResampleBuffer, *ioNumberDataPackets);
+ ring->read(self->ResampleBuffer, *ioNumberDataPackets);
// Set the input data
ioData->mNumberBuffers = 1;
@@ -739,7 +741,8 @@ static ALCenum ALCcoreAudioCapture_captureSamples(ALCcoreAudioCapture *self, ALC
static ALCuint ALCcoreAudioCapture_availableSamples(ALCcoreAudioCapture *self)
{
- return ll_ringbuffer_read_space(self->Ring.get()) / self->SampleRateRatio;
+ RingBuffer *ring{self->Ring.get()};
+ return ring->readSpace() / self->SampleRateRatio;
}
diff --git a/Alc/backends/dsound.cpp b/Alc/backends/dsound.cpp
index 4ada7419..516a7770 100644
--- a/Alc/backends/dsound.cpp
+++ b/Alc/backends/dsound.cpp
@@ -889,16 +889,18 @@ void ALCdsoundCapture_stop(ALCdsoundCapture *self)
ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring.get(), buffer, samples);
+ RingBuffer *ring{self->Ring.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->Ring.get()};
if(!device->Connected.load(std::memory_order_acquire))
- return static_cast<ALCuint>(ll_ringbuffer_read_space(self->Ring.get()));
+ return static_cast<ALCuint>(ring->readSpace());
ALsizei FrameSize{device->frameSizeFromFmt()};
DWORD BufferBytes{self->BufferBytes};
@@ -911,15 +913,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.get()));
+ if(!NumBytes) return static_cast<ALCubyte>(ring->readSpace());
hr = self->DSCbuffer->Lock(LastCursor, NumBytes, &ReadPtr1, &ReadCnt1,
&ReadPtr2, &ReadCnt2, 0);
}
if(SUCCEEDED(hr))
{
- ll_ringbuffer_write(self->Ring.get(), ReadPtr1, ReadCnt1/FrameSize);
+ ring->write(ReadPtr1, ReadCnt1/FrameSize);
if(ReadPtr2 != nullptr)
- ll_ringbuffer_write(self->Ring.get(), ReadPtr2, ReadCnt2/FrameSize);
+ ring->write(ReadPtr2, ReadCnt2/FrameSize);
hr = self->DSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
self->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
}
@@ -930,7 +932,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.get()));
+ return static_cast<ALCuint>(ring->readSpace());
}
} // namespace
diff --git a/Alc/backends/jack.cpp b/Alc/backends/jack.cpp
index c768983d..02e29973 100644
--- a/Alc/backends/jack.cpp
+++ b/Alc/backends/jack.cpp
@@ -245,7 +245,8 @@ int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
out[numchans++] = static_cast<float*>(jack_port_get_buffer(port, numframes));
}
- auto data = ll_ringbuffer_get_read_vector(self->mRing.get());
+ RingBuffer *ring{self->mRing.get()};
+ auto data = ring->getReadVector();
jack_nframes_t todo{minu(numframes, data.first.len)};
std::transform(out, out+numchans, out,
[&data,numchans,todo](ALfloat *outbuf) -> ALfloat*
@@ -287,7 +288,7 @@ int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
total += todo;
}
- ll_ringbuffer_read_advance(self->mRing.get(), total);
+ ring->readAdvance(total);
self->mSem.post();
if(numframes > total)
@@ -307,7 +308,8 @@ int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
{
- ALCdevice *device{STATIC_CAST(ALCbackend,self)->mDevice};
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -316,7 +318,7 @@ int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
while(!self->mKillNow.load(std::memory_order_acquire) &&
device->Connected.load(std::memory_order_acquire))
{
- if(ll_ringbuffer_write_space(self->mRing.get()) < device->UpdateSize)
+ if(ring->writeSpace() < device->UpdateSize)
{
ALCjackPlayback_unlock(self);
self->mSem.wait();
@@ -324,7 +326,7 @@ int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
continue;
}
- auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto data = ring->getWriteVector();
auto todo = static_cast<ALuint>(data.first.len + data.second.len);
todo -= todo%device->UpdateSize;
@@ -334,7 +336,7 @@ int ALCjackPlayback_mixerProc(ALCjackPlayback *self)
aluMixData(device, data.first.buf, len1);
if(len2 > 0)
aluMixData(device, data.second.buf, len2);
- ll_ringbuffer_write_advance(self->mRing.get(), todo);
+ ring->writeAdvance(todo);
}
ALCjackPlayback_unlock(self);
@@ -506,8 +508,9 @@ ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
ALCjackPlayback_lock(self);
ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing.get())};
+ ret.Latency = std::chrono::seconds{ring->readSpace()};
ret.Latency /= device->Frequency;
ALCjackPlayback_unlock(self);
diff --git a/Alc/backends/opensl.cpp b/Alc/backends/opensl.cpp
index 9213919b..872fbc91 100644
--- a/Alc/backends/opensl.cpp
+++ b/Alc/backends/opensl.cpp
@@ -203,7 +203,8 @@ static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
/* this callback handler is called every time a buffer finishes playing */
static void ALCopenslPlayback_process(SLAndroidSimpleBufferQueueItf UNUSED(bq), void *context)
{
- ALCopenslPlayback *self = static_cast<ALCopenslPlayback*>(context);
+ auto self = static_cast<ALCopenslPlayback*>(context);
+ RingBuffer *ring{self->mRing.get()};
/* A note on the ringbuffer usage: The buffer queue seems to hold on to the
* pointer passed to the Enqueue method, rather than copying the audio.
@@ -213,7 +214,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.get(), 1);
+ ring->readAdvance(1);
self->mSem.post();
}
@@ -221,7 +222,8 @@ static void ALCopenslPlayback_process(SLAndroidSimpleBufferQueueItf UNUSED(bq),
static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
SLAndroidSimpleBufferQueueItf bufferQueue;
SLPlayItf player;
SLresult result;
@@ -247,7 +249,7 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
{
size_t todo;
- if(ll_ringbuffer_write_space(self->mRing.get()) == 0)
+ if(ring->writeSpace() == 0)
{
SLuint32 state = 0;
@@ -264,7 +266,7 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
break;
}
- if(ll_ringbuffer_write_space(self->mRing.get()) == 0)
+ if(ring->writeSpace() == 0)
{
ALCopenslPlayback_unlock(self);
self->mSem.wait();
@@ -273,15 +275,15 @@ static int ALCopenslPlayback_mixerProc(ALCopenslPlayback *self)
}
}
- auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto data = ring->getWriteVector();
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.get(), todo);
+ ring->writeAdvance(todo);
- for(size_t i = 0;i < todo;i++)
+ for(size_t i{0};i < todo;i++)
{
if(!data.first.len)
{
@@ -556,13 +558,13 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
{
- SLAndroidSimpleBufferQueueItf bufferQueue;
- SLresult result;
+ RingBuffer *ring{self->mRing.get()};
- ll_ringbuffer_reset(self->mRing.get());
+ ring->reset();
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ SLAndroidSimpleBufferQueueItf bufferQueue;
+ SLresult result{VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ &bufferQueue)};
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS != result)
return ALC_FALSE;
@@ -632,13 +634,13 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
ClockLatency ret;
ALCopenslPlayback_lock(self);
ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing.get()) *
- device->UpdateSize};
+ ret.Latency = std::chrono::seconds{ring->readSpace() * device->UpdateSize};
ret.Latency /= device->Frequency;
ALCopenslPlayback_unlock(self);
@@ -702,9 +704,10 @@ static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
static void ALCopenslCapture_process(SLAndroidSimpleBufferQueueItf UNUSED(bq), void *context)
{
- ALCopenslCapture *self = static_cast<ALCopenslCapture*>(context);
+ auto *self = static_cast<ALCopenslCapture*>(context);
+ RingBuffer *ring{self->mRing.get()};
/* A new chunk has been written into the ring buffer, advance it. */
- ll_ringbuffer_write_advance(self->mRing.get(), 1);
+ ring->writeAdvance(1);
}
@@ -837,10 +840,11 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
}
if(SL_RESULT_SUCCESS == result)
{
+ RingBuffer *ring{self->mRing.get()};
ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
size_t i;
- auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto data = ring->getWriteVector();
for(i = 0;i < data.first.len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data.first.buf + chunk_size*i, chunk_size);
@@ -914,7 +918,8 @@ static void ALCopenslCapture_stop(ALCopenslCapture *self)
static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLresult result;
@@ -927,7 +932,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.get());
+ auto data = ring->getReadVector();
for(i = 0;i < samples;)
{
ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
@@ -941,7 +946,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.get(), 1);
+ ring->readAdvance(1);
result = VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS != result) break;
@@ -969,8 +974,9 @@ 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.get()) * device->UpdateSize;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
+ return ring->readSpace() * device->UpdateSize;
}
diff --git a/Alc/backends/oss.cpp b/Alc/backends/oss.cpp
index e338c40d..f6a75d12 100644
--- a/Alc/backends/oss.cpp
+++ b/Alc/backends/oss.cpp
@@ -537,7 +537,8 @@ void ALCcaptureOSS_Destruct(ALCcaptureOSS *self)
int ALCcaptureOSS_recordProc(ALCcaptureOSS *self)
{
- ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
SetRTPriority();
althrd_setname(RECORD_THREAD_NAME);
@@ -564,7 +565,7 @@ int ALCcaptureOSS_recordProc(ALCcaptureOSS *self)
continue;
}
- auto vec = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto vec = ring->getWriteVector();
if(vec.first.len > 0)
{
ssize_t amt{read(self->fd, vec.first.buf, vec.first.len*frame_size)};
@@ -576,7 +577,7 @@ int ALCcaptureOSS_recordProc(ALCcaptureOSS *self)
ALCcaptureOSS_unlock(self);
break;
}
- ll_ringbuffer_write_advance(self->mRing.get(), amt/frame_size);
+ ring->writeAdvance(amt/frame_size);
}
}
@@ -724,13 +725,15 @@ void ALCcaptureOSS_stop(ALCcaptureOSS *self)
ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->mRing.get(), static_cast<char*>(buffer), samples);
+ RingBuffer *ring{self->mRing.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self)
{
- return ll_ringbuffer_read_space(self->mRing.get());
+ RingBuffer *ring{self->mRing.get()};
+ return ring->readSpace();
}
} // namespace
diff --git a/Alc/backends/portaudio.cpp b/Alc/backends/portaudio.cpp
index 59b357b5..f39661a7 100644
--- a/Alc/backends/portaudio.cpp
+++ b/Alc/backends/portaudio.cpp
@@ -365,8 +365,9 @@ int ALCportCapture_ReadCallback(const void *inputBuffer, void *UNUSED(outputBuff
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo),
const PaStreamCallbackFlags UNUSED(statusFlags), void *userData)
{
- ALCportCapture *self = static_cast<ALCportCapture*>(userData);
- ll_ringbuffer_write(self->Ring.get(), inputBuffer, framesPerBuffer);
+ auto self = static_cast<ALCportCapture*>(userData);
+ RingBuffer *ring{self->Ring.get()};
+ ring->write(inputBuffer, framesPerBuffer);
return 0;
}
@@ -456,12 +457,14 @@ void ALCportCapture_stop(ALCportCapture *self)
ALCuint ALCportCapture_availableSamples(ALCportCapture *self)
{
- return ll_ringbuffer_read_space(self->Ring.get());
+ RingBuffer *ring{self->Ring.get()};
+ return ring->readSpace();
}
ALCenum ALCportCapture_captureSamples(ALCportCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring.get(), buffer, samples);
+ RingBuffer *ring{self->Ring.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
diff --git a/Alc/backends/sndio.cpp b/Alc/backends/sndio.cpp
index 2be1d26c..887b5703 100644
--- a/Alc/backends/sndio.cpp
+++ b/Alc/backends/sndio.cpp
@@ -323,20 +323,20 @@ static void SndioCapture_Destruct(SndioCapture *self)
static int SndioCapture_recordProc(SndioCapture *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- ALsizei frameSize;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->ring.get()};
SetRTPriority();
althrd_setname(RECORD_THREAD_NAME);
- frameSize = device->frameSizeFromFmt();
+ const ALsizei frameSize{device->frameSizeFromFmt()};
while(!self->mKillNow.load(std::memory_order_acquire) &&
device->Connected.load(std::memory_order_acquire))
{
size_t total, todo;
- auto data = ll_ringbuffer_get_write_vector(self->ring.get());
+ auto data = ring->getWriteVector();
todo = data.first.len + data.second.len;
if(todo == 0)
{
@@ -369,7 +369,7 @@ static int SndioCapture_recordProc(SndioCapture *self)
data.first.len -= got;
total += got;
}
- ll_ringbuffer_write_advance(self->ring.get(), total / frameSize);
+ ring->writeAdvance(total / frameSize);
}
return 0;
@@ -514,13 +514,15 @@ static void SndioCapture_stop(SndioCapture *self)
static ALCenum SndioCapture_captureSamples(SndioCapture *self, void *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->ring.get(), static_cast<char*>(buffer), samples);
+ RingBuffer *ring{self->ring.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
static ALCuint SndioCapture_availableSamples(SndioCapture *self)
{
- return ll_ringbuffer_read_space(self->ring.get());
+ RingBuffer *ring{self->ring.get()};
+ return ring->readSpace();
}
diff --git a/Alc/backends/wasapi.cpp b/Alc/backends/wasapi.cpp
index c1b4bddb..e1783ef9 100644
--- a/Alc/backends/wasapi.cpp
+++ b/Alc/backends/wasapi.cpp
@@ -1230,7 +1230,8 @@ void ALCwasapiCapture_Destruct(ALCwasapiCapture *self)
FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
{
- ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->mRing.get()};
IAudioCaptureClient *capture{self->mCapture};
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
@@ -1272,7 +1273,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
rdata = reinterpret_cast<BYTE*>(samples.data());
}
- auto data = ll_ringbuffer_get_write_vector(self->mRing.get());
+ auto data = ring->getWriteVector();
size_t dstframes;
if(self->mSampleConv)
@@ -1308,7 +1309,7 @@ FORCE_ALIGN int ALCwasapiCapture_recordProc(ALCwasapiCapture *self)
dstframes = len1 + len2;
}
- ll_ringbuffer_write_advance(self->mRing.get(), dstframes);
+ ring->writeAdvance(dstframes);
hr = capture->ReleaseBuffer(numsamples);
if(FAILED(hr)) ERR("Failed to release capture buffer: 0x%08lx\n", hr);
@@ -1786,12 +1787,14 @@ void ALCwasapiCapture::stopProxy()
ALuint ALCwasapiCapture_availableSamples(ALCwasapiCapture *self)
{
- return (ALuint)ll_ringbuffer_read_space(self->mRing.get());
+ RingBuffer *ring{self->mRing.get()};
+ return (ALuint)ring->readSpace();
}
ALCenum ALCwasapiCapture_captureSamples(ALCwasapiCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->mRing.get(), reinterpret_cast<char*>(buffer), samples);
+ RingBuffer *ring{self->mRing.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
diff --git a/Alc/backends/winmm.cpp b/Alc/backends/winmm.cpp
index 0ebba81c..7bfb7f6c 100644
--- a/Alc/backends/winmm.cpp
+++ b/Alc/backends/winmm.cpp
@@ -472,7 +472,8 @@ void CALLBACK ALCwinmmCapture_waveInProc(HWAVEIN UNUSED(device), UINT msg,
int ALCwinmmCapture_captureProc(ALCwinmmCapture *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ ALCdevice *device{self->mDevice};
+ RingBuffer *ring{self->Ring.get()};
althrd_setname(RECORD_THREAD_NAME);
@@ -494,9 +495,7 @@ int ALCwinmmCapture_captureProc(ALCwinmmCapture *self)
WAVEHDR &waveHdr = self->WaveBuffer[widx];
widx = (widx+1) % self->WaveBuffer.size();
- ll_ringbuffer_write(self->Ring.get(), waveHdr.lpData,
- waveHdr.dwBytesRecorded / self->Format.nBlockAlign
- );
+ ring->write(waveHdr.lpData, waveHdr.dwBytesRecorded / self->Format.nBlockAlign);
self->Readable.fetch_sub(1, std::memory_order_acq_rel);
waveInAddBuffer(self->InHdl, &waveHdr, sizeof(WAVEHDR));
} while(--todo);
@@ -645,13 +644,15 @@ void ALCwinmmCapture_stop(ALCwinmmCapture *self)
ALCenum ALCwinmmCapture_captureSamples(ALCwinmmCapture *self, ALCvoid *buffer, ALCuint samples)
{
- ll_ringbuffer_read(self->Ring.get(), buffer, samples);
+ RingBuffer *ring{self->Ring.get()};
+ ring->read(buffer, samples);
return ALC_NO_ERROR;
}
ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self)
{
- return (ALCuint)ll_ringbuffer_read_space(self->Ring.get());
+ RingBuffer *ring{self->Ring.get()};
+ return (ALCuint)ring->readSpace();
}
} // namespace
diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp
index b94f26be..48844219 100644
--- a/Alc/mixvoice.cpp
+++ b/Alc/mixvoice.cpp
@@ -736,13 +736,14 @@ ALboolean MixSource(ALvoice *voice, const ALuint SourceID, ALCcontext *Context,
ALbitfieldSOFT enabledevt{Context->EnabledEvts.load(std::memory_order_acquire)};
if(buffers_done > 0 && (enabledevt&EventType_BufferCompleted))
{
- auto evt_data = ll_ringbuffer_get_write_vector(Context->AsyncEvents).first;
+ RingBuffer *ring{Context->AsyncEvents};
+ auto evt_data = ring->getWriteVector().first;
if(evt_data.len > 0)
{
AsyncEvent *evt{new (evt_data.buf) AsyncEvent{EventType_BufferCompleted}};
evt->u.bufcomp.id = SourceID;
evt->u.bufcomp.count = buffers_done;
- ll_ringbuffer_write_advance(Context->AsyncEvents, 1);
+ ring->writeAdvance(1);
Context->EventSem.post();
}
}
diff --git a/Alc/ringbuffer.cpp b/Alc/ringbuffer.cpp
index a298ff43..9e531316 100644
--- a/Alc/ringbuffer.cpp
+++ b/Alc/ringbuffer.cpp
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <limits.h>
+#include <algorithm>
+
#include "ringbuffer.h"
#include "atomic.h"
#include "threads.h"
@@ -31,9 +33,9 @@
#include "compat.h"
-ll_ringbuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
+RingBuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
{
- ll_ringbuffer *rb;
+ RingBuffer *rb;
size_t power_of_two = 0;
if(sz > 0)
@@ -51,57 +53,52 @@ ll_ringbuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
power_of_two++;
if(power_of_two < sz) return NULL;
- rb = new (al_malloc(16, sizeof(*rb) + power_of_two*elem_sz)) ll_ringbuffer{};
+ rb = new (al_malloc(16, sizeof(*rb) + power_of_two*elem_sz)) RingBuffer{};
- rb->size = limit_writes ? sz : power_of_two;
- rb->size_mask = power_of_two - 1;
- rb->elem_size = elem_sz;
+ rb->mSize = limit_writes ? sz : power_of_two;
+ rb->mSizeMask = power_of_two - 1;
+ rb->mElemSize = elem_sz;
return rb;
}
-void ll_ringbuffer_reset(ll_ringbuffer *rb)
+void RingBuffer::reset() noexcept
{
- rb->write_ptr.store(0, std::memory_order_relaxed);
- rb->read_ptr.store(0, std::memory_order_relaxed);
- std::fill_n(rb->buf+0, (rb->size_mask+1)*rb->elem_size, 0);
+ mWritePtr.store(0, std::memory_order_relaxed);
+ mReadPtr.store(0, std::memory_order_relaxed);
+ std::fill_n(mBuffer, (mSizeMask+1)*mElemSize, 0);
}
-size_t ll_ringbuffer_read_space(const ll_ringbuffer *rb)
+size_t RingBuffer::readSpace() const noexcept
{
- 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 w = mWritePtr.load(std::memory_order_acquire);
+ size_t r = mReadPtr.load(std::memory_order_acquire);
+ return (w-r) & mSizeMask;
}
-size_t ll_ringbuffer_write_space(const ll_ringbuffer *rb)
+size_t RingBuffer::writeSpace() const noexcept
{
- size_t w = rb->write_ptr.load(std::memory_order_acquire);
- size_t r = rb->read_ptr.load(std::memory_order_acquire);
- w = (r-w-1) & rb->size_mask;
- return (w > rb->size) ? rb->size : w;
+ size_t w = mWritePtr.load(std::memory_order_acquire);
+ size_t r = mReadPtr.load(std::memory_order_acquire);
+ w = (r-w-1) & mSizeMask;
+ return std::max(w, mSize);
}
-size_t ll_ringbuffer_read(ll_ringbuffer *rb, void *dest, size_t cnt)
+size_t RingBuffer::read(void *dest, size_t cnt) noexcept
{
- size_t read_ptr;
- size_t free_cnt;
- size_t cnt2;
- size_t to_read;
- size_t n1, n2;
-
- free_cnt = ll_ringbuffer_read_space(rb);
+ const size_t free_cnt{readSpace()};
if(free_cnt == 0) return 0;
- to_read = (cnt > free_cnt) ? free_cnt : cnt;
- read_ptr = rb->read_ptr.load(std::memory_order_relaxed) & rb->size_mask;
+ const size_t to_read{std::min(cnt, free_cnt)};
+ size_t read_ptr{mReadPtr.load(std::memory_order_relaxed) & mSizeMask};
- cnt2 = read_ptr + to_read;
- if(cnt2 > rb->size_mask+1)
+ size_t n1, n2;
+ const size_t cnt2{read_ptr + to_read};
+ if(cnt2 > mSizeMask+1)
{
- n1 = rb->size_mask+1 - read_ptr;
- n2 = cnt2 & rb->size_mask;
+ n1 = mSizeMask+1 - read_ptr;
+ n2 = cnt2 & mSizeMask;
}
else
{
@@ -109,38 +106,32 @@ size_t ll_ringbuffer_read(ll_ringbuffer *rb, void *dest, size_t cnt)
n2 = 0;
}
- memcpy(dest, &rb->buf[read_ptr*rb->elem_size], n1*rb->elem_size);
+ memcpy(dest, &mBuffer[read_ptr*mElemSize], n1*mElemSize);
read_ptr += n1;
if(n2)
{
- memcpy(static_cast<char*>(dest) + n1*rb->elem_size,
- &rb->buf[(read_ptr&rb->size_mask)*rb->elem_size],
- n2*rb->elem_size);
+ memcpy(static_cast<char*>(dest) + n1*mElemSize, &mBuffer[(read_ptr&mSizeMask)*mElemSize],
+ n2*mElemSize);
read_ptr += n2;
}
- rb->read_ptr.store(read_ptr, std::memory_order_release);
+ mReadPtr.store(read_ptr, std::memory_order_release);
return to_read;
}
-size_t ll_ringbuffer_peek(ll_ringbuffer *rb, void *dest, size_t cnt)
+size_t RingBuffer::peek(void *dest, size_t cnt) const noexcept
{
- size_t free_cnt;
- size_t cnt2;
- size_t to_read;
- size_t n1, n2;
- size_t read_ptr;
-
- free_cnt = ll_ringbuffer_read_space(rb);
+ const size_t free_cnt{readSpace()};
if(free_cnt == 0) return 0;
- to_read = (cnt > free_cnt) ? free_cnt : cnt;
- read_ptr = rb->read_ptr.load(std::memory_order_relaxed) & rb->size_mask;
+ const size_t to_read{std::min(cnt, free_cnt)};
+ size_t read_ptr{mReadPtr.load(std::memory_order_relaxed) & mSizeMask};
- cnt2 = read_ptr + to_read;
- if(cnt2 > rb->size_mask+1)
+ size_t n1, n2;
+ const size_t cnt2{read_ptr + to_read};
+ if(cnt2 > mSizeMask+1)
{
- n1 = rb->size_mask+1 - read_ptr;
- n2 = cnt2 & rb->size_mask;
+ n1 = mSizeMask+1 - read_ptr;
+ n2 = cnt2 & mSizeMask;
}
else
{
@@ -148,36 +139,30 @@ size_t ll_ringbuffer_peek(ll_ringbuffer *rb, void *dest, size_t cnt)
n2 = 0;
}
- memcpy(dest, &rb->buf[read_ptr*rb->elem_size], n1*rb->elem_size);
+ memcpy(dest, &mBuffer[read_ptr*mElemSize], n1*mElemSize);
if(n2)
{
read_ptr += n1;
- memcpy(static_cast<char*>(dest) + n1*rb->elem_size,
- &rb->buf[(read_ptr&rb->size_mask)*rb->elem_size],
- n2*rb->elem_size);
+ memcpy(static_cast<char*>(dest) + n1*mElemSize, &mBuffer[(read_ptr&mSizeMask)*mElemSize],
+ n2*mElemSize);
}
return to_read;
}
-size_t ll_ringbuffer_write(ll_ringbuffer *rb, const void *src, size_t cnt)
+size_t RingBuffer::write(const void *src, size_t cnt) noexcept
{
- size_t write_ptr;
- size_t free_cnt;
- size_t cnt2;
- size_t to_write;
- size_t n1, n2;
-
- free_cnt = ll_ringbuffer_write_space(rb);
+ const size_t free_cnt{writeSpace()};
if(free_cnt == 0) return 0;
- to_write = (cnt > free_cnt) ? free_cnt : cnt;
- write_ptr = rb->write_ptr.load(std::memory_order_relaxed) & rb->size_mask;
+ const size_t to_write{std::min(cnt, free_cnt)};
+ size_t write_ptr{mWritePtr.load(std::memory_order_relaxed) & mSizeMask};
- cnt2 = write_ptr + to_write;
- if(cnt2 > rb->size_mask+1)
+ size_t n1, n2;
+ const size_t cnt2{write_ptr + to_write};
+ if(cnt2 > mSizeMask+1)
{
- n1 = rb->size_mask+1 - write_ptr;
- n2 = cnt2 & rb->size_mask;
+ n1 = mSizeMask+1 - write_ptr;
+ n2 = cnt2 & mSizeMask;
}
else
{
@@ -185,57 +170,54 @@ size_t ll_ringbuffer_write(ll_ringbuffer *rb, const void *src, size_t cnt)
n2 = 0;
}
- memcpy(&rb->buf[write_ptr*rb->elem_size], src, n1*rb->elem_size);
+ memcpy(&mBuffer[write_ptr*mElemSize], src, n1*mElemSize);
write_ptr += n1;
if(n2)
{
- memcpy(&rb->buf[(write_ptr&rb->size_mask)*rb->elem_size],
- static_cast<const char*>(src) + n1*rb->elem_size,
- n2*rb->elem_size);
+ memcpy(&mBuffer[(write_ptr&mSizeMask)*mElemSize],
+ static_cast<const char*>(src) + n1*mElemSize, n2*mElemSize);
write_ptr += n2;
}
- rb->write_ptr.store(write_ptr, std::memory_order_release);
+ mWritePtr.store(write_ptr, std::memory_order_release);
return to_write;
}
-void ll_ringbuffer_read_advance(ll_ringbuffer *rb, size_t cnt)
+void RingBuffer::readAdvance(size_t cnt) noexcept
{
- rb->read_ptr.fetch_add(cnt, std::memory_order_acq_rel);
+ mReadPtr.fetch_add(cnt, std::memory_order_acq_rel);
}
-void ll_ringbuffer_write_advance(ll_ringbuffer *rb, size_t cnt)
+void RingBuffer::writeAdvance(size_t cnt) noexcept
{
- rb->write_ptr.fetch_add(cnt, std::memory_order_acq_rel);
+ mWritePtr.fetch_add(cnt, std::memory_order_acq_rel);
}
-ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer *rb)
+ll_ringbuffer_data_pair RingBuffer::getWriteVector() const noexcept
{
ll_ringbuffer_data_pair ret;
- size_t free_cnt;
- size_t cnt2;
- size_t w = rb->write_ptr.load(std::memory_order_acquire);
- size_t r = rb->read_ptr.load(std::memory_order_acquire);
- w &= rb->size_mask;
- r &= rb->size_mask;
- free_cnt = (w-r) & rb->size_mask;
+ size_t w{mWritePtr.load(std::memory_order_acquire)};
+ size_t r{mReadPtr.load(std::memory_order_acquire)};
+ w &= mSizeMask;
+ r &= mSizeMask;
+ const size_t free_cnt{(w-r) & mSizeMask};
- cnt2 = r + free_cnt;
- if(cnt2 > rb->size_mask+1)
+ const size_t cnt2{r + free_cnt};
+ if(cnt2 > mSizeMask+1)
{
/* Two part vector: the rest of the buffer after the current write ptr,
* plus some from the start of the buffer. */
- ret.first.buf = const_cast<char*>(&rb->buf[r*rb->elem_size]);
- ret.first.len = rb->size_mask+1 - r;
- ret.second.buf = const_cast<char*>(rb->buf);
- ret.second.len = cnt2 & rb->size_mask;
+ ret.first.buf = const_cast<char*>(&mBuffer[r*mElemSize]);
+ ret.first.len = mSizeMask+1 - r;
+ ret.second.buf = const_cast<char*>(mBuffer);
+ ret.second.len = cnt2 & mSizeMask;
}
else
{
/* Single part vector: just the rest of the buffer */
- ret.first.buf = const_cast<char*>(&rb->buf[r*rb->elem_size]);
+ ret.first.buf = const_cast<char*>(&mBuffer[r*mElemSize]);
ret.first.len = free_cnt;
ret.second.buf = nullptr;
ret.second.len = 0;
@@ -244,32 +226,29 @@ ll_ringbuffer_data_pair ll_ringbuffer_get_read_vector(const ll_ringbuffer *rb)
return ret;
}
-ll_ringbuffer_data_pair ll_ringbuffer_get_write_vector(const ll_ringbuffer *rb)
+ll_ringbuffer_data_pair RingBuffer::getReadVector() const noexcept
{
ll_ringbuffer_data_pair ret;
- size_t free_cnt;
- size_t cnt2;
-
- size_t w = rb->write_ptr.load(std::memory_order_acquire);
- size_t r = rb->read_ptr.load(std::memory_order_acquire);
- w &= rb->size_mask;
- r &= rb->size_mask;
- free_cnt = (r-w-1) & rb->size_mask;
- if(free_cnt > rb->size) free_cnt = rb->size;
-
- cnt2 = w + free_cnt;
- if(cnt2 > rb->size_mask+1)
+
+ size_t w{mWritePtr.load(std::memory_order_acquire)};
+ size_t r{mReadPtr.load(std::memory_order_acquire)};
+ w &= mSizeMask;
+ r &= mSizeMask;
+ const size_t free_cnt{std::min((r-w-1) & mSizeMask, mSize)};
+
+ const size_t cnt2{w + free_cnt};
+ if(cnt2 > mSizeMask+1)
{
/* Two part vector: the rest of the buffer after the current write ptr,
* plus some from the start of the buffer. */
- ret.first.buf = const_cast<char*>(&rb->buf[w*rb->elem_size]);
- ret.first.len = rb->size_mask+1 - w;
- ret.second.buf = const_cast<char*>(rb->buf);
- ret.second.len = cnt2 & rb->size_mask;
+ ret.first.buf = const_cast<char*>(&mBuffer[w*mElemSize]);
+ ret.first.len = mSizeMask+1 - w;
+ ret.second.buf = const_cast<char*>(mBuffer);
+ ret.second.len = cnt2 & mSizeMask;
}
else
{
- ret.first.buf = const_cast<char*>(&rb->buf[w*rb->elem_size]);
+ ret.first.buf = const_cast<char*>(&mBuffer[w*mElemSize]);
ret.first.len = free_cnt;
ret.second.buf = nullptr;
ret.second.len = 0;
diff --git a/Alc/ringbuffer.h b/Alc/ringbuffer.h
index 5111023e..a2871859 100644
--- a/Alc/ringbuffer.h
+++ b/Alc/ringbuffer.h
@@ -15,18 +15,6 @@
* 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_data {
char *buf;
@@ -35,60 +23,74 @@ struct ll_ringbuffer_data {
using ll_ringbuffer_data_pair = std::pair<ll_ringbuffer_data,ll_ringbuffer_data>;
-/**
- * Create a new ringbuffer to hold at least `sz' elements of `elem_sz' bytes.
- * 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 *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 *rb);
+struct RingBuffer {
+ std::atomic<size_t> mWritePtr{0u};
+ std::atomic<size_t> mReadPtr{0u};
+ size_t mSize{0u};
+ size_t mSizeMask{0u};
+ size_t mElemSize{0u};
+
+ alignas(16) char mBuffer[];
+
+ /** Reset the read and write pointers to zero. This is not thread safe. */
+ void reset() noexcept;
+
+ /**
+ * The non-copying data reader. Returns two ringbuffer data pointers that
+ * hold the current readable data. If the readable data is in one segment
+ * the second segment has zero length.
+ */
+ ll_ringbuffer_data_pair getReadVector() const noexcept;
+ /**
+ * The non-copying data writer. Returns two ringbuffer data pointers that
+ * hold the current writeable data. If the writeable data is in one segment
+ * the second segment has zero length.
+ */
+ ll_ringbuffer_data_pair getWriteVector() const noexcept;
+
+ /**
+ * 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 readSpace() const noexcept;
+ /**
+ * The copying data reader. Copy at most `cnt' elements into `dest'.
+ * Returns the actual number of elements copied.
+ */
+ size_t read(void *dest, size_t cnt) noexcept;
+ /**
+ * The copying data reader w/o read pointer advance. Copy at most `cnt'
+ * elements into `dest'. Returns the actual number of elements copied.
+ */
+ size_t peek(void *dest, size_t cnt) const noexcept;
+ /** Advance the read pointer `cnt' places. */
+ void readAdvance(size_t cnt) noexcept;
+
+ /**
+ * 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 writeSpace() const noexcept;
+ /**
+ * The copying data writer. Copy at most `cnt' elements from `src'. Returns
+ * the actual number of elements copied.
+ */
+ size_t write(const void *src, size_t cnt) noexcept;
+ /** Advance the write pointer `cnt' places. */
+ void writeAdvance(size_t cnt) noexcept;
-/**
- * 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 *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 *rb);
+ DEF_PLACE_NEWDEL()
+};
-/**
- * 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 *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 *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 *rb, void *dest, size_t cnt);
-/** Advance the read pointer `cnt' places. */
-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 *rb);
-/**
- * The copying data writer. Copy at most `cnt' elements to `rb' from `src'.
- * Returns the actual number of elements copied.
+ * Create a new ringbuffer to hold at least `sz' elements of `elem_sz' bytes.
+ * 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).
*/
-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 *rb, size_t cnt);
+RingBuffer *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes);
-using RingBufferPtr = std::unique_ptr<ll_ringbuffer>;
+using RingBufferPtr = std::unique_ptr<RingBuffer>;
#endif /* RINGBUFFER_H */
diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp
index b70fc872..03375e2d 100644
--- a/OpenAL32/alSource.cpp
+++ b/OpenAL32/alSource.cpp
@@ -691,13 +691,14 @@ void SendStateChangeEvent(ALCcontext *context, ALuint id, ALenum state)
* and we don't want state change messages to occur out of order, so send
* it through the async queue to ensure proper ordering.
*/
- auto evt_data = ll_ringbuffer_get_write_vector(context->AsyncEvents).first;
- if(evt_data.len < 1) return;
+ RingBuffer *ring{context->AsyncEvents};
+ auto evt_vec = ring->getWriteVector();
+ if(evt_vec.first.len < 1) return;
- AsyncEvent *evt{new (evt_data.buf) AsyncEvent{EventType_SourceStateChange}};
+ AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}};
evt->u.srcstate.id = id;
evt->u.srcstate.state = state;
- ll_ringbuffer_write_advance(context->AsyncEvents, 1);
+ ring->writeAdvance(1);
context->EventSem.post();
}
diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp
index 6399603b..f14c3229 100644
--- a/OpenAL32/event.cpp
+++ b/OpenAL32/event.cpp
@@ -17,10 +17,11 @@
static int EventThread(ALCcontext *context)
{
+ RingBuffer *ring{context->AsyncEvents};
bool quitnow{false};
while(LIKELY(!quitnow))
{
- auto evt_data = ll_ringbuffer_get_read_vector(context->AsyncEvents).first;
+ auto evt_data = ring->getReadVector().first;
if(evt_data.len == 0)
{
context->EventSem.wait();
@@ -37,11 +38,11 @@ static int EventThread(ALCcontext *context)
*/
const struct EventAutoDestructor {
AsyncEvent &evt;
- ll_ringbuffer *ring;
+ RingBuffer *ring;
~EventAutoDestructor()
{
evt.~AsyncEvent();
- ll_ringbuffer_read_advance(ring, 1);
+ ring->readAdvance(1);
}
} _{evt, context->AsyncEvents};
@@ -110,16 +111,17 @@ void StartEventThrd(ALCcontext *ctx)
void StopEventThrd(ALCcontext *ctx)
{
static constexpr AsyncEvent kill_evt{EventType_KillThread};
- ll_ringbuffer_data evt_data = ll_ringbuffer_get_write_vector(ctx->AsyncEvents).first;
+ RingBuffer *ring{ctx->AsyncEvents};
+ auto evt_data = ring->getWriteVector().first;
if(evt_data.len == 0)
{
do {
std::this_thread::yield();
- evt_data = ll_ringbuffer_get_write_vector(ctx->AsyncEvents).first;
+ evt_data = ring->getWriteVector().first;
} while(evt_data.len == 0);
}
new (evt_data.buf) AsyncEvent{kill_evt};
- ll_ringbuffer_write_advance(ctx->AsyncEvents, 1);
+ ring->writeAdvance(1);
ctx->EventSem.post();
if(ctx->EventThread.joinable())