@@ -39,9 +39,11 @@ endif | |||||
ifeq ($(DEBUG),true) | ifeq ($(DEBUG),true) | ||||
BASE_FLAGS += -DDEBUG -O0 -g | BASE_FLAGS += -DDEBUG -O0 -g | ||||
CMD_STRIP = \# no-strip | |||||
else | else | ||||
BASE_FLAGS += -DNDEBUG $(BASE_OPTS) -fvisibility=hidden | BASE_FLAGS += -DNDEBUG $(BASE_OPTS) -fvisibility=hidden | ||||
# BASE_FLAGS += -DCARLA_NO_ASSERTS | # BASE_FLAGS += -DCARLA_NO_ASSERTS | ||||
CMD_STRIP = && $(STRIP) | |||||
endif | endif | ||||
32BIT_FLAGS = -m32 | 32BIT_FLAGS = -m32 | ||||
@@ -79,22 +79,22 @@ win64: carla-discovery-win64.exe | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
carla-discovery-native: $(OBJS) $(LIBS) | carla-discovery-native: $(OBJS) $(LIBS) | ||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(NATIVE_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(NATIVE_FLAGS) $(POSIX_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
carla-discovery-native.exe: $(OBJS) $(LIBS) | carla-discovery-native.exe: $(OBJS) $(LIBS) | ||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(NATIVE_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(NATIVE_FLAGS) $(WIN_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
carla-discovery-posix32: $(OBJS) $(LIBS_posix32) | carla-discovery-posix32: $(OBJS) $(LIBS_posix32) | ||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_32BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_32BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
carla-discovery-posix64: $(OBJS) $(LIBS_posix64) | carla-discovery-posix64: $(OBJS) $(LIBS_posix64) | ||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_64BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_64BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
carla-discovery-win32.exe: $(OBJS) $(LIBS_win32) | carla-discovery-win32.exe: $(OBJS) $(LIBS_win32) | ||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
carla-discovery-win64.exe: $(OBJS) $(LIBS_win64) | carla-discovery-win64.exe: $(OBJS) $(LIBS_win64) | ||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
$(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ $(CMD_STRIP) $@ | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
@@ -106,21 +106,11 @@ debug: | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
../libs/lilv.a: | |||||
$(MAKE) -C ../libs lilv | |||||
../libs/lilv.posix32.a: | |||||
$(MAKE) -C ../libs lilv_posix32 | |||||
../libs/lilv.posix64.a: | |||||
$(MAKE) -C ../libs lilv_posix32 | |||||
.FORCE: | |||||
.PHONY: .FORCE | |||||
../libs/lilv.win32.a: | |||||
$(MAKE) -C ../libs lilv_win32 | |||||
../libs/lilv.win64.a: | |||||
$(MAKE) -C ../libs lilv_win64 | |||||
../libs/lilv.a: .FORCE | |||||
$(MAKE) -C ../libs lilv | |||||
.PHONY: ../libs/lilv.a \ | |||||
../libs/lilv.posix32.a ../libs/lilv.posix64.a \ | |||||
../libs/lilv.win32.a ../libs/lilv.win64.a | |||||
../libs/lilv.%.a: .FORCE | |||||
$(MAKE) -C ../libs lilv_$* |
@@ -878,7 +878,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
// Get & check every plugin-instance | // Get & check every plugin-instance | ||||
for (int i=0; i < URIs.count(); ++i) | for (int i=0; i < URIs.count(); ++i) | ||||
{ | { | ||||
const LV2_RDF_Descriptor* const rdfDescriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData()); | |||||
const LV2_RDF_Descriptor* const rdfDescriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData(), false); | |||||
CARLA_ASSERT(rdfDescriptor != nullptr && rdfDescriptor->URI != nullptr); | CARLA_ASSERT(rdfDescriptor != nullptr && rdfDescriptor->URI != nullptr); | ||||
if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr) | if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr) | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* Carla Bridge utils imported from dssi-vst code | * Carla Bridge utils imported from dssi-vst code | ||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2004-2010 Chris Cannam <cannam@all-day-breakfast.com> | * Copyright (C) 2004-2010 Chris Cannam <cannam@all-day-breakfast.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 | ||||
* 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,9 +25,8 @@ | |||||
#define BRIDGE_SHM_RING_BUFFER_SIZE 2048 | #define BRIDGE_SHM_RING_BUFFER_SIZE 2048 | ||||
/*! | |||||
* TODO. | |||||
*/ | |||||
// --------------------------------------------------------------------------------------------- | |||||
enum PluginBridgeInfoType { | enum PluginBridgeInfoType { | ||||
kPluginBridgeAudioCount, | kPluginBridgeAudioCount, | ||||
kPluginBridgeMidiCount, | kPluginBridgeMidiCount, | ||||
@@ -59,20 +58,11 @@ enum PluginBridgeOpcode { | |||||
kPluginBridgeOpcodeSetParameter = 4, // int, float | kPluginBridgeOpcodeSetParameter = 4, // int, float | ||||
kPluginBridgeOpcodeSetProgram = 5, // int | kPluginBridgeOpcodeSetProgram = 5, // int | ||||
kPluginBridgeOpcodeSetMidiProgram = 6, // int | kPluginBridgeOpcodeSetMidiProgram = 6, // int | ||||
kPluginBridgeOpcodeMidiEvent = 7, // long, int, char, ... (long = timeFrame, int = size max 4) | |||||
kPluginBridgeOpcodeMidiEvent = 7, // long, int, char[] (long = timeFrame, int = size max 4) | |||||
kPluginBridgeOpcodeProcess = 8, | kPluginBridgeOpcodeProcess = 8, | ||||
kPluginBridgeOpcodeQuit = 9 | kPluginBridgeOpcodeQuit = 9 | ||||
}; | }; | ||||
/*! | |||||
* @defgroup BridgeMessages Bridge Messages | |||||
* | |||||
* Various bridge related messages, used as configure(<message>, value). | |||||
* \note This is for internal use only. | |||||
* | |||||
* TODO: Review these, may not be needed anymore | |||||
* @{ | |||||
*/ | |||||
const char* const CARLA_BRIDGE_MSG_HIDE_GUI = "CarlaBridgeHideGUI"; //!< Plugin -> Host call, tells host GUI is now hidden | const char* const CARLA_BRIDGE_MSG_HIDE_GUI = "CarlaBridgeHideGUI"; //!< Plugin -> Host call, tells host GUI is now hidden | ||||
const char* const CARLA_BRIDGE_MSG_SAVED = "CarlaBridgeSaved"; //!< Plugin -> Host call, tells host state is saved | const char* const CARLA_BRIDGE_MSG_SAVED = "CarlaBridgeSaved"; //!< Plugin -> Host call, tells host state is saved | ||||
#if 0 | #if 0 | ||||
@@ -81,22 +71,15 @@ const char* const CARLA_BRIDGE_MSG_SET_CHUNK = "CarlaBridgeSetChunk"; //!< Hos | |||||
const char* const CARLA_BRIDGE_MSG_SET_CUSTOM = "CarlaBridgeSetCustom"; //!< Host -> Plugin call, tells plugin to set a custom data set using \a value ("type·key·rvalue"). | const char* const CARLA_BRIDGE_MSG_SET_CUSTOM = "CarlaBridgeSetCustom"; //!< Host -> Plugin call, tells plugin to set a custom data set using \a value ("type·key·rvalue"). | ||||
//If \a type is 'chunk' or 'binary' \a rvalue refers to chunk file. | //If \a type is 'chunk' or 'binary' \a rvalue refers to chunk file. | ||||
#endif | #endif | ||||
/**@}*/ | |||||
/*! | |||||
* TODO. | |||||
*/ | |||||
// --------------------------------------------------------------------------------------------- | |||||
struct BridgeRingBuffer { | struct BridgeRingBuffer { | ||||
int head; | |||||
int tail; | |||||
int written; | |||||
int head, tail, written; | |||||
bool invalidateCommit; | bool invalidateCommit; | ||||
char buf[BRIDGE_SHM_RING_BUFFER_SIZE]; | char buf[BRIDGE_SHM_RING_BUFFER_SIZE]; | ||||
}; | }; | ||||
/*! | |||||
* TODO. | |||||
*/ | |||||
struct BridgeShmControl { | struct BridgeShmControl { | ||||
// 32 and 64-bit binaries align semaphores differently. | // 32 and 64-bit binaries align semaphores differently. | ||||
// Let's make sure there's plenty of room for either one. | // Let's make sure there's plenty of room for either one. | ||||
@@ -111,6 +94,8 @@ struct BridgeShmControl { | |||||
BridgeRingBuffer ringBuffer; | BridgeRingBuffer ringBuffer; | ||||
}; | }; | ||||
// --------------------------------------------------------------------------------------------- | |||||
static inline | static inline | ||||
const char* PluginBridgeInfoType2str(const PluginBridgeInfoType type) | const char* PluginBridgeInfoType2str(const PluginBridgeInfoType type) | ||||
{ | { | ||||
@@ -418,7 +418,7 @@ extern Lv2WorldClass gLv2World; | |||||
// Create new RDF object (using lilv) | // Create new RDF object (using lilv) | ||||
static inline | static inline | ||||
const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri) | |||||
const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool fillPresets = true) | |||||
{ | { | ||||
CARLA_ASSERT(uri != nullptr); | CARLA_ASSERT(uri != nullptr); | ||||
@@ -1020,6 +1020,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri) | |||||
// -------------------------------------------------- | // -------------------------------------------------- | ||||
// Set Plugin Presets | // Set Plugin Presets | ||||
if (fillPresets) | |||||
{ | { | ||||
Lilv::Nodes presetNodes(lilvPlugin.get_related(gLv2World.preset_preset)); | Lilv::Nodes presetNodes(lilvPlugin.get_related(gLv2World.preset_preset)); | ||||
@@ -98,7 +98,7 @@ shm_t carla_shm_create(const char* const name) | |||||
{ | { | ||||
CARLA_ASSERT(name != nullptr); | CARLA_ASSERT(name != nullptr); | ||||
return shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); | |||||
return shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600); | |||||
} | } | ||||
static inline | static inline | ||||
@@ -155,7 +155,7 @@ void* carla_shm_map(shm_t& shm, const size_t size) | |||||
if (ftruncate(shm, size) != 0) | if (ftruncate(shm, size) != 0) | ||||
return nullptr; | return nullptr; | ||||
return mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0); | |||||
return mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -20,7 +20,6 @@ | |||||
#include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
#include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
#include "RtList.hpp" | #include "RtList.hpp" | ||||
#include <QtXml/QDomNode> | #include <QtXml/QDomNode> | ||||
@@ -48,9 +47,15 @@ struct StateParameter { | |||||
~StateParameter() | ~StateParameter() | ||||
{ | { | ||||
if (name != nullptr) | if (name != nullptr) | ||||
{ | |||||
delete[] name; | delete[] name; | ||||
name = nullptr; | |||||
} | |||||
if (symbol != nullptr) | if (symbol != nullptr) | ||||
{ | |||||
delete[] symbol; | delete[] symbol; | ||||
symbol = nullptr; | |||||
} | |||||
} | } | ||||
CARLA_DECLARE_NON_COPY_STRUCT(StateParameter) | CARLA_DECLARE_NON_COPY_STRUCT(StateParameter) | ||||
@@ -69,11 +74,20 @@ struct StateCustomData { | |||||
~StateCustomData() | ~StateCustomData() | ||||
{ | { | ||||
if (type != nullptr) | if (type != nullptr) | ||||
{ | |||||
delete[] type; | delete[] type; | ||||
type = nullptr; | |||||
} | |||||
if (key != nullptr) | if (key != nullptr) | ||||
{ | |||||
delete[] key; | delete[] key; | ||||
key = nullptr; | |||||
} | |||||
if (value != nullptr) | if (value != nullptr) | ||||
{ | |||||
delete[] value; | delete[] value; | ||||
value = nullptr; | |||||
} | |||||
} | } | ||||
CARLA_DECLARE_NON_COPY_STRUCT(StateCustomData) | CARLA_DECLARE_NON_COPY_STRUCT(StateCustomData) | ||||
@@ -140,31 +154,26 @@ struct SaveState { | |||||
delete[] type; | delete[] type; | ||||
type = nullptr; | type = nullptr; | ||||
} | } | ||||
if (name != nullptr) | if (name != nullptr) | ||||
{ | { | ||||
delete[] name; | delete[] name; | ||||
name = nullptr; | name = nullptr; | ||||
} | } | ||||
if (label != nullptr) | if (label != nullptr) | ||||
{ | { | ||||
delete[] label; | delete[] label; | ||||
label = nullptr; | label = nullptr; | ||||
} | } | ||||
if (binary != nullptr) | if (binary != nullptr) | ||||
{ | { | ||||
delete[] binary; | delete[] binary; | ||||
binary = nullptr; | binary = nullptr; | ||||
} | } | ||||
if (currentProgramName != nullptr) | if (currentProgramName != nullptr) | ||||
{ | { | ||||
delete[] currentProgramName; | delete[] currentProgramName; | ||||
currentProgramName = nullptr; | currentProgramName = nullptr; | ||||
} | } | ||||
if (chunk != nullptr) | if (chunk != nullptr) | ||||
{ | { | ||||
delete[] chunk; | delete[] chunk; | ||||
@@ -259,7 +268,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("UniqueID", Qt::CaseInsensitive) == 0) | else if (tag.compare("UniqueID", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
long uniqueID = text.toLong(&ok); | |||||
const long uniqueID(text.toLong(&ok)); | |||||
if (ok) saveState.uniqueID = uniqueID; | if (ok) saveState.uniqueID = uniqueID; | ||||
} | } | ||||
@@ -289,37 +298,37 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("DryWet", Qt::CaseInsensitive) == 0) | else if (tag.compare("DryWet", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = text.toFloat(&ok); | |||||
const float value(text.toFloat(&ok)); | |||||
if (ok) saveState.dryWet = value; | if (ok) saveState.dryWet = value; | ||||
} | } | ||||
else if (tag.compare("Volume", Qt::CaseInsensitive) == 0) | else if (tag.compare("Volume", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = text.toFloat(&ok); | |||||
const float value(text.toFloat(&ok)); | |||||
if (ok) saveState.volume = value; | if (ok) saveState.volume = value; | ||||
} | } | ||||
else if (tag.compare("Balance-Left", Qt::CaseInsensitive) == 0) | else if (tag.compare("Balance-Left", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = text.toFloat(&ok); | |||||
const float value(text.toFloat(&ok)); | |||||
if (ok) saveState.balanceLeft = value; | if (ok) saveState.balanceLeft = value; | ||||
} | } | ||||
else if (tag.compare("Balance-Right", Qt::CaseInsensitive) == 0) | else if (tag.compare("Balance-Right", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = text.toFloat(&ok); | |||||
const float value(text.toFloat(&ok)); | |||||
if (ok) saveState.balanceRight = value; | if (ok) saveState.balanceRight = value; | ||||
} | } | ||||
else if (tag.compare("Panning", Qt::CaseInsensitive) == 0) | else if (tag.compare("Panning", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = text.toFloat(&ok); | |||||
const float value(text.toFloat(&ok)); | |||||
if (ok) saveState.panning = value; | if (ok) saveState.panning = value; | ||||
} | } | ||||
else if (tag.compare("ControlChannel", Qt::CaseInsensitive) == 0) | else if (tag.compare("ControlChannel", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
short value = text.toShort(&ok); | |||||
const short value(text.toShort(&ok)); | |||||
if (ok && value >= 1 && value < INT8_MAX) | if (ok && value >= 1 && value < INT8_MAX) | ||||
saveState.ctrlChannel = static_cast<int8_t>(value-1); | saveState.ctrlChannel = static_cast<int8_t>(value-1); | ||||
} | } | ||||
@@ -330,7 +339,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("CurrentProgramIndex", Qt::CaseInsensitive) == 0) | else if (tag.compare("CurrentProgramIndex", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
int value = text.toInt(&ok); | |||||
const int value(text.toInt(&ok)); | |||||
if (ok && value >= 1) | if (ok && value >= 1) | ||||
saveState.currentProgramIndex = value-1; | saveState.currentProgramIndex = value-1; | ||||
} | } | ||||
@@ -345,14 +354,14 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("CurrentMidiBank", Qt::CaseInsensitive) == 0) | else if (tag.compare("CurrentMidiBank", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
int value = text.toInt(&ok); | |||||
const int value(text.toInt(&ok)); | |||||
if (ok && value >= 1) | if (ok && value >= 1) | ||||
saveState.currentMidiBank = value-1; | saveState.currentMidiBank = value-1; | ||||
} | } | ||||
else if (tag.compare("CurrentMidiProgram", Qt::CaseInsensitive) == 0) | else if (tag.compare("CurrentMidiProgram", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
int value = text.toInt(&ok); | |||||
const int value(text.toInt(&ok)); | |||||
if (ok && value >= 1) | if (ok && value >= 1) | ||||
saveState.currentMidiProgram = value-1; | saveState.currentMidiProgram = value-1; | ||||
} | } | ||||
@@ -374,7 +383,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
if (pTag.compare("Index", Qt::CaseInsensitive) == 0) | if (pTag.compare("Index", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
uint index = pText.toUInt(&ok); | |||||
const uint index(pText.toUInt(&ok)); | |||||
if (ok) stateParameter->index = index; | if (ok) stateParameter->index = index; | ||||
} | } | ||||
else if (pTag.compare("Name", Qt::CaseInsensitive) == 0) | else if (pTag.compare("Name", Qt::CaseInsensitive) == 0) | ||||
@@ -388,20 +397,20 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (pTag.compare("Value", Qt::CaseInsensitive) == 0) | else if (pTag.compare("Value", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
float value = pText.toFloat(&ok); | |||||
const float value(pText.toFloat(&ok)); | |||||
if (ok) stateParameter->value = value; | if (ok) stateParameter->value = value; | ||||
} | } | ||||
else if (pTag.compare("MidiChannel", Qt::CaseInsensitive) == 0) | else if (pTag.compare("MidiChannel", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
ushort channel = pText.toUShort(&ok); | |||||
const ushort channel(pText.toUShort(&ok)); | |||||
if (ok && channel >= 1 && channel < MAX_MIDI_CHANNELS) | if (ok && channel >= 1 && channel < MAX_MIDI_CHANNELS) | ||||
stateParameter->midiChannel = static_cast<uint8_t>(channel-1); | stateParameter->midiChannel = static_cast<uint8_t>(channel-1); | ||||
} | } | ||||
else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
int cc = pText.toInt(&ok); | |||||
const int cc(pText.toInt(&ok)); | |||||
if (ok && cc >= 1 && cc < INT16_MAX) | if (ok && cc >= 1 && cc < INT16_MAX) | ||||
stateParameter->midiCC = static_cast<int16_t>(cc); | stateParameter->midiCC = static_cast<int16_t>(cc); | ||||
} | } | ||||
@@ -566,7 +575,7 @@ const QString& getXMLFromSaveState(const SaveState& saveState) | |||||
{ | { | ||||
// ignore 'default' program | // ignore 'default' program | ||||
#ifdef __USE_GNU | #ifdef __USE_GNU | ||||
if ((saveState.currentProgramIndex > 0 || strcasecmp(saveState.currentProgramName, "Default") != 0)) | |||||
if ((saveState.currentProgramIndex > 0 || strcasecmp(saveState.currentProgramName, "default") != 0)) | |||||
#else | #else | ||||
if ((saveState.currentProgramIndex > 0 || std::strcmp(saveState.currentProgramName, "Default") != 0)) | if ((saveState.currentProgramIndex > 0 || std::strcmp(saveState.currentProgramName, "Default") != 0)) | ||||
#endif | #endif | ||||
@@ -25,12 +25,12 @@ class Lv2AtomQueue | |||||
{ | { | ||||
public: | public: | ||||
Lv2AtomQueue() | Lv2AtomQueue() | ||||
: fIndex(0), | |||||
fIndexPool(0), | |||||
fEmpty(true), | |||||
fFull(false) | |||||
{ | { | ||||
index = indexPool = 0; | |||||
empty = true; | |||||
full = false; | |||||
std::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
std::memset(fDataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
} | } | ||||
void copyDataFrom(Lv2AtomQueue* const queue) | void copyDataFrom(Lv2AtomQueue* const queue) | ||||
@@ -40,79 +40,86 @@ public: | |||||
lock(); | lock(); | ||||
// copy data from queue | // copy data from queue | ||||
std::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE); | |||||
std::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
index = queue->index; | |||||
indexPool = queue->indexPool; | |||||
empty = queue->empty; | |||||
full = queue->full; | |||||
std::memcpy(fData, queue->fData, sizeof(DataType)*MAX_SIZE); | |||||
std::memcpy(fDataPool, queue->fDataPool, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
fIndex = queue->fIndex; | |||||
fIndexPool = queue->fIndexPool; | |||||
fEmpty = queue->fEmpty; | |||||
fFull = queue->fFull; | |||||
// unlock our mutex, no longer needed | // unlock our mutex, no longer needed | ||||
unlock(); | unlock(); | ||||
// reset queque | // reset queque | ||||
std::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE); | |||||
std::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
queue->index = queue->indexPool = 0; | |||||
queue->empty = true; | |||||
queue->full = false; | |||||
std::memset(queue->fData, 0, sizeof(DataType)*MAX_SIZE); | |||||
std::memset(queue->fDataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
queue->fIndex = queue->fIndexPool = 0; | |||||
queue->fEmpty = true; | |||||
queue->fFull = false; | |||||
// unlock queque mutex | // unlock queque mutex | ||||
queue->unlock(); | queue->unlock(); | ||||
} | } | ||||
bool isEmpty() | |||||
bool isEmpty() const | |||||
{ | { | ||||
return empty; | |||||
return fEmpty; | |||||
} | } | ||||
bool isFull() | |||||
bool isFull() const | |||||
{ | { | ||||
return full; | |||||
return fFull; | |||||
} | } | ||||
void lock() | void lock() | ||||
{ | { | ||||
mutex.lock(); | |||||
fMutex.lock(); | |||||
} | } | ||||
bool tryLock() | bool tryLock() | ||||
{ | { | ||||
return mutex.tryLock(); | |||||
return fMutex.tryLock(); | |||||
} | } | ||||
void unlock() | void unlock() | ||||
{ | { | ||||
mutex.unlock(); | |||||
fMutex.unlock(); | |||||
} | } | ||||
void put(const uint32_t portIndex, const LV2_Atom* const atom) | |||||
bool put(const uint32_t portIndex, const LV2_Atom* const atom) | |||||
{ | { | ||||
CARLA_ASSERT(atom != nullptr && atom->size > 0); | CARLA_ASSERT(atom != nullptr && atom->size > 0); | ||||
CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow | |||||
CARLA_ASSERT(fIndexPool + atom->size < MAX_POOL_SIZE); // overflow | |||||
if (fFull || atom == nullptr || fIndexPool + atom->size >= MAX_POOL_SIZE) | |||||
return false; | |||||
if (atom->size == 0) | |||||
return true; | |||||
if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE) | |||||
return; | |||||
bool ret = false; | |||||
lock(); | lock(); | ||||
for (unsigned short i=0; i < MAX_SIZE; ++i) | for (unsigned short i=0; i < MAX_SIZE; ++i) | ||||
{ | { | ||||
if (data[i].size == 0) | |||||
if (fData[i].size == 0) | |||||
{ | { | ||||
data[i].portIndex = portIndex; | |||||
data[i].size = atom->size; | |||||
data[i].type = atom->type; | |||||
data[i].poolOffset = indexPool; | |||||
std::memcpy(dataPool + indexPool, LV2NV_ATOM_BODY_CONST(atom), atom->size); | |||||
empty = false; | |||||
full = (i == MAX_SIZE-1); | |||||
indexPool += atom->size; | |||||
fData[i].portIndex = portIndex; | |||||
fData[i].size = atom->size; | |||||
fData[i].type = atom->type; | |||||
fData[i].poolOffset = fIndexPool; | |||||
std::memcpy(fDataPool + fIndexPool, LV2NV_ATOM_BODY_CONST(atom), atom->size); | |||||
fEmpty = false; | |||||
fFull = (i == MAX_SIZE-1); | |||||
fIndexPool += atom->size; | |||||
ret = true; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
unlock(); | unlock(); | ||||
return ret; | |||||
} | } | ||||
// needs to be locked first! | // needs to be locked first! | ||||
@@ -120,45 +127,45 @@ public: | |||||
{ | { | ||||
CARLA_ASSERT(portIndex != nullptr && atom != nullptr); | CARLA_ASSERT(portIndex != nullptr && atom != nullptr); | ||||
if (empty || portIndex == nullptr || atom == nullptr) | |||||
if (fEmpty || portIndex == nullptr || atom == nullptr) | |||||
return false; | return false; | ||||
full = false; | |||||
fFull = false; | |||||
if (data[index].size == 0) | |||||
if (fData[fIndex].size == 0) | |||||
{ | { | ||||
index = indexPool = 0; | |||||
empty = true; | |||||
fIndex = fIndexPool = 0; | |||||
fEmpty = true; | |||||
unlock(); | unlock(); | ||||
return false; | return false; | ||||
} | } | ||||
retAtom.atom.size = data[index].size; | |||||
retAtom.atom.type = data[index].type; | |||||
std::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size); | |||||
fRetAtom.atom.size = fData[fIndex].size; | |||||
fRetAtom.atom.type = fData[fIndex].type; | |||||
std::memcpy(fRetAtom.data, fDataPool + fData[fIndex].poolOffset, fData[fIndex].size); | |||||
*portIndex = data[index].portIndex; | |||||
*atom = (LV2_Atom*)&retAtom; | |||||
*portIndex = fData[index].portIndex; | |||||
*atom = (LV2_Atom*)&fRetAtom; | |||||
data[index].portIndex = 0; | |||||
data[index].size = 0; | |||||
data[index].type = 0; | |||||
data[index].poolOffset = 0; | |||||
index++; | |||||
empty = false; | |||||
fData[fIndex].portIndex = 0; | |||||
fData[fIndex].size = 0; | |||||
fData[fIndex].type = 0; | |||||
fData[fIndex].poolOffset = 0; | |||||
fEmpty = false; | |||||
++fIndex; | |||||
return true; | return true; | ||||
} | } | ||||
private: | private: | ||||
struct datatype { | |||||
struct DataType { | |||||
size_t size; | size_t size; | ||||
uint32_t type; | uint32_t type; | ||||
uint32_t portIndex; | uint32_t portIndex; | ||||
uint32_t poolOffset; | uint32_t poolOffset; | ||||
datatype() | |||||
DataType() | |||||
: size(0), | : size(0), | ||||
type(0), | type(0), | ||||
portIndex(0), | portIndex(0), | ||||
@@ -168,18 +175,23 @@ private: | |||||
static const unsigned short MAX_SIZE = 128; | static const unsigned short MAX_SIZE = 128; | ||||
static const unsigned short MAX_POOL_SIZE = 8192; | static const unsigned short MAX_POOL_SIZE = 8192; | ||||
datatype data[MAX_SIZE]; | |||||
unsigned char dataPool[MAX_POOL_SIZE]; | |||||
DataType fData[MAX_SIZE]; | |||||
unsigned char fDataPool[MAX_POOL_SIZE]; | |||||
struct { | |||||
struct RetAtom { | |||||
LV2_Atom atom; | LV2_Atom atom; | ||||
unsigned char data[MAX_POOL_SIZE]; | unsigned char data[MAX_POOL_SIZE]; | ||||
} retAtom; | |||||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||||
RetAtom() = delete; | |||||
RetAtom(RetAtom&) = delete; | |||||
RetAtom(const RetAtom&) = delete; | |||||
#endif | |||||
} fRetAtom; | |||||
unsigned short index, indexPool; | |||||
bool empty, full; | |||||
unsigned short fIndex, fIndexPool; | |||||
bool fEmpty, fFull; | |||||
CarlaMutex mutex; | |||||
CarlaMutex fMutex; | |||||
}; | }; | ||||
#endif // __LV2_ATOM_QUEUE_HPP__ | #endif // __LV2_ATOM_QUEUE_HPP__ |