aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-03-01 21:23:13 -0800
committerChris Robinson <[email protected]>2018-03-01 21:23:13 -0800
commit6f62fed65c4dcdf999a612e258cca59a22355f3c (patch)
treebd8d8f9e84beb94761ae35da41c3e66465af62a8
parentcba37819d1e68ff6473d0e10b42ac9465943d5cb (diff)
Add an option to limit the write size of the ringbuffer
-rw-r--r--Alc/backends/alsa.c3
-rw-r--r--Alc/backends/coreaudio.c2
-rw-r--r--Alc/backends/dsound.c2
-rw-r--r--Alc/backends/jack.c6
-rw-r--r--Alc/backends/mmdevapi.c3
-rw-r--r--Alc/backends/opensl.c16
-rw-r--r--Alc/backends/oss.c2
-rw-r--r--Alc/backends/portaudio.c2
-rw-r--r--Alc/backends/winmm.c2
-rw-r--r--Alc/ringbuffer.c32
-rw-r--r--Alc/ringbuffer.h2
-rw-r--r--OpenAL32/event.c2
12 files changed, 37 insertions, 37 deletions
diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c
index c75749de..d0f0e24e 100644
--- a/Alc/backends/alsa.c
+++ b/Alc/backends/alsa.c
@@ -1124,7 +1124,8 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name)
{
self->ring = ll_ringbuffer_create(
device->UpdateSize*device->NumUpdates + 1,
- FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder)
+ FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
+ false
);
if(!self->ring)
{
diff --git a/Alc/backends/coreaudio.c b/Alc/backends/coreaudio.c
index 3db0d702..caa01167 100644
--- a/Alc/backends/coreaudio.c
+++ b/Alc/backends/coreaudio.c
@@ -664,7 +664,7 @@ static ALCenum ALCcoreAudioCapture_open(ALCcoreAudioCapture *self, const ALCchar
self->ring = ll_ringbuffer_create(
device->UpdateSize*self->sampleRateRatio*device->NumUpdates + 1,
- self->frameSize
+ self->frameSize, false
);
if(!self->ring) goto error;
diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c
index 0040a840..4c52e0f8 100644
--- a/Alc/backends/dsound.c
+++ b/Alc/backends/dsound.c
@@ -857,7 +857,7 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi
if(SUCCEEDED(hr))
{
self->Ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates + 1,
- InputType.Format.nBlockAlign);
+ InputType.Format.nBlockAlign, false);
if(self->Ring == NULL)
hr = DSERR_OUTOFMEMORY;
}
diff --git a/Alc/backends/jack.c b/Alc/backends/jack.c
index e6f4b435..003877a4 100644
--- a/Alc/backends/jack.c
+++ b/Alc/backends/jack.c
@@ -236,7 +236,8 @@ static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg)
ll_ringbuffer_free(self->Ring);
self->Ring = ll_ringbuffer_create(bufsize,
- FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder)
+ FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
+ true
);
if(!self->Ring)
{
@@ -437,7 +438,8 @@ static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
ll_ringbuffer_free(self->Ring);
self->Ring = ll_ringbuffer_create(bufsize,
- FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder)
+ FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
+ true
);
if(!self->Ring)
{
diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c
index 5f1dbba8..34dcf468 100644
--- a/Alc/backends/mmdevapi.c
+++ b/Alc/backends/mmdevapi.c
@@ -1813,7 +1813,8 @@ static HRESULT ALCmmdevCapture_resetProxy(ALCmmdevCapture *self)
buffer_len = maxu(device->UpdateSize*device->NumUpdates + 1, buffer_len);
ll_ringbuffer_free(self->Ring);
self->Ring = ll_ringbuffer_create(buffer_len,
- FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder)
+ FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder),
+ false
);
if(!self->Ring)
{
diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c
index b20d7841..d930526d 100644
--- a/Alc/backends/opensl.c
+++ b/Alc/backends/opensl.c
@@ -239,7 +239,6 @@ static int ALCopenslPlayback_mixerProc(void *arg)
ll_ringbuffer_data_t data[2];
SLPlayItf player;
SLresult result;
- size_t padding;
SetRTPriority();
althrd_setname(althrd_current(), MIXER_THREAD_NAME);
@@ -260,18 +259,13 @@ static int ALCopenslPlayback_mixerProc(void *arg)
return 1;
}
- /* NOTE: The ringbuffer will be larger than the desired buffer metrics.
- * Calculate the amount of extra space so we know how much to keep unused.
- */
- padding = ll_ringbuffer_write_space(self->mRing) - device->NumUpdates;
-
ALCopenslPlayback_lock(self);
while(!ATOMIC_LOAD(&self->mKillNow, almemory_order_acquire) &&
ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
{
size_t todo, len0, len1;
- if(ll_ringbuffer_write_space(self->mRing) <= padding)
+ if(ll_ringbuffer_write_space(self->mRing) == 0)
{
SLuint32 state = 0;
@@ -288,7 +282,7 @@ static int ALCopenslPlayback_mixerProc(void *arg)
break;
}
- if(ll_ringbuffer_write_space(self->mRing) <= padding)
+ if(ll_ringbuffer_write_space(self->mRing) == 0)
{
ALCopenslPlayback_unlock(self);
alsem_wait(&self->mSem);
@@ -298,7 +292,7 @@ static int ALCopenslPlayback_mixerProc(void *arg)
}
ll_ringbuffer_get_write_vector(self->mRing, data);
- todo = data[0].len+data[1].len - padding;
+ todo = data[0].len+data[1].len;
len0 = minu(todo, data[0].len);
len1 = minu(todo-len0, data[1].len);
@@ -577,7 +571,7 @@ static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
* buffer will not be writeable, and we only write in period-sized chunks.
*/
self->mRing = ll_ringbuffer_create(device->NumUpdates + 1,
- self->mFrameSize*device->UpdateSize);
+ self->mFrameSize*device->UpdateSize, true);
result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
@@ -854,7 +848,7 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
if(SL_RESULT_SUCCESS == result)
{
self->mRing = ll_ringbuffer_create(device->NumUpdates + 1,
- device->UpdateSize * self->mFrameSize);
+ device->UpdateSize * self->mFrameSize, false);
result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue);
diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c
index faf3ee99..61d25476 100644
--- a/Alc/backends/oss.c
+++ b/Alc/backends/oss.c
@@ -729,7 +729,7 @@ static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
return ALC_INVALID_VALUE;
}
- self->ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates + 1, frameSize);
+ self->ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates + 1, frameSize, false);
if(!self->ring)
{
ERR("Ring buffer create failed\n");
diff --git a/Alc/backends/portaudio.c b/Alc/backends/portaudio.c
index fdc8a2a5..9b0d3487 100644
--- a/Alc/backends/portaudio.c
+++ b/Alc/backends/portaudio.c
@@ -395,7 +395,7 @@ static ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
samples = maxu(samples, 100 * device->Frequency / 1000);
frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
- self->ring = ll_ringbuffer_create(samples, frame_size);
+ self->ring = ll_ringbuffer_create(samples, frame_size, false);
if(self->ring == NULL) return ALC_INVALID_VALUE;
self->params.device = -1;
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index d6ecd7a9..787ba8e4 100644
--- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c
@@ -626,7 +626,7 @@ static ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *name)
if(CapturedDataSize < (self->Format.nSamplesPerSec / 10))
CapturedDataSize = self->Format.nSamplesPerSec / 10;
- self->Ring = ll_ringbuffer_create(CapturedDataSize+1, self->Format.nBlockAlign);
+ self->Ring = ll_ringbuffer_create(CapturedDataSize+1, self->Format.nBlockAlign, false);
if(!self->Ring) goto failure;
InitRef(&self->WaveBuffersCommitted, 0);
diff --git a/Alc/ringbuffer.c b/Alc/ringbuffer.c
index c594331e..02fa857c 100644
--- a/Alc/ringbuffer.c
+++ b/Alc/ringbuffer.c
@@ -48,7 +48,7 @@ struct ll_ringbuffer {
/* 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. */
-ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz)
+ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes)
{
ll_ringbuffer_t *rb;
size_t power_of_two = 0;
@@ -73,8 +73,8 @@ ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz)
ATOMIC_INIT(&rb->write_ptr, 0);
ATOMIC_INIT(&rb->read_ptr, 0);
- rb->size = power_of_two;
- rb->size_mask = rb->size - 1;
+ rb->size = limit_writes ? sz : power_of_two;
+ rb->size_mask = power_of_two - 1;
rb->elem_size = elem_sz;
return rb;
}
@@ -90,7 +90,7 @@ void ll_ringbuffer_reset(ll_ringbuffer_t *rb)
{
ATOMIC_STORE(&rb->write_ptr, 0, almemory_order_release);
ATOMIC_STORE(&rb->read_ptr, 0, almemory_order_release);
- memset(rb->buf, 0, rb->size*rb->elem_size);
+ memset(rb->buf, 0, (rb->size_mask+1)*rb->elem_size);
}
/* Return the number of elements available for reading. This is the number of
@@ -107,7 +107,8 @@ size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb)
{
size_t w = ATOMIC_LOAD(&CONST_CAST(ll_ringbuffer_t*,rb)->write_ptr, almemory_order_acquire);
size_t r = ATOMIC_LOAD(&CONST_CAST(ll_ringbuffer_t*,rb)->read_ptr, almemory_order_acquire);
- return (r-w-1) & rb->size_mask;
+ w = (r-w-1) & rb->size_mask;
+ return (w > rb->size) ? rb->size : w;
}
/* The copying data reader. Copy at most `cnt' elements from `rb' to `dest'.
@@ -127,9 +128,9 @@ size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt)
read_ptr = ATOMIC_LOAD(&rb->read_ptr, almemory_order_relaxed) & rb->size_mask;
cnt2 = read_ptr + to_read;
- if(cnt2 > rb->size)
+ if(cnt2 > rb->size_mask+1)
{
- n1 = rb->size - read_ptr;
+ n1 = rb->size_mask+1 - read_ptr;
n2 = cnt2 & rb->size_mask;
}
else
@@ -168,9 +169,9 @@ size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt)
read_ptr = ATOMIC_LOAD(&rb->read_ptr, almemory_order_relaxed) & rb->size_mask;
cnt2 = read_ptr + to_read;
- if(cnt2 > rb->size)
+ if(cnt2 > rb->size_mask+1)
{
- n1 = rb->size - read_ptr;
+ n1 = rb->size_mask+1 - read_ptr;
n2 = cnt2 & rb->size_mask;
}
else
@@ -206,9 +207,9 @@ size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt)
write_ptr = ATOMIC_LOAD(&rb->write_ptr, almemory_order_relaxed) & rb->size_mask;
cnt2 = write_ptr + to_write;
- if(cnt2 > rb->size)
+ if(cnt2 > rb->size_mask+1)
{
- n1 = rb->size - write_ptr;
+ n1 = rb->size_mask+1 - write_ptr;
n2 = cnt2 & rb->size_mask;
}
else
@@ -257,12 +258,12 @@ void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data
free_cnt = (w-r) & rb->size_mask;
cnt2 = r + free_cnt;
- if(cnt2 > rb->size)
+ if(cnt2 > rb->size_mask+1)
{
/* Two part vector: the rest of the buffer after the current write ptr,
* plus some from the start of the buffer. */
vec[0].buf = (char*)&rb->buf[r*rb->elem_size];
- vec[0].len = rb->size - r;
+ vec[0].len = rb->size_mask+1 - r;
vec[1].buf = (char*)rb->buf;
vec[1].len = cnt2 & rb->size_mask;
}
@@ -290,14 +291,15 @@ void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_dat
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)
+ if(cnt2 > rb->size_mask+1)
{
/* Two part vector: the rest of the buffer after the current write ptr,
* plus some from the start of the buffer. */
vec[0].buf = (char*)&rb->buf[w*rb->elem_size];
- vec[0].len = rb->size - w;
+ vec[0].len = rb->size_mask+1 - w;
vec[1].buf = (char*)rb->buf;
vec[1].len = cnt2 & rb->size_mask;
}
diff --git a/Alc/ringbuffer.h b/Alc/ringbuffer.h
index f764c20f..c1a7a6fa 100644
--- a/Alc/ringbuffer.h
+++ b/Alc/ringbuffer.h
@@ -10,7 +10,7 @@ typedef struct ll_ringbuffer_data {
size_t len;
} ll_ringbuffer_data_t;
-ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
+ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz, int limit_writes);
void ll_ringbuffer_free(ll_ringbuffer_t *rb);
void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
diff --git a/OpenAL32/event.c b/OpenAL32/event.c
index ef36f977..333b7613 100644
--- a/OpenAL32/event.c
+++ b/OpenAL32/event.c
@@ -78,7 +78,7 @@ AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, A
bool isrunning;
almtx_lock(&context->EventThrdLock);
if(!context->AsyncEvents)
- context->AsyncEvents = ll_ringbuffer_create(64, sizeof(AsyncEvent));
+ context->AsyncEvents = ll_ringbuffer_create(63, sizeof(AsyncEvent), false);
enabledevts = ATOMIC_LOAD(&context->EnabledEvts, almemory_order_relaxed);
isrunning = !!enabledevts;
while(ATOMIC_COMPARE_EXCHANGE_WEAK(&context->EnabledEvts, &enabledevts, enabledevts|flags,