Use a normal delete instead of ll_ringbuffer_free

And use RingBufferPtr in more places
This commit is contained in:
Chris Robinson
2018-12-22 11:38:38 -08:00
parent b955c5cf5d
commit 10ce121dbd
12 changed files with 119 additions and 169 deletions
+1 -1
View File
@@ -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);
+7 -11
View File
@@ -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)
+7 -13
View File
@@ -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;
}
+9 -13
View File
@@ -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
+20 -28
View File
@@ -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;
}
+7 -8
View File
@@ -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
+6 -12
View File
@@ -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;
}
+7 -9
View File
@@ -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());
}
+6 -12
View File
@@ -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;
}
+5 -8
View File
@@ -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
+12 -33
View File
@@ -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;
+32 -21
View File
@@ -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 */