diff options
author | Chris Robinson <[email protected]> | 2018-03-01 21:23:13 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-03-01 21:23:13 -0800 |
commit | 6f62fed65c4dcdf999a612e258cca59a22355f3c (patch) | |
tree | bd8d8f9e84beb94761ae35da41c3e66465af62a8 | |
parent | cba37819d1e68ff6473d0e10b42ac9465943d5cb (diff) |
Add an option to limit the write size of the ringbuffer
-rw-r--r-- | Alc/backends/alsa.c | 3 | ||||
-rw-r--r-- | Alc/backends/coreaudio.c | 2 | ||||
-rw-r--r-- | Alc/backends/dsound.c | 2 | ||||
-rw-r--r-- | Alc/backends/jack.c | 6 | ||||
-rw-r--r-- | Alc/backends/mmdevapi.c | 3 | ||||
-rw-r--r-- | Alc/backends/opensl.c | 16 | ||||
-rw-r--r-- | Alc/backends/oss.c | 2 | ||||
-rw-r--r-- | Alc/backends/portaudio.c | 2 | ||||
-rw-r--r-- | Alc/backends/winmm.c | 2 | ||||
-rw-r--r-- | Alc/ringbuffer.c | 32 | ||||
-rw-r--r-- | Alc/ringbuffer.h | 2 | ||||
-rw-r--r-- | OpenAL32/event.c | 2 |
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, |