@@ -707,6 +707,7 @@ public: | |||
*/ | |||
virtual void clearBuffers() noexcept; | |||
#ifndef BUILD_BRIDGE | |||
// ------------------------------------------------------------------- | |||
// OSC stuff | |||
@@ -738,11 +739,12 @@ public: | |||
* This is a handy function that waits for the GUI to respond and automatically asks it to show itself. | |||
*/ | |||
bool waitForOscGuiShow(); | |||
#endif | |||
#ifndef BUILD_BRIDGE | |||
// ------------------------------------------------------------------- | |||
// MIDI events | |||
#ifndef BUILD_BRIDGE | |||
/*! | |||
* Send a single midi note to be processed in the next audio callback. | |||
* A note with 0 velocity means note-off. | |||
@@ -2163,6 +2163,7 @@ const char* carla_get_host_osc_url_udp() | |||
#include "CarlaPluginUI.cpp" | |||
#include "CarlaDssiUtils.cpp" | |||
#include "CarlaPatchbayUtils.cpp" | |||
#include "CarlaPipeUtils.cpp" | |||
#include "CarlaStateUtils.cpp" | |||
#include "CarlaJuceEvents.cpp" | |||
@@ -512,7 +512,9 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||
if (plugin == nullptr) | |||
return false; | |||
#ifndef BUILD_BRIDGE | |||
plugin->registerToOscClient(); | |||
#endif | |||
EnginePluginData& pluginData(pData->plugins[id]); | |||
pluginData.plugin = plugin; | |||
@@ -2029,6 +2029,7 @@ CARLA_BACKEND_END_NAMESPACE | |||
#include "CarlaHostCommon.cpp" | |||
#include "CarlaPluginUI.cpp" | |||
#include "CarlaDssiUtils.cpp" | |||
#include "CarlaPatchbayUtils.cpp" | |||
#include "CarlaPipeUtils.cpp" | |||
#include "CarlaStateUtils.cpp" | |||
#include "CarlaJuceEvents.cpp" | |||
@@ -401,9 +401,11 @@ int CarlaEngineOsc::handleMsgUpdate(CARLA_ENGINE_OSC_HANDLE_ARGS2, const lo_addr | |||
carla_debug("CarlaEngineOsc::handleMsgUpdate()"); | |||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); | |||
#ifndef BUILD_BRIDGE | |||
const char* const url = (const char*)&argv[0]->s; | |||
plugin->updateOscData(source, url); | |||
#endif | |||
return 0; | |||
} | |||
@@ -44,6 +44,8 @@ static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0 | |||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||
static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | |||
static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr }; | |||
static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr }; | |||
static const PluginPostRtEvent kPluginPostRtEventFallback = { kPluginPostRtEventNull, 0, 0, 0.0f }; | |||
// ------------------------------------------------------------------- | |||
@@ -261,7 +263,7 @@ const MidiProgramData& CarlaPlugin::getMidiProgramData(const uint32_t index) con | |||
const CustomData& CarlaPlugin::getCustomData(const uint32_t index) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(index < pData->custom.count(), kCustomDataNull); | |||
return pData->custom.getAt(index, kCustomDataNull); | |||
return pData->custom.getAt(index, kCustomDataFallback); | |||
} | |||
std::size_t CarlaPlugin::getChunkData(void** const dataPtr) noexcept | |||
@@ -588,7 +590,7 @@ const CarlaStateSave& CarlaPlugin::getStateSave() | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
const CustomData& cData(it.getValue(kCustomDataNull)); | |||
const CustomData& cData(it.getValue(kCustomDataFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.isValid()); | |||
CarlaStateSave::CustomData* stateCustomData(new CarlaStateSave::CustomData()); | |||
@@ -613,7 +615,10 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
for (CarlaStateSave::CustomDataItenerator it = stateSave.customData.begin(); it.valid(); it.next()) | |||
{ | |||
const CarlaStateSave::CustomData* const stateCustomData(it.getValue()); | |||
const CarlaStateSave::CustomData* const stateCustomData(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid()); | |||
const char* const key(stateCustomData->key); | |||
bool wantData = false; | |||
@@ -693,7 +698,8 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
for (CarlaStateSave::ParameterItenerator it = stateSave.parameters.begin(); it.valid(); it.next()) | |||
{ | |||
CarlaStateSave::Parameter* const stateParameter(it.getValue()); | |||
CarlaStateSave::Parameter* const stateParameter(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateParameter != nullptr); | |||
int32_t index = -1; | |||
@@ -704,7 +710,9 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
{ | |||
for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin(); it2.valid(); it2.next()) | |||
{ | |||
ParamSymbol* const paramSymbol(it2.getValue()); | |||
ParamSymbol* const paramSymbol(it2.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(paramSymbol != nullptr); | |||
CARLA_SAFE_ASSERT_CONTINUE(paramSymbol->symbol != nullptr); | |||
if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0) | |||
{ | |||
@@ -725,7 +733,9 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
{ | |||
for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin(); it2.valid(); it2.next()) | |||
{ | |||
ParamSymbol* const paramSymbol(it2.getValue()); | |||
ParamSymbol* const paramSymbol(it2.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(paramSymbol != nullptr); | |||
CARLA_SAFE_ASSERT_CONTINUE(paramSymbol->symbol != nullptr); | |||
if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0) | |||
{ | |||
@@ -772,7 +782,7 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
for (LinkedList<ParamSymbol*>::Itenerator it = paramSymbols.begin(); it.valid(); it.next()) | |||
{ | |||
ParamSymbol* const paramSymbol(it.getValue()); | |||
ParamSymbol* const paramSymbol(it.getValue(nullptr)); | |||
delete paramSymbol; | |||
} | |||
@@ -783,7 +793,10 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
for (CarlaStateSave::CustomDataItenerator it = stateSave.customData.begin(); it.valid(); it.next()) | |||
{ | |||
const CarlaStateSave::CustomData* const stateCustomData(it.getValue()); | |||
const CarlaStateSave::CustomData* const stateCustomData(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid()); | |||
const char* const key(stateCustomData->key); | |||
if (getType() == PLUGIN_DSSI && (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0)) | |||
@@ -1197,7 +1210,7 @@ void CarlaPlugin::setCustomData(const char* const type, const char* const key, c | |||
// Check if we already have this key | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
CustomData& customData(it.getValue()); | |||
CustomData& customData(it.getValue(kCustomDataFallbackNC)); | |||
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid()); | |||
if (std::strcmp(customData.key, key) == 0) | |||
@@ -1422,6 +1435,7 @@ void CarlaPlugin::clearBuffers() noexcept | |||
pData->clearBuffers(); | |||
} | |||
#ifndef BUILD_BRIDGE | |||
// ------------------------------------------------------------------- | |||
// OSC stuff | |||
@@ -1617,7 +1631,7 @@ void CarlaPlugin::updateOscData(const lo_address& source, const char* const url) | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
const CustomData& customData(it.getValue(kCustomDataNull)); | |||
const CustomData& customData(it.getValue(kCustomDataFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid()); | |||
if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_STRING) == 0) | |||
@@ -1682,6 +1696,7 @@ bool CarlaPlugin::waitForOscGuiShow() | |||
carla_stdout("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", oscUiTimeout); | |||
return false; | |||
} | |||
#endif | |||
// ------------------------------------------------------------------- | |||
// MIDI events | |||
@@ -26,7 +26,9 @@ CARLA_BACKEND_START_NAMESPACE | |||
// ------------------------------------------------------------------- | |||
// Fallback data | |||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||
static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr }; | |||
static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr }; | |||
// ----------------------------------------------------------------------- | |||
// PluginAudioData | |||
@@ -405,7 +407,8 @@ void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept | |||
{ | |||
if (mutex.tryLock()) | |||
{ | |||
dataPendingRT.spliceAppendTo(data); | |||
if (dataPendingRT.count() > 0) | |||
dataPendingRT.moveTo(data, true); | |||
mutex.unlock(); | |||
} | |||
} | |||
@@ -525,31 +528,32 @@ CarlaPlugin::ProtectedData::~ProtectedData() noexcept | |||
for (LinkedList<CustomData>::Itenerator it = custom.begin(); it.valid(); it.next()) | |||
{ | |||
CustomData& cData(it.getValue()); | |||
CustomData& customData(it.getValue(kCustomDataFallbackNC)); | |||
//CARLA_SAFE_ASSERT_CONTINUE(customData.isValid()); | |||
if (cData.type != nullptr) | |||
if (customData.type != nullptr) | |||
{ | |||
delete[] cData.type; | |||
cData.type = nullptr; | |||
delete[] customData.type; | |||
customData.type = nullptr; | |||
} | |||
else | |||
carla_safe_assert("cData.type != nullptr", __FILE__, __LINE__); | |||
carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__); | |||
if (cData.key != nullptr) | |||
if (customData.key != nullptr) | |||
{ | |||
delete[] cData.key; | |||
cData.key = nullptr; | |||
delete[] customData.key; | |||
customData.key = nullptr; | |||
} | |||
else | |||
carla_safe_assert("cData.key != nullptr", __FILE__, __LINE__); | |||
carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__); | |||
if (cData.value != nullptr) | |||
if (customData.value != nullptr) | |||
{ | |||
delete[] cData.value; | |||
cData.value = nullptr; | |||
delete[] customData.value; | |||
customData.value = nullptr; | |||
} | |||
else | |||
carla_safe_assert("cData.value != nullptr", __FILE__, __LINE__); | |||
carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__); | |||
} | |||
prog.clear(); | |||
@@ -36,7 +36,9 @@ public: | |||
// might have some leftovers | |||
for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
{ | |||
Lib& lib(it.getValue()); | |||
static Lib libFallback = { nullptr, nullptr, 0, false }; | |||
Lib& lib(it.getValue(libFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr); | |||
@@ -73,7 +75,9 @@ public: | |||
for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
{ | |||
Lib& lib(it.getValue()); | |||
static Lib libFallback = { nullptr, nullptr, 0, false }; | |||
Lib& lib(it.getValue(libFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.filename != nullptr); | |||
@@ -116,7 +120,9 @@ public: | |||
for (LinkedList<Lib>::Itenerator it = fLibs.begin(); it.valid(); it.next()) | |||
{ | |||
Lib& lib(it.getValue()); | |||
static Lib libFallback = { nullptr, nullptr, 0, false }; | |||
Lib& lib(it.getValue(libFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.count > 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(lib.lib != nullptr); | |||
@@ -0,0 +1,85 @@ | |||
/* | |||
* Carla patchbay utils | |||
* Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
* published by the Free Software Foundation; either version 2 of | |||
* the License, or any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "CarlaPatchbayUtils.hpp" | |||
static const GroupNameToId kGroupNameToIdFallback = { 0, { '\0' } }; | |||
static const PortNameToId kPortNameToIdFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
uint PatchbayGroupList::getGroupId(const char* const groupName) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(groupName != nullptr && groupName[0] != '\0', 0); | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const GroupNameToId& groupNameToId(it.getValue(kGroupNameToIdFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (std::strncmp(groupNameToId.name, groupName, STR_MAX) == 0) | |||
return groupNameToId.group; | |||
} | |||
return 0; | |||
} | |||
const char* PatchbayGroupList::getGroupName(const uint groupId) const noexcept | |||
{ | |||
static const char fallback[] = { '\0' }; | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const GroupNameToId& groupNameToId(it.getValue(kGroupNameToIdFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (groupNameToId.group == groupId) | |||
return groupNameToId.name; | |||
} | |||
return fallback; | |||
} | |||
const char* PatchbayPortList::getFullPortName(const uint groupId, const uint portId) const noexcept | |||
{ | |||
static const char fallback[] = { '\0' }; | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& portNameToId(it.getValue(kPortNameToIdFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (portNameToId.group == groupId && portNameToId.port == portId) | |||
return portNameToId.fullName; | |||
} | |||
return fallback; | |||
} | |||
const PortNameToId& PatchbayPortList::getPortNameToId(const char* const fullPortName) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fullPortName != nullptr && fullPortName[0] != '\0', kPortNameToIdFallback); | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& portNameToId(it.getValue(kPortNameToIdFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (std::strncmp(portNameToId.fullName, fullPortName, STR_MAX) == 0) | |||
return portNameToId; | |||
} | |||
return kPortNameToIdFallback; | |||
} |
@@ -75,41 +75,10 @@ struct PatchbayGroupList { | |||
list.clear(); | |||
} | |||
uint getGroupId(const char* const groupName) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(groupName != nullptr && groupName[0] != '\0', 0); | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
static const GroupNameToId groupNameFallback = { 0, { '\0' } }; | |||
const GroupNameToId& groupNameToId(it.getValue(groupNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (std::strncmp(groupNameToId.name, groupName, STR_MAX) == 0) | |||
return groupNameToId.group; | |||
} | |||
return 0; | |||
} | |||
uint getGroupId(const char* const groupName) const noexcept; | |||
const char* getGroupName(const uint groupId) const noexcept | |||
{ | |||
static const char fallback[] = { '\0' }; | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
static const GroupNameToId groupNameFallback = { 0, { '\0' } }; | |||
const GroupNameToId& groupNameToId(it.getValue(groupNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (groupNameToId.group == groupId) | |||
return groupNameToId.name; | |||
} | |||
return fallback; | |||
} | |||
// always returns valid pointer (non-null) | |||
const char* getGroupName(const uint groupId) const noexcept; | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -175,41 +144,10 @@ struct PatchbayPortList { | |||
list.clear(); | |||
} | |||
const char* getFullPortName(const uint groupId, const uint portId) const noexcept | |||
{ | |||
static const char fallback[] = { '\0' }; | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
const PortNameToId& portNameToId(it.getValue(portNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (portNameToId.group == groupId && portNameToId.port == portId) | |||
return portNameToId.fullName; | |||
} | |||
return fallback; | |||
} | |||
// always returns valid pointer (non-null) | |||
const char* getFullPortName(const uint groupId, const uint portId) const noexcept; | |||
const PortNameToId& getPortNameToId(const char* const fullPortName) const noexcept | |||
{ | |||
static const PortNameToId fallback = { 0, 0, { '\0' }, { '\0' } }; | |||
CARLA_SAFE_ASSERT_RETURN(fullPortName != nullptr && fullPortName[0] != '\0', fallback); | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& portNameToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (std::strncmp(portNameToId.fullName, fullPortName, STR_MAX) == 0) | |||
return portNameToId; | |||
} | |||
return fallback; | |||
} | |||
const PortNameToId& getPortNameToId(const char* const fullPortName) const noexcept; | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -129,6 +129,13 @@ public: | |||
data->value = value; | |||
} | |||
// TODO: remove this, fallback should be mandatory | |||
T& getValue() const noexcept | |||
{ | |||
Data* const data(list_entry(fEntry, Data, siblings)); | |||
return data->value; | |||
} | |||
private: | |||
ListHead* fEntry; | |||
ListHead* fEntry2; | |||