Browse Source

Fix RtList code, misc changes

tags/1.9.4
falkTX 12 years ago
parent
commit
db7c065328
5 changed files with 122 additions and 59 deletions
  1. +31
    -26
      source/backend/plugin/carla_plugin.cpp
  2. +16
    -0
      source/backend/plugin/carla_plugin_internal.hpp
  3. +2
    -0
      source/backend/plugin/ladspa.cpp
  4. +16
    -5
      source/carla_shared.py
  5. +57
    -28
      source/utils/rt_list.hpp

+ 31
- 26
source/backend/plugin/carla_plugin.cpp View File

@@ -50,6 +50,7 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id)
case PROCESS_MODE_MULTIPLE_CLIENTS: case PROCESS_MODE_MULTIPLE_CLIENTS:
fData->ctrlInChannel = 0; fData->ctrlInChannel = 0;
break; break;

case PROCESS_MODE_CONTINUOUS_RACK: case PROCESS_MODE_CONTINUOUS_RACK:
CARLA_ASSERT(id < MAX_RACK_PLUGINS && id < MAX_MIDI_CHANNELS); CARLA_ASSERT(id < MAX_RACK_PLUGINS && id < MAX_MIDI_CHANNELS);


@@ -57,6 +58,10 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id)
fData->ctrlInChannel = id; fData->ctrlInChannel = id;


break; break;

case PROCESS_MODE_PATCHBAY:
case PROCESS_MODE_BRIDGE:
break;
} }
} }


