Browse Source

Rework ringbuffer class to allow stack vs heap, update lv2 for it

tags/1.9.4
falkTX 11 years ago
parent
commit
f0dcea3da9
5 changed files with 177 additions and 90 deletions
  1. +2
    -2
      source/backend/plugin/BridgePlugin.cpp
  2. +24
    -31
      source/backend/plugin/Lv2Plugin.cpp
  3. +1
    -1
      source/utils/CarlaBridgeUtils.hpp
  4. +46
    -24
      source/utils/CarlaRingBuffer.hpp
  5. +104
    -32
      source/utils/Lv2AtomQueue.hpp

+ 2
- 2
source/backend/plugin/BridgePlugin.cpp View File

@@ -151,13 +151,13 @@ struct BridgeAudioPool {
} }
}; };


struct BridgeControl : public RingBufferControl {
struct BridgeControl : public RingBufferControlTemplate<StackRingBuffer> {
CarlaString filename; CarlaString filename;
BridgeShmControl* data; BridgeShmControl* data;
shm_t shm; shm_t shm;


BridgeControl() BridgeControl()
: RingBufferControl(nullptr),
: RingBufferControlTemplate(nullptr),
data(nullptr) data(nullptr)
{ {
carla_shm_init(shm); carla_shm_init(shm);


+ 24
- 31
source/backend/plugin/Lv2Plugin.cpp View File

@@ -1204,36 +1204,39 @@ public:


void idle() override void idle() override
{ {
#if 0
if (fUi.type == UI::TYPE_NULL)
return CarlaPlugin::idle();

if (! fAtomQueueOut.isEmpty()) if (! fAtomQueueOut.isEmpty())
{ {
char dumpBuf[fAtomQueueOut.getSize()];

Lv2AtomQueue tmpQueue; Lv2AtomQueue tmpQueue;
tmpQueue.copyDataFrom(&fAtomQueueOut);
tmpQueue.copyAndDumpDataFromQueue(fAtomQueueOut, dumpBuf);


uint32_t portIndex; uint32_t portIndex;
const LV2_Atom* atom; const LV2_Atom* atom;
const bool hasPortEvent(fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr); const bool hasPortEvent(fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr);


while (tmpQueue.get(&portIndex, &atom))
for (; tmpQueue.get(&atom, &portIndex);)
{ {
//carla_stdout("OUTPUT message IN GUI REMOVED FROM BUFFER");
carla_stdout("OUTPUT message IN GUI REMOVED FROM BUFFER");


if (fUi.type == PLUGIN_UI_OSC)
if (fUi.type == UI::TYPE_OSC)
{ {
if (pData->osc.data.target != nullptr) if (pData->osc.data.target != nullptr)
{ {
QByteArray chunk((const char*)atom, lv2_atom_total_size(atom));
osc_send_lv2_atom_transfer(&pData->osc.data, portIndex, chunk.toBase64().constData());
QByteArray chunk((const char*)atom, static_cast<int>(lv2_atom_total_size(atom)));
osc_send_lv2_atom_transfer(pData->osc.data, portIndex, chunk.toBase64().constData());
} }
} }
else if (fUi.type != PLUGIN_UI_NULL)
else
{ {
if (hasPortEvent) if (hasPortEvent)
fUi.descriptor->port_event(fUi.handle, portIndex, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); fUi.descriptor->port_event(fUi.handle, portIndex, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
} }
} }
} }
#endif


if (fUi.handle != nullptr && fUi.descriptor != nullptr) if (fUi.handle != nullptr && fUi.descriptor != nullptr)
{ {
@@ -2507,26 +2510,24 @@ public:
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// Message Input // Message Input


#if 0
if (fAtomQueueIn.tryLock()) if (fAtomQueueIn.tryLock())
{ {
if (! fAtomQueueIn.isEmpty()) if (! fAtomQueueIn.isEmpty())
{ {
uint32_t portIndex;
const LV2_Atom* atom; const LV2_Atom* atom;
uint32_t portIndex;


k = fEventsIn.ctrlIndex;
const uint32_t j = fEventsIn.ctrlIndex;


while (fAtomQueueIn.get(&portIndex, &atom))
for (; fAtomQueueIn.get(&atom, &portIndex);)
{ {
carla_debug("Event input message sent to plugin DSP, type %i:\"%s\", size:%i/%i", carla_debug("Event input message sent to plugin DSP, type %i:\"%s\", size:%i/%i",
atom->type, carla_lv2_urid_unmap(this, atom->type), atom->type, carla_lv2_urid_unmap(this, atom->type),
atom->size, lv2_atom_total_size(atom)
);
atom->size, lv2_atom_total_size(atom));


if (! lv2_atom_buffer_write(&evInAtomIters[k], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom)))
if (! lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)))
{ {
carla_stdout("Event input buffer full, 1 message lost");
carla_stdout("Event input buffer full, at least 1 message lost");
break; break;
} }
} }
@@ -2534,7 +2535,6 @@ public:


fAtomQueueIn.unlock(); fAtomQueueIn.unlock();
} }
#endif


// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// MIDI Input (External) // MIDI Input (External)
@@ -2912,7 +2912,6 @@ public:
{ {
if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM) if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM)
{ {
//const uint32_t rindex(fEventsOut.ctrl->rindex);
const LV2_Atom_Event* ev; const LV2_Atom_Event* ev;
LV2_Atom_Buffer_Iterator iter; LV2_Atom_Buffer_Iterator iter;


@@ -2932,12 +2931,11 @@ public:
if (fEventsOut.ctrl->port != nullptr && ev->time.frames >= 0 && ev->body.size <= 0xFF) if (fEventsOut.ctrl->port != nullptr && ev->time.frames >= 0 && ev->body.size <= 0xFF)
fEventsOut.ctrl->port->writeMidiEvent(static_cast<uint32_t>(ev->time.frames), static_cast<uint8_t>(ev->body.size), data); fEventsOut.ctrl->port->writeMidiEvent(static_cast<uint32_t>(ev->time.frames), static_cast<uint8_t>(ev->body.size), data);
} }
#if 0
else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK) else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK)
{ {
fAtomQueueOut.put(rindex, &ev->body);
fAtomQueueOut.put(&ev->body, fEventsOut.ctrl->rindex);
} }
#endif
lv2_atom_buffer_increment(&iter); lv2_atom_buffer_increment(&iter);
} }
} }
@@ -3938,9 +3936,9 @@ public:


case CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM: case CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM:
case CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT: case CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT:
#if 0
fAtomQueueIn.put(rindex, (const LV2_Atom*)buffer);
#endif
CARLA_SAFE_ASSERT_RETURN(((const LV2_Atom*)buffer)->size == bufferSize,);
fAtomQueueIn.put((const LV2_Atom*)buffer, rindex);
break; break;


default: default:
@@ -4633,10 +4631,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
carla_debug("Lv2Plugin::handleTransferAtom(%i, %p)", portIndex, atom); carla_debug("Lv2Plugin::handleTransferAtom(%i, %p)", portIndex, atom);


#if 0
fAtomQueueIn.put(portIndex, atom);
#endif
return; (void)portIndex;
fAtomQueueIn.put(atom, portIndex);
} }


