|
|
|
@@ -23,13 +23,13 @@ |
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
// RingBuffer structs |
|
|
|
|
|
|
|
struct HeapRingBuffer { |
|
|
|
struct HeapBuffer { |
|
|
|
uint32_t size; |
|
|
|
int32_t head, tail, written; |
|
|
|
bool invalidateCommit; |
|
|
|
char* buf; |
|
|
|
|
|
|
|
HeapRingBuffer& operator=(const HeapRingBuffer& rb) noexcept |
|
|
|
HeapBuffer& operator=(const HeapBuffer& rb) noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size == rb.size, *this); |
|
|
|
|
|
|
|
@@ -44,7 +44,7 @@ struct HeapRingBuffer { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct StackRingBuffer { |
|
|
|
struct StackBuffer { |
|
|
|
static const uint32_t size = 4096; |
|
|
|
int32_t head, tail, written; |
|
|
|
bool invalidateCommit; |
|
|
|
@@ -54,12 +54,12 @@ struct StackRingBuffer { |
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
// RingBufferControl templated class |
|
|
|
|
|
|
|
template <class RingBufferStruct> |
|
|
|
template <class BufferStruct> |
|
|
|
class RingBufferControl |
|
|
|
{ |
|
|
|
public: |
|
|
|
RingBufferControl(RingBufferStruct* const ringBuf) noexcept |
|
|
|
: fRingBuf(ringBuf) |
|
|
|
RingBufferControl(BufferStruct* const ringBuf) noexcept |
|
|
|
: fBuffer(ringBuf) |
|
|
|
{ |
|
|
|
if (ringBuf != nullptr) |
|
|
|
clear(); |
|
|
|
@@ -67,23 +67,23 @@ public: |
|
|
|
|
|
|
|
void clear() noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); |
|
|
|
|
|
|
|
fRingBuf->head = 0; |
|
|
|
fRingBuf->tail = 0; |
|
|
|
fRingBuf->written = 0; |
|
|
|
fRingBuf->invalidateCommit = false; |
|
|
|
fBuffer->head = 0; |
|
|
|
fBuffer->tail = 0; |
|
|
|
fBuffer->written = 0; |
|
|
|
fBuffer->invalidateCommit = false; |
|
|
|
|
|
|
|
if (fRingBuf->size > 0) |
|
|
|
carla_zeroChar(fRingBuf->buf, fRingBuf->size); |
|
|
|
if (fBuffer->size > 0) |
|
|
|
carla_zeroChar(fBuffer->buf, fBuffer->size); |
|
|
|
} |
|
|
|
|
|
|
|
void setRingBuffer(RingBufferStruct* const ringBuf, const bool reset) noexcept |
|
|
|
void setRingBuffer(BufferStruct* const ringBuf, const bool reset) noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(ringBuf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(ringBuf != fRingBuf,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(ringBuf != fBuffer,); |
|
|
|
|
|
|
|
fRingBuf = ringBuf; |
|
|
|
fBuffer = ringBuf; |
|
|
|
|
|
|
|
if (reset) |
|
|
|
clear(); |
|
|
|
@@ -93,26 +93,26 @@ public: |
|
|
|
|
|
|
|
bool commitWrite() noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr, false); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); |
|
|
|
|
|
|
|
if (fRingBuf->invalidateCommit) |
|
|
|
if (fBuffer->invalidateCommit) |
|
|
|
{ |
|
|
|
fRingBuf->written = fRingBuf->head; |
|
|
|
fRingBuf->invalidateCommit = false; |
|
|
|
fBuffer->written = fBuffer->head; |
|
|
|
fBuffer->invalidateCommit = false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fRingBuf->head = fRingBuf->written; |
|
|
|
fBuffer->head = fBuffer->written; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool isDataAvailable() const noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr, false); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); |
|
|
|
|
|
|
|
return (fRingBuf->head != fRingBuf->tail); |
|
|
|
return (fBuffer->head != fBuffer->tail); |
|
|
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
|
@@ -179,25 +179,25 @@ public: |
|
|
|
protected: |
|
|
|
void tryRead(void* const buf, const size_t size) noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(buf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size != 0,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size < fRingBuf->size,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size,); |
|
|
|
|
|
|
|
// this should not happen |
|
|
|
CARLA_ASSERT(fRingBuf->head >= 0); |
|
|
|
CARLA_ASSERT(fRingBuf->tail >= 0); |
|
|
|
CARLA_ASSERT(fRingBuf->written >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->head >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->tail >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->written >= 0); |
|
|
|
|
|
|
|
// empty |
|
|
|
if (fRingBuf->head == fRingBuf->tail) |
|
|
|
if (fBuffer->head == fBuffer->tail) |
|
|
|
return; |
|
|
|
|
|
|
|
char* const charbuf(static_cast<char*>(buf)); |
|
|
|
|
|
|
|
const size_t head(static_cast<size_t>(fRingBuf->head)); |
|
|
|
const size_t tail(static_cast<size_t>(fRingBuf->tail)); |
|
|
|
const size_t wrap((head < tail) ? fRingBuf->size : 0); |
|
|
|
const size_t head(static_cast<size_t>(fBuffer->head)); |
|
|
|
const size_t tail(static_cast<size_t>(fBuffer->tail)); |
|
|
|
const size_t wrap((head < tail) ? fBuffer->size : 0); |
|
|
|
|
|
|
|
if (head - tail + wrap < size) |
|
|
|
{ |
|
|
|
@@ -207,65 +207,65 @@ protected: |
|
|
|
|
|
|
|
size_t readto = tail + size; |
|
|
|
|
|
|
|
if (readto >= fRingBuf->size) |
|
|
|
if (readto >= fBuffer->size) |
|
|
|
{ |
|
|
|
readto -= fRingBuf->size; |
|
|
|
const size_t firstpart(fRingBuf->size - tail); |
|
|
|
std::memcpy(charbuf, fRingBuf->buf + tail, firstpart); |
|
|
|
std::memcpy(charbuf + firstpart, fRingBuf->buf, readto); |
|
|
|
readto -= fBuffer->size; |
|
|
|
const size_t firstpart(fBuffer->size - tail); |
|
|
|
std::memcpy(charbuf, fBuffer->buf + tail, firstpart); |
|
|
|
std::memcpy(charbuf + firstpart, fBuffer->buf, readto); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
std::memcpy(charbuf, fRingBuf->buf + tail, size); |
|
|
|
std::memcpy(charbuf, fBuffer->buf + tail, size); |
|
|
|
} |
|
|
|
|
|
|
|
fRingBuf->tail = static_cast<int32_t>(readto); |
|
|
|
fBuffer->tail = static_cast<int32_t>(readto); |
|
|
|
} |
|
|
|
|
|
|
|
void tryWrite(const void* const buf, const size_t size) noexcept |
|
|
|
{ |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(buf != nullptr,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size != 0,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size < fRingBuf->size,); |
|
|
|
CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size,); |
|
|
|
|
|
|
|
// this should not happen |
|
|
|
CARLA_ASSERT(fRingBuf->head >= 0); |
|
|
|
CARLA_ASSERT(fRingBuf->tail >= 0); |
|
|
|
CARLA_ASSERT(fRingBuf->written >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->head >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->tail >= 0); |
|
|
|
CARLA_ASSERT(fBuffer->written >= 0); |
|
|
|
|
|
|
|
const char* const charbuf(static_cast<const char*>(buf)); |
|
|
|
|
|
|
|
const size_t tail(static_cast<size_t>(fRingBuf->tail)); |
|
|
|
const size_t wrtn(static_cast<size_t>(fRingBuf->written)); |
|
|
|
const size_t wrap((tail <= wrtn) ? fRingBuf->size : 0); |
|
|
|
const size_t tail(static_cast<size_t>(fBuffer->tail)); |
|
|
|
const size_t wrtn(static_cast<size_t>(fBuffer->written)); |
|
|
|
const size_t wrap((tail <= wrtn) ? fBuffer->size : 0); |
|
|
|
|
|
|
|
if (tail - wrtn + wrap <= size) |
|
|
|
{ |
|
|
|
carla_stderr2("RingBufferControl::tryWrite() - buffer full!"); |
|
|
|
fRingBuf->invalidateCommit = true; |
|
|
|
fBuffer->invalidateCommit = true; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
size_t writeto = wrtn + size; |
|
|
|
|
|
|
|
if (writeto >= fRingBuf->size) |
|
|
|
if (writeto >= fBuffer->size) |
|
|
|
{ |
|
|
|
writeto -= fRingBuf->size; |
|
|
|
const size_t firstpart(fRingBuf->size - wrtn); |
|
|
|
std::memcpy(fRingBuf->buf + wrtn, charbuf, firstpart); |
|
|
|
std::memcpy(fRingBuf->buf, charbuf + firstpart, writeto); |
|
|
|
writeto -= fBuffer->size; |
|
|
|
const size_t firstpart(fBuffer->size - wrtn); |
|
|
|
std::memcpy(fBuffer->buf + wrtn, charbuf, firstpart); |
|
|
|
std::memcpy(fBuffer->buf, charbuf + firstpart, writeto); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
std::memcpy(fRingBuf->buf + wrtn, charbuf, size); |
|
|
|
std::memcpy(fBuffer->buf + wrtn, charbuf, size); |
|
|
|
} |
|
|
|
|
|
|
|
fRingBuf->written = static_cast<int32_t>(writeto); |
|
|
|
fBuffer->written = static_cast<int32_t>(writeto); |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
RingBufferStruct* fRingBuf; |
|
|
|
BufferStruct* fBuffer; |
|
|
|
|
|
|
|
CARLA_PREVENT_HEAP_ALLOCATION |
|
|
|
CARLA_DECLARE_NON_COPY_CLASS(RingBufferControl) |
|
|
|
|