@@ -1199,7 +1204,7 @@ void CarlaPlugin::postponeRtEvent(const PluginPostRtEventType type, const int32_


void CarlaPlugin::postRtEventsRun() void CarlaPlugin::postRtEventsRun()
{ {
unsigned short i = 0;
unsigned short k = 0;
PluginPostRtEvent listData[MAX_RT_EVENTS]; PluginPostRtEvent listData[MAX_RT_EVENTS];


// Make a safe copy of events while clearing them // Make a safe copy of events while clearing them
@@ -1209,53 +1214,53 @@ void CarlaPlugin::postRtEventsRun()
{ {
PluginPostRtEvent& event = fData->postRtEvents.data.getFirst(true); PluginPostRtEvent& event = fData->postRtEvents.data.getFirst(true);
//listData[i++] = event; //listData[i++] = event;
std::memcpy(&listData[i++], &event, sizeof(PluginPostRtEvent));
std::memcpy(&listData[k++], &event, sizeof(PluginPostRtEvent));
} }


fData->postRtEvents.mutex.unlock(); fData->postRtEvents.mutex.unlock();


// Handle events now // Handle events now
for (i=0; i < MAX_RT_EVENTS; i++)
for (unsigned short i=0; i < k; i++)
{ {
const PluginPostRtEvent* const event = &listData[i];
const PluginPostRtEvent& event = listData[i];


if (event->type != kPluginPostRtEventNull)
qWarning("postRtEventsRun() - event type %i", i);
if (event.type != kPluginPostRtEventNull)
qWarning("postRtEventsRun() - @ %i", i);


switch (event->type)
switch (event.type)
{ {
case kPluginPostRtEventNull: case kPluginPostRtEventNull:
break; break;


case kPluginPostRtEventDebug: case kPluginPostRtEventDebug:
fData->engine->callback(CALLBACK_DEBUG, fData->id, event->value1, event->value2, event->value3, nullptr);
fData->engine->callback(CALLBACK_DEBUG, fData->id, event.value1, event.value2, event.value3, nullptr);
break; break;


case kPluginPostRtEventParameterChange: case kPluginPostRtEventParameterChange:
// Update UI // Update UI
if (event->value1 >= 0)
uiParameterChange(event->value1, event->value3);
if (event.value1 >= 0)
uiParameterChange(event.value1, event.value3);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client // Update OSC control client
if (fData->engine->isOscControlRegistered()) if (fData->engine->isOscControlRegistered())
fData->engine->osc_send_control_set_parameter_value(fData->id, event->value1, event->value3);
fData->engine->osc_send_control_set_parameter_value(fData->id, event.value1, event.value3);
#endif #endif


// Update Host // Update Host
fData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fData->id, event->value1, 0, event->value3, nullptr);
fData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fData->id, event.value1, 0, event.value3, nullptr);
break; break;


case kPluginPostRtEventProgramChange: case kPluginPostRtEventProgramChange:
// Update UI // Update UI
if (event->value1 >= 0)
uiProgramChange(event->value1);
if (event.value1 >= 0)
uiProgramChange(event.value1);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client // Update OSC control client
if (fData->engine->isOscControlRegistered()) if (fData->engine->isOscControlRegistered())
{ {
fData->engine->osc_send_control_set_program(fData->id, event->value1);
fData->engine->osc_send_control_set_program(fData->id, event.value1);


for (uint32_t j=0; j < fData->param.count; j++) for (uint32_t j=0; j < fData->param.count; j++)
fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def); fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def);
@@ -1263,19 +1268,19 @@ void CarlaPlugin::postRtEventsRun()
#endif #endif


// Update Host // Update Host
fData->engine->callback(CALLBACK_PROGRAM_CHANGED, fData->id, event->value1, 0, 0.0, nullptr);
fData->engine->callback(CALLBACK_PROGRAM_CHANGED, fData->id, event.value1, 0, 0.0, nullptr);
break; break;


case kPluginPostRtEventMidiProgramChange: case kPluginPostRtEventMidiProgramChange:
// Update UI // Update UI
if (event->value1 >= 0)
uiMidiProgramChange(event->value1);
if (event.value1 >= 0)
uiMidiProgramChange(event.value1);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client // Update OSC control client
if (fData->engine->isOscControlRegistered()) if (fData->engine->isOscControlRegistered())
{ {
fData->engine->osc_send_control_set_midi_program(fData->id, event->value1);
fData->engine->osc_send_control_set_midi_program(fData->id, event.value1);


for (uint32_t j=0; j < fData->param.count; j++) for (uint32_t j=0; j < fData->param.count; j++)
fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def); fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def);
@@ -1283,35 +1288,35 @@ void CarlaPlugin::postRtEventsRun()
#endif #endif


// Update Host // Update Host
fData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fData->id, event->value1, 0, 0.0, nullptr);
fData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fData->id, event.value1, 0, 0.0, nullptr);
break; break;


case kPluginPostRtEventNoteOn: case kPluginPostRtEventNoteOn:
// Update UI // Update UI
uiNoteOn(event->value1, event->value2, int(event->value3));
uiNoteOn(event.value1, event.value2, int(event.value3));


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client // Update OSC control client
if (fData->engine->isOscControlRegistered()) if (fData->engine->isOscControlRegistered())
fData->engine->osc_send_control_note_on(fData->id, event->value1, event->value2, int(event->value3));
fData->engine->osc_send_control_note_on(fData->id, event.value1, event.value2, int(event.value3));
#endif #endif


// Update Host // Update Host
fData->engine->callback(CALLBACK_NOTE_ON, fData->id, event->value1, event->value2, int(event->value3), nullptr);
fData->engine->callback(CALLBACK_NOTE_ON, fData->id, event.value1, event.value2, int(event.value3), nullptr);
break; break;


case kPluginPostRtEventNoteOff: case kPluginPostRtEventNoteOff:
// Update UI // Update UI
uiNoteOff(event->value1, event->value2);
uiNoteOff(event.value1, event.value2);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client // Update OSC control client
if (fData->engine->isOscControlRegistered()) if (fData->engine->isOscControlRegistered())
fData->engine->osc_send_control_note_off(fData->id, event->value1, event->value2);
fData->engine->osc_send_control_note_off(fData->id, event.value1, event.value2);
#endif #endif


// Update Host // Update Host
fData->engine->callback(CALLBACK_NOTE_OFF, fData->id, event->value1, event->value2, 0.0, nullptr);
fData->engine->callback(CALLBACK_NOTE_OFF, fData->id, event.value1, event.value2, 0.0, nullptr);
break; break;
} }
} }