void handleUridMap(const LV2_URID urid, const char* const uri) void handleUridMap(const LV2_URID urid, const char* const uri)
@@ -4662,10 +4657,8 @@ private:
float** fAudioOutBuffers; float** fAudioOutBuffers;
float* fParamBuffers; float* fParamBuffers;


#if 0
Lv2AtomQueue fAtomQueueIn; Lv2AtomQueue fAtomQueueIn;
Lv2AtomQueue fAtomQueueOut; Lv2AtomQueue fAtomQueueOut;
#endif
LV2_Atom_Forge fAtomForge; LV2_Atom_Forge fAtomForge;


Lv2PluginEventData fEventsIn; Lv2PluginEventData fEventsIn;


+ 1
- 1
source/utils/CarlaBridgeUtils.hpp View File

@@ -79,7 +79,7 @@ struct BridgeShmControl {
void* runClient; void* runClient;
char _padClient[32]; char _padClient[32];
}; };
RingBuffer ringBuffer;
StackRingBuffer ringBuffer;
} POST_PACKED_STRUCTURE; } POST_PACKED_STRUCTURE;


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 46
- 24
source/utils/CarlaRingBuffer.hpp View File

@@ -1,6 +1,5 @@
/* /*
* Carla Ring Buffer based on dssi-vst code
* Copyright (C) 2004-2010 Chris Cannam <cannam@all-day-breakfast.com>
* Carla Ring Buffer
* Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@@ -21,26 +20,45 @@


#include "CarlaUtils.hpp" #include "CarlaUtils.hpp"


//#ifndef RING_BUFFER_SIZE
#define RING_BUFFER_SIZE 2048
//#endif

// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// RingBuffer struct
// RingBuffer structs

struct HeapRingBuffer {
uint32_t size;
int32_t head, tail, written;
bool invalidateCommit;
char* buf;

HeapRingBuffer& operator=(const HeapRingBuffer& rb)
{
CARLA_SAFE_ASSERT_RETURN(size == rb.size, *this);

size = rb.size;
head = rb.head;
tail = rb.tail;
written = rb.written;
invalidateCommit = rb.invalidateCommit;
std::memcpy(buf, rb.buf, size);


struct RingBuffer {
return *this;
}
};

struct StackRingBuffer {
static const uint32_t size = 2048;
int32_t head, tail, written; int32_t head, tail, written;
bool invalidateCommit; bool invalidateCommit;
char buf[RING_BUFFER_SIZE];
char buf[size];
}; };


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// RingBufferControl class
// RingBufferControl templated class


class RingBufferControl
template <class RingBufferStruct>
class RingBufferControlTemplate
{ {
public: public:
RingBufferControl(RingBuffer* const ringBuf) noexcept
RingBufferControlTemplate(RingBufferStruct* const ringBuf) noexcept
: fRingBuf(ringBuf) : fRingBuf(ringBuf)
{ {
if (ringBuf != nullptr) if (ringBuf != nullptr)
@@ -55,10 +73,12 @@ public:
fRingBuf->tail = 0; fRingBuf->tail = 0;
fRingBuf->written = 0; fRingBuf->written = 0;
fRingBuf->invalidateCommit = false; fRingBuf->invalidateCommit = false;
carla_zeroChar(fRingBuf->buf, RING_BUFFER_SIZE);

if (fRingBuf->size > 0)
carla_zeroChar(fRingBuf->buf, fRingBuf->size);
} }


void setRingBuffer(RingBuffer* const ringBuf, const bool reset) noexcept
void setRingBuffer(RingBufferStruct* const ringBuf, const bool reset) noexcept
{ {
CARLA_SAFE_ASSERT_RETURN(ringBuf != nullptr,); CARLA_SAFE_ASSERT_RETURN(ringBuf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(ringBuf != fRingBuf,); CARLA_SAFE_ASSERT_RETURN(ringBuf != fRingBuf,);
@@ -155,6 +175,7 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,); CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(buf != nullptr,); CARLA_SAFE_ASSERT_RETURN(buf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size != 0,); CARLA_SAFE_ASSERT_RETURN(size != 0,);
CARLA_SAFE_ASSERT_RETURN(size < fRingBuf->size,);


// this should not happen // this should not happen
CARLA_ASSERT(fRingBuf->head >= 0); CARLA_ASSERT(fRingBuf->head >= 0);
@@ -169,7 +190,7 @@ protected:


const size_t head(static_cast<size_t>(fRingBuf->head)); const size_t head(static_cast<size_t>(fRingBuf->head));
const size_t tail(static_cast<size_t>(fRingBuf->tail)); const size_t tail(static_cast<size_t>(fRingBuf->tail));
const size_t wrap((head < tail) ? RING_BUFFER_SIZE : 0);
const size_t wrap((head < tail) ? fRingBuf->size : 0);


if (head - tail + wrap < size) if (head - tail + wrap < size)
{ {
@@ -179,10 +200,10 @@ protected:


size_t readto = tail + size; size_t readto = tail + size;


if (readto >= RING_BUFFER_SIZE)
if (readto >= fRingBuf->size)
{ {
readto -= RING_BUFFER_SIZE;
const size_t firstpart(RING_BUFFER_SIZE - tail);
readto -= fRingBuf->size;
const size_t firstpart(fRingBuf->size - tail);
std::memcpy(charbuf, fRingBuf->buf + tail, firstpart); std::memcpy(charbuf, fRingBuf->buf + tail, firstpart);
std::memcpy(charbuf + firstpart, fRingBuf->buf, readto); std::memcpy(charbuf + firstpart, fRingBuf->buf, readto);
} }
@@ -199,6 +220,7 @@ protected:
CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,); CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(buf != nullptr,); CARLA_SAFE_ASSERT_RETURN(buf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size != 0,); CARLA_SAFE_ASSERT_RETURN(size != 0,);
CARLA_SAFE_ASSERT_RETURN(size < fRingBuf->size,);


// this should not happen // this should not happen
CARLA_ASSERT(fRingBuf->head >= 0); CARLA_ASSERT(fRingBuf->head >= 0);
@@ -209,7 +231,7 @@ protected:


const size_t tail(static_cast<size_t>(fRingBuf->tail)); const size_t tail(static_cast<size_t>(fRingBuf->tail));
const size_t wrtn(static_cast<size_t>(fRingBuf->written)); const size_t wrtn(static_cast<size_t>(fRingBuf->written));
const size_t wrap((tail <= wrtn) ? RING_BUFFER_SIZE : 0);
const size_t wrap((tail <= wrtn) ? fRingBuf->size : 0);


if (tail - wrtn + wrap <= size) if (tail - wrtn + wrap <= size)
{ {
@@ -220,10 +242,10 @@ protected:


size_t writeto = wrtn + size; size_t writeto = wrtn + size;


if (writeto >= RING_BUFFER_SIZE)
if (writeto >= fRingBuf->size)
{ {
writeto -= RING_BUFFER_SIZE;
const size_t firstpart(RING_BUFFER_SIZE - wrtn);
writeto -= fRingBuf->size;
const size_t firstpart(fRingBuf->size - wrtn);
std::memcpy(fRingBuf->buf + wrtn, charbuf, firstpart); std::memcpy(fRingBuf->buf + wrtn, charbuf, firstpart);
std::memcpy(fRingBuf->buf, charbuf + firstpart, writeto); std::memcpy(fRingBuf->buf, charbuf + firstpart, writeto);
} }
@@ -236,10 +258,10 @@ protected:
} }


private: private:
RingBuffer* fRingBuf;
RingBufferStruct* fRingBuf;


CARLA_PREVENT_HEAP_ALLOCATION CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(RingBufferControl)
CARLA_DECLARE_NON_COPY_CLASS(RingBufferControlTemplate)
}; };


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 104
- 32
source/utils/Lv2AtomQueue.hpp View File

@@ -1,6 +1,6 @@
/* /*
* Simple Queue, specially developed for Atom types * Simple Queue, specially developed for Atom types
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -25,17 +25,47 @@


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class Lv2AtomRingBufferControl : public RingBufferControl
class Lv2AtomRingBufferControl : public RingBufferControlTemplate<HeapRingBuffer>
{ {
public: public:
Lv2AtomRingBufferControl() Lv2AtomRingBufferControl()
: RingBufferControl(&fBuffer)
: RingBufferControlTemplate(nullptr)
{ {
fBuffer.size = 0;
fBuffer.buf = nullptr;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------


const LV2_Atom* readAtom(uint32_t* const portIndex)
void createBuffer(const uint32_t size)
{
if (fBuffer.buf != nullptr)
delete[] fBuffer.buf;

fBuffer.size = size;
fBuffer.buf = new char[size];
setRingBuffer(&fBuffer, true);
}

// used for tmp buffers only
void copyDump(HeapRingBuffer& rb, char dumpBuf[])
{
CARLA_SAFE_ASSERT_RETURN(fBuffer.size == 0,);
CARLA_SAFE_ASSERT_RETURN(fBuffer.buf == nullptr,);

fBuffer.buf = dumpBuf;
fBuffer.size = rb.size;
fBuffer.head = rb.head;
fBuffer.tail = rb.tail;
fBuffer.written = rb.written;
fBuffer.invalidateCommit = rb.invalidateCommit;

std::memcpy(dumpBuf, rb.buf, rb.size);
}

// -------------------------------------------------------------------

const LV2_Atom* readAtom(uint32_t* const portIndex) noexcept
{ {
fRetAtom.atom.size = 0; fRetAtom.atom.size = 0;
fRetAtom.atom.type = 0; fRetAtom.atom.type = 0;
@@ -44,12 +74,12 @@ public:
if (fRetAtom.atom.size == 0 || fRetAtom.atom.type == 0) if (fRetAtom.atom.size == 0 || fRetAtom.atom.type == 0)
return nullptr; return nullptr;


CARLA_SAFE_ASSERT_RETURN(fRetAtom.atom.size < RING_BUFFER_SIZE, nullptr);
CARLA_SAFE_ASSERT_RETURN(fRetAtom.atom.size < kMaxDataSize, nullptr);


int32_t index = -1; int32_t index = -1;
tryRead(&index, sizeof(int32_t)); tryRead(&index, sizeof(int32_t));


if (index == -1)
if (index < 0)
return nullptr; return nullptr;


if (portIndex != nullptr) if (portIndex != nullptr)
@@ -63,7 +93,7 @@ public:


// ------------------------------------------------------------------- // -------------------------------------------------------------------


bool writeAtom(const LV2_Atom* const atom, const int32_t portIndex)
bool writeAtom(const LV2_Atom* const atom, const int32_t portIndex) noexcept
{ {
tryWrite(atom, sizeof(LV2_Atom)); tryWrite(atom, sizeof(LV2_Atom));
tryWrite(&portIndex, sizeof(int32_t)); tryWrite(&portIndex, sizeof(int32_t));
@@ -74,11 +104,13 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
RingBuffer fBuffer;
HeapRingBuffer fBuffer;

static const size_t kMaxDataSize = 2048;


struct RetAtom { struct RetAtom {
LV2_Atom atom; LV2_Atom atom;
char data[RING_BUFFER_SIZE];
char data[kMaxDataSize];
} fRetAtom; } fRetAtom;


friend class Lv2AtomQueue; friend class Lv2AtomQueue;
@@ -96,21 +128,54 @@ public:
{ {
} }


void copyDataFromQueue(Lv2AtomQueue& queue)
// -------------------------------------------------------------------

void createBuffer(const uint32_t size)
{ {
// lock queue
const CarlaMutex::ScopedLocker qsl(queue.fMutex);
fRingBufferCtrl.createBuffer(size);
}


// -------------------------------------------------------------------

uint32_t getSize() const noexcept
{
return fRingBufferCtrl.fBuffer.size;
}

bool isEmpty() const noexcept
{
return !fRingBufferCtrl.isDataAvailable();
}

// must have been locked before
bool get(const LV2_Atom** const atom, uint32_t* const portIndex)
{
CARLA_SAFE_ASSERT_RETURN(atom != nullptr && portIndex != nullptr, false);

if (! fRingBufferCtrl.isDataAvailable())
return false;

if (const LV2_Atom* retAtom = fRingBufferCtrl.readAtom(portIndex))
{ {
// copy data from queue
const CarlaMutex::ScopedLocker sl(fMutex);
carla_copyStruct<RingBuffer>(fRingBufferCtrl.fBuffer, queue.fRingBufferCtrl.fBuffer);
*atom = retAtom;
return true;
} }


// reset queque - FIXME? no queue.?
queue.fRingBufferCtrl.clear();
return false;
} }


// must NOT been locked, we do that here
bool put(const LV2_Atom* const atom, const uint32_t portIndex)
{
CARLA_SAFE_ASSERT_RETURN(atom != nullptr && atom->size > 0, false);

const CarlaMutex::ScopedLocker sl(fMutex);

return fRingBufferCtrl.writeAtom(atom, static_cast<int32_t>(portIndex));
}

// -------------------------------------------------------------------

void lock() const noexcept void lock() const noexcept
{ {
fMutex.lock(); fMutex.lock();
@@ -126,33 +191,40 @@ public:
fMutex.unlock(); fMutex.unlock();
} }


bool put(const LV2_Atom* const atom, const uint32_t portIndex)
// -------------------------------------------------------------------

void copyDataFromQueue(Lv2AtomQueue& queue)
{ {
CARLA_SAFE_ASSERT_RETURN(atom != nullptr && atom->size > 0, false);
// lock source
const CarlaMutex::ScopedLocker qsl(queue.fMutex);


const CarlaMutex::ScopedLocker sl(fMutex);
{
// copy data from source
const CarlaMutex::ScopedLocker sl(fMutex);
fRingBufferCtrl.fBuffer = queue.fRingBufferCtrl.fBuffer;
}


return fRingBufferCtrl.writeAtom(atom, static_cast<int32_t>(portIndex));
// clear source
queue.fRingBufferCtrl.clear();
} }


bool get(const LV2_Atom** const atom, uint32_t* const portIndex)
void copyAndDumpDataFromQueue(Lv2AtomQueue& queue, char dumpBuf[])
{ {
CARLA_SAFE_ASSERT_RETURN(atom != nullptr && portIndex != nullptr, false);

const CarlaMutex::ScopedLocker sl(fMutex);

if (! fRingBufferCtrl.isDataAvailable())
return false;
// lock source
const CarlaMutex::ScopedLocker qsl(queue.fMutex);


if (const LV2_Atom* retAtom = fRingBufferCtrl.readAtom(portIndex))
{ {
*atom = retAtom;
return true;
// copy data from source
const CarlaMutex::ScopedLocker sl(fMutex);
fRingBufferCtrl.copyDump(queue.fRingBufferCtrl.fBuffer, dumpBuf);
} }


return false;
// clear source
queue.fRingBufferCtrl.clear();
} }


// -------------------------------------------------------------------

private: private:
CarlaMutex fMutex; CarlaMutex fMutex;
Lv2AtomRingBufferControl fRingBufferCtrl; Lv2AtomRingBufferControl fRingBufferCtrl;


Loading…
Cancel
Save