@@ -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); | ||||
@@ -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; | ||||
@@ -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; | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -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) | |||||
}; | }; | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -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; | ||||