+ 16
- 0
source/backend/plugin/carla_plugin_internal.hpp View File

@@ -434,10 +434,18 @@ struct CarlaPluginProtectedData {
: data(MIN_RT_EVENTS, MAX_RT_EVENTS), : data(MIN_RT_EVENTS, MAX_RT_EVENTS),
dataPendingRT(MIN_RT_EVENTS, MAX_RT_EVENTS) {} dataPendingRT(MIN_RT_EVENTS, MAX_RT_EVENTS) {}


~PostRtEvents()
{
clear();
}

void appendRT(const PluginPostRtEvent& event) void appendRT(const PluginPostRtEvent& event)
{ {
dataPendingRT.append(event); dataPendingRT.append(event);
}


void trySplice()
{
if (mutex.tryLock()) if (mutex.tryLock())
{ {
dataPendingRT.splice(data, true); dataPendingRT.splice(data, true);
@@ -445,6 +453,14 @@ struct CarlaPluginProtectedData {
} }
} }


void clear()
{
mutex.lock();
data.clear();
dataPendingRT.clear();
mutex.unlock();
}

//void appendNonRT(const PluginPostRtEvent& event) //void appendNonRT(const PluginPostRtEvent& event)
//{ //{
// data.append_sleepy(event); // data.append_sleepy(event);


+ 2
- 0
source/backend/plugin/ladspa.cpp View File

@@ -921,6 +921,8 @@ public:
} }
} }


fData->postRtEvents.trySplice();

} // End of Parameters Input } // End of Parameters Input


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


+ 16
- 5
source/carla_shared.py View File

@@ -1820,15 +1820,26 @@ class PluginEdit(QDialog):
# Check parameters needing update # Check parameters needing update
for index, value in self.fParametersToUpdate: for index, value in self.fParametersToUpdate:
if index == PARAMETER_DRYWET: if index == PARAMETER_DRYWET:
self.ui.dial_drywet.setValue(value * 1000, True, False)
self.ui.dial_drywet.blockSignals(True)
self.ui.dial_drywet.setValue(value * 1000)
self.ui.dial_drywet.blockSignals(False)
elif index == PARAMETER_VOLUME: elif index == PARAMETER_VOLUME:
self.ui.dial_vol.setValue(value * 1000, True, False)
self.ui.dial_vol.blockSignals(True)
self.ui.dial_vol.setValue(value * 1000)
self.ui.dial_vol.blockSignals(False)
elif index == PARAMETER_BALANCE_LEFT: elif index == PARAMETER_BALANCE_LEFT:
self.ui.dial_b_left.setValue(value * 1000, True, False)
self.ui.dial_b_left.blockSignals(True)
self.ui.dial_b_left.setValue(value * 1000)
self.ui.dial_b_left.blockSignals(False)
elif index == PARAMETER_BALANCE_RIGHT: elif index == PARAMETER_BALANCE_RIGHT:
self.ui.dial_b_right.setValue(value * 1000, True, False)
self.ui.dial_b_right.blockSignals(True)
self.ui.dial_b_right.setValue(value * 1000)
self.ui.dial_b_right.blockSignals(False)
elif index == PARAMETER_PANNING: elif index == PARAMETER_PANNING:
pass #self.ui.dial_pan.setValue(value * 1000, True, False)
pass
#self.ui.dial_pan.blockSignals(True)
#self.ui.dial_pan.setValue(value * 1000, True, False)
#self.ui.dial_pan.blockSignals(False)
elif index >= 0: elif index >= 0:
for paramType, paramId, paramWidget in self.fParameterList: for paramType, paramId, paramWidget in self.fParameterList:
if paramId == index: if paramId == index:


+ 57
- 28
source/utils/rt_list.hpp View File

@@ -1,5 +1,5 @@
/* /*
* High-level, real-time safe, templated C++ doubly linked list
* High-level, real-time safe, templated C++ doubly-linked list
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> * Copyright (C) 2013 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
@@ -23,8 +23,7 @@ extern "C" {
#include "rtmempool/rtmempool.h" #include "rtmempool/rtmempool.h"
} }


#include <cassert>
#include <cstring>
#include "carla_utils.hpp"


// list_entry C++11 version (using nullptr instead of 0) // list_entry C++11 version (using nullptr instead of 0)
#undef list_entry #undef list_entry
@@ -47,7 +46,8 @@ class List
{ {
protected: protected:
List() List()
: fDataSize(sizeof(Data))
: kDataSize(sizeof(Data)),
fCount(0)
{ {
_init(); _init();
} }
@@ -55,20 +55,19 @@ protected:
public: public:
virtual ~List() virtual ~List()
{ {
clear();
CARLA_ASSERT(fCount == 0);
} }


void clear() void clear()
{ {
if (fCount != 0) if (fCount != 0)
{ {
Data* data;
k_list_head* entry; k_list_head* entry;


list_for_each(entry, &fQueue) list_for_each(entry, &fQueue)
{ {
data = list_entry(entry, Data, siblings);
_deallocate(data);
if (Data* data = list_entry(entry, Data, siblings))
_deallocate(data);
} }
} }


@@ -98,14 +97,27 @@ public:
return false; return false;
} }


bool insert(const T& value)
{
if (Data* const data = _allocate())
{
std::memcpy(&data->value, &value, sizeof(T));
list_add(&data->siblings, &fQueue);
fCount++;
return true;
}

return false;
}

T& getAt(const size_t index, const bool remove = false) T& getAt(const size_t index, const bool remove = false)
{ {
if (fCount == 0 || index >= fCount) if (fCount == 0 || index >= fCount)
return _retEmpty(); return _retEmpty();


size_t i = 0;
Data* data = nullptr; Data* data = nullptr;
k_list_head* entry; k_list_head* entry;
size_t i = 0;


list_for_each(entry, &fQueue) list_for_each(entry, &fQueue)
{ {
@@ -113,20 +125,22 @@ public:
continue; continue;


data = list_entry(entry, Data, siblings); data = list_entry(entry, Data, siblings);
assert(data);


if (remove) if (remove)
{ {
fCount--; fCount--;
list_del(entry); list_del(entry);
_deallocate(data);

if (data != nullptr)
_deallocate(data);
} }


break; break;
} }


assert(data);
return data->value;
CARLA_ASSERT(data != nullptr);

return (data != nullptr) ? data->value : _retEmpty();
} }


T& getFirst(const bool remove = false) T& getFirst(const bool remove = false)
@@ -147,9 +161,10 @@ public:
list_for_each(entry, &fQueue) list_for_each(entry, &fQueue)
{ {
data = list_entry(entry, Data, siblings); data = list_entry(entry, Data, siblings);
assert(data);


if (data->value == value)
CARLA_ASSERT(data != nullptr);

if (data != nullptr && data->value == value)
{ {
fCount--; fCount--;
list_del(entry); list_del(entry);
@@ -170,9 +185,10 @@ public:
list_for_each_safe(entry, tmp, &fQueue) list_for_each_safe(entry, tmp, &fQueue)
{ {
data = list_entry(entry, Data, siblings); data = list_entry(entry, Data, siblings);
assert(data);


if (data->value == value)
CARLA_ASSERT(data != nullptr);

if (data != nullptr && data->value == value)
{ {
fCount--; fCount--;
list_del(entry); list_del(entry);
@@ -184,13 +200,20 @@ public:
void splice(List& list, const bool init = false) void splice(List& list, const bool init = false)
{ {
if (init) if (init)
{
list_splice_init(&fQueue, &list.fQueue); list_splice_init(&fQueue, &list.fQueue);
list.fCount += fCount;
fCount = 0;
}
else else
{
list_splice(&fQueue, &list.fQueue); list_splice(&fQueue, &list.fQueue);
list.fCount += fCount;
}
} }


protected: protected:
const size_t fDataSize;
const size_t kDataSize;
size_t fCount; size_t fCount;
k_list_head fQueue; k_list_head fQueue;


@@ -214,15 +237,17 @@ private:
if (fCount == 0) if (fCount == 0)
return _retEmpty(); return _retEmpty();


k_list_head* const entry = first ? fQueue.next : fQueue.prev;
k_list_head* const entry = first ? fQueue.prev : fQueue.next;
Data* const data = list_entry(entry, Data, siblings); Data* const data = list_entry(entry, Data, siblings);


CARLA_ASSERT(data != nullptr);

if (data == nullptr) if (data == nullptr)
return _retEmpty(); return _retEmpty();


T& ret = data->value; T& ret = data->value;


if (data && remove)
if (data != nullptr && remove)
{ {
fCount--; fCount--;
list_del(entry); list_del(entry);
@@ -247,7 +272,7 @@ private:
return value; return value;
} }


//LIST_DECLARATIONS(List)
LIST_DECLARATIONS(List)
}; };


template<typename T> template<typename T>
@@ -255,9 +280,10 @@ class RtList : public List<T>
{ {
public: public:
RtList(const size_t minPreallocated, const size_t maxPreallocated) RtList(const size_t minPreallocated, const size_t maxPreallocated)
: fMemPool(nullptr)
{ {
rtsafe_memory_pool_create(&fMemPool, nullptr, this->fDataSize, minPreallocated, maxPreallocated);
assert(fMemPool);
rtsafe_memory_pool_create(&fMemPool, nullptr, this->kDataSize, minPreallocated, maxPreallocated);
CARLA_ASSERT(fMemPool != nullptr);
} }


~RtList() ~RtList()
@@ -280,9 +306,12 @@ public:
{ {
this->clear(); this->clear();


rtsafe_memory_pool_destroy(fMemPool);
if (fMemPool != nullptr)
rtsafe_memory_pool_destroy(fMemPool);

fMemPool = nullptr;
rtsafe_memory_pool_create(&fMemPool, nullptr, this->fDataSize, minPreallocated, maxPreallocated); rtsafe_memory_pool_create(&fMemPool, nullptr, this->fDataSize, minPreallocated, maxPreallocated);
assert(fMemPool);
CARLA_ASSERT(fMemPool != nullptr);
} }


private: private:
@@ -303,7 +332,7 @@ private:
return (typename List<T>::Data*)rtsafe_memory_pool_allocate_sleepy(fMemPool); return (typename List<T>::Data*)rtsafe_memory_pool_allocate_sleepy(fMemPool);
} }


void _deallocate(typename List<T>::Data* const dataPtr)
void _deallocate(typename List<T>::Data* const dataPtr)
{ {
rtsafe_memory_pool_deallocate(fMemPool, dataPtr); rtsafe_memory_pool_deallocate(fMemPool, dataPtr);
} }
@@ -329,7 +358,7 @@ private:
return (typename List<T>::Data*)malloc(this->fDataSize); return (typename List<T>::Data*)malloc(this->fDataSize);
} }


void _deallocate(typename List<T>::Data* const dataPtr)
void _deallocate(typename List<T>::Data* const dataPtr)
{ {
free(dataPtr); free(dataPtr);
} }
@@ -355,7 +384,7 @@ private:
return new typename List<T>::Data; return new typename List<T>::Data;
} }


void _deallocate(typename List<T>::Data* const dataPtr)
void _deallocate(typename List<T>::Data* const dataPtr)
{ {
delete dataPtr; delete dataPtr;
} }


Loading…
Cancel
Save