Browse Source

More work for Juce migration, random stuff

tags/1.9.4
falkTX 11 years ago
parent
commit
0321ff8571
43 changed files with 743 additions and 700 deletions
  1. +17
    -18
      source/backend/CarlaBackend.hpp
  2. +2
    -1
      source/backend/CarlaEngine.hpp
  3. +45
    -36
      source/backend/engine/CarlaEngine.cpp
  4. +41
    -24
      source/backend/engine/CarlaEngineJack.cpp
  5. +2
    -2
      source/backend/engine/CarlaEngineJuce.cpp
  6. +4
    -6
      source/backend/engine/CarlaEngineNative.cpp
  7. +5
    -5
      source/backend/engine/CarlaEngineThread.cpp
  8. +5
    -18
      source/backend/engine/Makefile
  9. +0
    -5
      source/backend/plugin/BridgePlugin.cpp
  10. +20
    -10
      source/backend/plugin/CarlaPlugin.cpp
  11. +3
    -1
      source/backend/plugin/CarlaPluginGui.cpp
  12. +2
    -0
      source/backend/plugin/CarlaPluginGui.hpp
  13. +2
    -2
      source/backend/plugin/CarlaPluginInternal.hpp
  14. +13
    -8
      source/backend/plugin/DssiPlugin.cpp
  15. +29
    -31
      source/backend/plugin/FluidSynthPlugin.cpp
  16. +4
    -4
      source/backend/plugin/LadspaPlugin.cpp
  17. +9
    -11
      source/backend/plugin/LinuxSamplerPlugin.cpp
  18. +58
    -54
      source/backend/plugin/Lv2Plugin.cpp
  19. +5
    -5
      source/backend/plugin/Makefile
  20. +28
    -27
      source/backend/plugin/NativePlugin.cpp
  21. +37
    -35
      source/backend/plugin/VstPlugin.cpp
  22. +25
    -77
      source/backend/standalone/CarlaStandalone.cpp
  23. +1
    -2
      source/backend/standalone/Makefile
  24. +7
    -6
      source/modules/CarlaNative.h
  25. +1
    -1
      source/modules/carla_native/audio-file.cpp
  26. +1
    -4
      source/modules/carla_native/bypass.c
  27. +2
    -2
      source/modules/carla_native/distrho-nekobi.cpp
  28. +1
    -1
      source/modules/carla_native/lfo.c
  29. +1
    -1
      source/modules/carla_native/midi-file.cpp
  30. +1
    -1
      source/modules/carla_native/midi-gain.c
  31. +24
    -19
      source/modules/carla_native/vex.cpp
  32. +3
    -0
      source/modules/carla_native/vex/cVoice.cpp
  33. +9
    -2
      source/modules/carla_native/vex/cWaveRenderer.h
  34. +9
    -9
      source/modules/carla_native/zynaddsubfx.cpp
  35. +15
    -15
      source/plugin/Makefile
  36. +5
    -0
      source/plugin/carla-native-base.cpp
  37. +64
    -56
      source/plugin/carla-native-lv2-export.cpp
  38. +153
    -123
      source/plugin/carla-native-lv2.cpp
  39. +6
    -4
      source/utils/CarlaBackendUtils.hpp
  40. +8
    -0
      source/utils/CarlaJuceUtils.hpp
  41. +65
    -68
      source/utils/CarlaStateUtils.hpp
  42. +5
    -0
      source/utils/CarlaString.hpp
  43. +6
    -6
      source/utils/RtList.hpp

+ 17
- 18
source/backend/CarlaBackend.hpp View File

@@ -54,15 +54,15 @@ const unsigned int MAX_DEFAULT_PARAMETERS = 200; //!< Maximum default number of
* \see CarlaPlugin::hints()
* @{
*/
const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge. This hint is required because "bridge" itself is not a plugin type.
const unsigned int PLUGIN_IS_RTSAFE = 0x002; //!< Plugin is hard real-time safe.
const unsigned int PLUGIN_IS_SYNTH = 0x004; //!< Plugin is a synthesizer (produces sound).
const unsigned int PLUGIN_HAS_GUI = 0x010; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_HAS_SINGLE_THREAD = 0x020; //!< Plugin has a single thread for all UI events (not thread-safe).
const unsigned int PLUGIN_CAN_DRYWET = 0x100; //!< Plugin can use internal Dry/Wet control.
const unsigned int PLUGIN_CAN_VOLUME = 0x200; //!< Plugin can use internal Volume control.
const unsigned int PLUGIN_CAN_BALANCE = 0x400; //!< Plugin can use internal Left & Right Balance controls.
const unsigned int PLUGIN_CAN_PANNING = 0x800; //!< Plugin can use internal Panning control.
const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge. This hint is required because "bridge" itself is not a plugin type.
const unsigned int PLUGIN_IS_RTSAFE = 0x002; //!< Plugin is hard real-time safe.
const unsigned int PLUGIN_HAS_GUI = 0x004; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_CAN_DRYWET = 0x010; //!< Plugin can use internal Dry/Wet control.
const unsigned int PLUGIN_CAN_VOLUME = 0x020; //!< Plugin can use internal Volume control.
const unsigned int PLUGIN_CAN_BALANCE = 0x040; //!< Plugin can use internal Left & Right Balance controls.
const unsigned int PLUGIN_CAN_PANNING = 0x080; //!< Plugin can use internal Panning control.
const unsigned int PLUGIN_NEEDS_SINGLE_THREAD = 0x100; //!< Plugin needs a single thread for all UI events.
const unsigned int PLUGIN_NEEDS_FIXED_BUFFERS = 0x200; //!< Plugin needs constant/fixed-size audio buffers.
/**@}*/

/*!
@@ -72,7 +72,7 @@ const unsigned int PLUGIN_CAN_PANNING = 0x800; //!< Plugin can use interna
* \see CarlaPlugin::availableOptions() and CarlaPlugin::options()
* @{
*/
const unsigned int PLUGIN_OPTION_FIXED_BUFFER = 0x001; //!< Use a constant/fixed-size audio buffer.
const unsigned int PLUGIN_OPTION_FIXED_BUFFERS = 0x001; //!< Use constant/fixed-size audio buffers.
const unsigned int PLUGIN_OPTION_FORCE_STEREO = 0x002; //!< Force mono plugin as stereo.
const unsigned int PLUGIN_OPTION_MAP_PROGRAM_CHANGES = 0x004; //!< Map MIDI-Programs to plugin programs.
const unsigned int PLUGIN_OPTION_USE_CHUNKS = 0x008; //!< Use chunks to save&restore data.
@@ -90,13 +90,13 @@ const unsigned int PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100; //!< Send MIDI a
* \see CarlaPlugin::parameterData()
* @{
*/
const unsigned int PARAMETER_IS_BOOLEAN = 0x001; //!< Parameter value is a boolean (always at minimum or maximum values).
const unsigned int PARAMETER_IS_INTEGER = 0x002; //!< Parameter value is an integer.
const unsigned int PARAMETER_IS_BOOLEAN = 0x001; //!< Parameter values are boolean (always at minimum or maximum values).
const unsigned int PARAMETER_IS_INTEGER = 0x002; //!< Parameter values are integer.
const unsigned int PARAMETER_IS_LOGARITHMIC = 0x004; //!< Parameter values are logarithmic.
const unsigned int PARAMETER_IS_ENABLED = 0x008; //!< Parameter is enabled (can be changed).
const unsigned int PARAMETER_IS_ENABLED = 0x008; //!< Parameter is enabled (can be viewed and changed).
const unsigned int PARAMETER_IS_AUTOMABLE = 0x010; //!< Parameter is automable (realtime safe).
const unsigned int PARAMETER_IS_READ_ONLY = 0x020; //!< Parameter is read-only.
const unsigned int PARAMETER_USES_SAMPLERATE = 0x040; //!< Parameter needs Sample-Rate to work (value and ranges are multiplied by SR, and must be divided by SR on save).
const unsigned int PARAMETER_USES_SAMPLERATE = 0x040; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR on usage, divided by SR on save).
const unsigned int PARAMETER_USES_SCALEPOINTS = 0x080; //!< Parameter uses scalepoints to define internal values in a meaningful way.
const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x100; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText()
/**@}*/
@@ -225,7 +225,6 @@ enum OptionsType {
/*!
* Set the current process name.\n
* This is a convenience option, as Python lacks this functionality.
* \note Not available on all platforms.
*/
OPTION_PROCESS_NAME = 0,

@@ -257,7 +256,7 @@ enum OptionsType {
OPTION_PREFER_PLUGIN_BRIDGES = 4,

/*!
* Use OSC-UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n
* Use UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n
* Default is yes.
*/
OPTION_PREFER_UI_BRIDGES = 5,
@@ -403,10 +402,10 @@ enum OptionsType {

#ifdef WANT_VST
/*!
* Set path to the VST Cocoa UI bridge executable.\n
* Set path to the VST Mac UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_VST_COCOA = 28,
OPTION_PATH_BRIDGE_VST_MAC = 28,

/*!
* Set path to the VST HWND UI bridge executable.\n


+ 2
- 1
source/backend/CarlaEngine.hpp View File

@@ -257,6 +257,7 @@ struct EngineOptions {
CarlaString bridge_win64;
#endif
#ifdef WANT_LV2
CarlaString bridge_lv2Extrn;
CarlaString bridge_lv2Gtk2;
CarlaString bridge_lv2Gtk3;
CarlaString bridge_lv2Qt4;
@@ -266,7 +267,7 @@ struct EngineOptions {
CarlaString bridge_lv2X11;
#endif
#ifdef WANT_VST
CarlaString bridge_vstCocoa;
CarlaString bridge_vstMac;
CarlaString bridge_vstHWND;
CarlaString bridge_vstX11;
#endif


+ 45
- 36
source/backend/engine/CarlaEngine.cpp View File

@@ -22,11 +22,6 @@

#include <cmath>

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>

CARLA_BACKEND_START_NAMESPACE

#if 0
@@ -359,34 +354,35 @@ CarlaEngine::~CarlaEngine()
// returned value must be deleted
const char* findDSSIGUI(const char* const filename, const char* const label)
{
QString guiFilename;
QString pluginDir(filename);
pluginDir.resize(pluginDir.lastIndexOf("."));

QString shortName(QFileInfo(pluginDir).baseName());

QString checkLabel(label);
QString checkSName(shortName);

if (! checkLabel.endsWith("_")) checkLabel += "_";
if (! checkSName.endsWith("_")) checkSName += "_";

QStringList guiFiles(QDir(pluginDir).entryList());

foreach (const QString& gui, guiFiles)
{
if (gui.startsWith(checkLabel) || gui.startsWith(checkSName))
{
QFileInfo finalname(pluginDir + QDir::separator() + gui);
guiFilename = finalname.absoluteFilePath();
break;
}
}

if (guiFilename.isEmpty())
return nullptr;

return carla_strdup(guiFilename.toUtf8().constData());
// QString guiFilename;
// QString pluginDir(filename);
// pluginDir.resize(pluginDir.lastIndexOf("."));
//
// QString shortName(QFileInfo(pluginDir).baseName());
//
// QString checkLabel(label);
// QString checkSName(shortName);
//
// if (! checkLabel.endsWith("_")) checkLabel += "_";
// if (! checkSName.endsWith("_")) checkSName += "_";
//
// QStringList guiFiles(QDir(pluginDir).entryList());
//
// foreach (const QString& gui, guiFiles)
// {
// if (gui.startsWith(checkLabel) || gui.startsWith(checkSName))
// {
// QFileInfo finalname(pluginDir + QDir::separator() + gui);
// guiFilename = finalname.absoluteFilePath();
// break;
// }
// }
//
// if (guiFilename.isEmpty())
// return nullptr;
//
// return carla_strdup(guiFilename.toUtf8().constData());
return nullptr;
}

// -----------------------------------------------------------------------
@@ -742,7 +738,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons
break;

case PLUGIN_CSOUND:
plugin = CarlaPlugin::newCSOUND(init);
//plugin = CarlaPlugin::newCSOUND(init);
break;

case PLUGIN_GIG:
@@ -1089,6 +1085,7 @@ bool CarlaEngine::loadFilename(const char* const filename)
CARLA_ASSERT(filename != nullptr);
carla_debug("CarlaEngine::loadFilename(\"%s\")", filename);

#if 0
QFileInfo fileInfo(filename);

if (! fileInfo.exists())
@@ -1206,6 +1203,7 @@ bool CarlaEngine::loadFilename(const char* const filename)
}

// -------------------------------------------------------------------
#endif

setLastError("Unknown file extension");
return false;
@@ -1230,6 +1228,7 @@ bool CarlaEngine::loadProject(const char* const filename)
CARLA_ASSERT(filename != nullptr);
carla_debug("CarlaEngine::loadProject(\"%s\")", filename);

#if 0
QFile file(filename);

if (! file.open(QIODevice::ReadOnly | QIODevice::Text))
@@ -1292,6 +1291,9 @@ bool CarlaEngine::loadProject(const char* const filename)
}

return true;
#endif
setLastError("Not implemented yet");
return false;
}

bool CarlaEngine::saveProject(const char* const filename)
@@ -1299,6 +1301,7 @@ bool CarlaEngine::saveProject(const char* const filename)
CARLA_ASSERT(filename != nullptr);
carla_debug("CarlaEngine::saveProject(\"%s\")", filename);

#if 0
QFile file(filename);

if (! file.open(QIODevice::WriteOnly | QIODevice::Text))
@@ -1341,6 +1344,9 @@ bool CarlaEngine::saveProject(const char* const filename)

file.close();
return true;
#endif
setLastError("Not implemented yet");
return false;
}

// -----------------------------------------------------------------------
@@ -1562,6 +1568,9 @@ void CarlaEngine::setOption(const OptionsType option, const int value, const cha
#endif

#ifdef WANT_LV2
case OPTION_PATH_BRIDGE_LV2_EXTERNAL:
fOptions.bridge_lv2Extrn = valueStr;
break;
case OPTION_PATH_BRIDGE_LV2_GTK2:
fOptions.bridge_lv2Gtk2 = valueStr;
break;
@@ -1586,8 +1595,8 @@ void CarlaEngine::setOption(const OptionsType option, const int value, const cha
#endif

#ifdef WANT_VST
case OPTION_PATH_BRIDGE_VST_COCOA:
fOptions.bridge_vstCocoa = valueStr;
case OPTION_PATH_BRIDGE_VST_MAC:
fOptions.bridge_vstMac = valueStr;
break;
case OPTION_PATH_BRIDGE_VST_HWND:
fOptions.bridge_vstHWND = valueStr;


+ 41
- 24
source/backend/engine/CarlaEngineJack.cpp View File

@@ -19,6 +19,8 @@
#include "CarlaBackendUtils.hpp"
#include "CarlaMIDI.h"

#include "juce_core.h"

#ifdef JACKBRIDGE_EXPORT
# include "jackbridge/JackBridge.hpp"
#else
@@ -27,10 +29,12 @@
#endif

#include <cmath>
#include <QtCore/QStringList>

#define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon"

using juce::String;
using juce::StringArray;

CARLA_BACKEND_START_NAMESPACE

#if 0
@@ -755,11 +759,12 @@ public:
void* data;
size_t dataSize;

QList<int> groupIconsCopy(fGroupIconsChanged);
fGroupIconsChanged.clear();
NonRtList<int> groupIconsCopy;
fGroupIconsChanged.spliceAppend(groupIconsCopy, true);

foreach (const int& groupId, groupIconsCopy)
for (NonRtList<int>::Itenerator it = groupIconsCopy.begin(); it.valid(); it.next())
{
const int& groupId(*it);
const char* const groupName(getGroupName(groupId));

data = nullptr;
@@ -792,6 +797,8 @@ public:
jackbridge_free(data);
}
}

groupIconsCopy.clear();
}
#endif

@@ -986,8 +993,10 @@ public:
return false;
}

foreach (const ConnectionToId& connectionToId, fUsedConnections)
for (NonRtList<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
{
const ConnectionToId& connectionToId(*it);

if (connectionToId.id == connectionId)
{
char portNameOut[STR_MAX+1];
@@ -1534,14 +1543,14 @@ protected:
}
else
{
for (int i=0, count=fUsedConnections.count(); i < count; ++i)
for (NonRtList<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
{
const ConnectionToId& connectionToId(fUsedConnections[i]);
const ConnectionToId& connectionToId(*it);

if (connectionToId.portOut == portIdA && connectionToId.portIn == portIdB)
{
callback(CALLBACK_PATCHBAY_CONNECTION_REMOVED, 0, connectionToId.id, 0, 0.0f, nullptr);
fUsedConnections.takeAt(i);
fUsedConnections.remove(it);
break;
}
}
@@ -1550,9 +1559,9 @@ protected:

void handleJackClientRenameCallback(const char* const oldName, const char* const newName)
{
for (int i=0, count=fUsedGroupNames.count(); i < count; ++i)
for (NonRtList<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
{
GroupNameToId& groupNameToId(fUsedGroupNames[i]);
GroupNameToId& groupNameToId(*it);

if (std::strcmp(groupNameToId.name, oldName) == 0)
{
@@ -1586,9 +1595,9 @@ protected:
if (groupId == -1)
return;

for (int i=0, count=fUsedPortNames.count(); i < count; ++i)
for (NonRtList<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
{
PortNameToId& portNameId(fUsedPortNames[i]);
PortNameToId& portNameId(*it);

if (std::strcmp(portNameId.fullName, oldName) == 0)
{
@@ -1754,10 +1763,10 @@ private:
int fLastPortId;
int fLastConnectionId;

QList<GroupNameToId> fUsedGroupNames;
QList<PortNameToId> fUsedPortNames;
QList<ConnectionToId> fUsedConnections;
QList<int> fGroupIconsChanged;
NonRtList<GroupNameToId> fUsedGroupNames;
NonRtList<PortNameToId> fUsedPortNames;
NonRtList<ConnectionToId> fUsedConnections;
NonRtList<int> fGroupIconsChanged;

int getGroupId(const char* const name)
{
@@ -1766,8 +1775,10 @@ private:
if (name == nullptr)
return -1;

foreach (const GroupNameToId& groupNameId, fUsedGroupNames)
for (NonRtList<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
{
const GroupNameToId& groupNameId(*it);

if (std::strcmp(groupNameId.name, name) == 0)
return groupNameId.id;
}
@@ -1784,8 +1795,10 @@ private:
if (groupId < 0)
return fallback;

foreach (const GroupNameToId& groupNameId, fUsedGroupNames)
for (NonRtList<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
{
const GroupNameToId& groupNameId(*it);

if (groupNameId.id == groupId)
return groupNameId.name;
}
@@ -1800,8 +1813,10 @@ private:
if (fullName == nullptr)
return -1;

foreach (const PortNameToId& portNameId, fUsedPortNames)
for (NonRtList<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
{
const PortNameToId& portNameId(*it);

if (std::strcmp(portNameId.fullName, fullName) == 0)
return portNameId.portId;
}
@@ -1811,8 +1826,10 @@ private:

void getFullPortName(const int portId, char nameBuf[STR_MAX+1])
{
foreach (const PortNameToId& portNameId, fUsedPortNames)
for (NonRtList<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
{
const PortNameToId& portNameId(*it);

if (portNameId.portId == portId)
{
std::strncpy(nameBuf, portNameId.fullName, STR_MAX);
@@ -1832,12 +1849,12 @@ private:
CARLA_ASSERT(ourName != nullptr);

// query initial jack ports
QStringList parsedGroups;
StringArray parsedGroups;

// our client
if (ourName != nullptr)
{
parsedGroups.append(QString(ourName));
parsedGroups.add(String(ourName));

GroupNameToId groupNameToId(fLastGroupId++, ourName);
fUsedGroupNames.append(groupNameToId);
@@ -1868,7 +1885,7 @@ private:
CarlaString groupName(fullPortName);
groupName.truncate(groupName.rfind(portName)-1);

QString qGroupName(groupName);
String qGroupName(groupName);

if (parsedGroups.contains(qGroupName))
{
@@ -1878,7 +1895,7 @@ private:
else
{
groupId = fLastGroupId++;
parsedGroups.append(qGroupName);
parsedGroups.add(qGroupName);

GroupNameToId groupNameToId(groupId, groupName);
fUsedGroupNames.append(groupNameToId);


+ 2
- 2
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -20,7 +20,7 @@
#include "CarlaMIDI.h"
#include "RtList.hpp"

#include "JuceHeader.h"
#include "juce_audio_basics.h"

CARLA_BACKEND_START_NAMESPACE

@@ -34,7 +34,7 @@ CARLA_BACKEND_START_NAMESPACE
static const char** gRetNames = nullptr;

class CarlaEngineJuce : public CarlaEngine,
public juce::AudioIODeviceCallback
public juce::AudioIODeviceCallback
{
public:
CarlaEngineJuce()


+ 4
- 6
source/backend/engine/CarlaEngineNative.cpp View File

@@ -20,14 +20,11 @@
#include "CarlaEngineInternal.hpp"
#include "CarlaStateUtils.hpp"

#include "carla_native/CarlaNative.hpp"

#include <QtCore/QProcess>
#include <QtCore/QTextStream>
#include <QtCore/QThread>
#include "CarlaNative.hpp"

CARLA_BACKEND_START_NAMESPACE

#if 0
// -----------------------------------------------------------------------

class CarlaEngineNativeThread : public QThread
@@ -753,11 +750,12 @@ static const PluginDescriptor carlaDesc = {
/* copyright */ "GNU GPL v2+",
PluginDescriptorFILL(CarlaEngineNative)
};
#endif

CARLA_EXPORT
void carla_register_native_plugin_carla()
{
carla_register_native_plugin(&carlaDesc);
//carla_register_native_plugin(&carlaDesc);
}

CARLA_BACKEND_END_NAMESPACE


+ 5
- 5
source/backend/engine/CarlaEngineThread.cpp View File

@@ -46,7 +46,7 @@ void CarlaEngineThread::run()
CARLA_ASSERT(fEngine->isRunning());
carla_debug("CarlaEngineThread::run()");

bool oscRegisted, usesSingleThread;
bool oscRegisted, needsSingleThread;
unsigned int i, count;
float value;

@@ -67,14 +67,14 @@ void CarlaEngineThread::run()

CARLA_SAFE_ASSERT_INT2(i == plugin->getId(), i, plugin->getId());

usesSingleThread = (plugin->getHints() & PLUGIN_HAS_SINGLE_THREAD);
needsSingleThread = (plugin->getHints() & PLUGIN_NEEDS_SINGLE_THREAD);

// -----------------------------------------------------------
// Process postponed events

if (oscRegisted || ! usesSingleThread)
if (oscRegisted || ! needsSingleThread)
{
if (! usesSingleThread)
if (! needsSingleThread)
plugin->postRtEventsRun();

// -------------------------------------------------------
@@ -88,7 +88,7 @@ void CarlaEngineThread::run()
value = plugin->getParameterValue(j);

// Update UI
if (! usesSingleThread)
if (! needsSingleThread)
plugin->uiParameterChange(j, value);

// Update OSC engine client


+ 5
- 18
source/backend/engine/Makefile View File

@@ -11,11 +11,11 @@ include ../Makefile.mk
BUILD_CXX_FLAGS += -D__UNIX_JACK__
BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo)

ifeq ($(HAVE_QT4),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtXml)
else
BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Xml)
endif
# ifeq ($(HAVE_QT4),true)
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtXml)
# else
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Xml)
# endif

# --------------------------------------------------------------

@@ -45,10 +45,6 @@ ifeq ($(WIN32),true)
BUILD_CXX_FLAGS += -D__WINDOWS_ASIO__ -D__WINDOWS_DS__ -D__WINDOWS_MM__
endif

PLUGIN_CXX_FLAGS = $(BUILD_CXX_FLAGS)
PLUGIN_CXX_FLAGS += -Idistrho -I../../libs/distrho
PLUGIN_CXX_FLAGS += -DWANT_PLUGIN

# --------------------------------------------------------------

OBJSp = \
@@ -98,15 +94,6 @@ HEADERS = \
%.cpp.o: %.cpp $(HEADERS)
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

%.cpp.dssi.o: %.cpp $(HEADERS)
$(CXX) $< $(PLUGIN_CXX_FLAGS) -DDISTRHO_PLUGIN_TARGET_DSSI -c -o $@

%.cpp.lv2.o: %.cpp $(HEADERS)
$(CXX) $< $(PLUGIN_CXX_FLAGS) -DDISTRHO_PLUGIN_TARGET_LV2 -c -o $@

%.cpp.vst.o: %.cpp $(HEADERS)
$(CXX) $< $(PLUGIN_CXX_FLAGS) -DDISTRHO_PLUGIN_TARGET_VST -c -o $@

$(TARGET): $(OBJS)
$(AR) rs $@ $^



+ 0
- 5
source/backend/plugin/BridgePlugin.cpp View File

@@ -28,11 +28,6 @@
#include <cmath>
#include <ctime>

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>

#define CARLA_BRIDGE_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
/* check argument count */ \
if (argc != argcToCompare) \


+ 20
- 10
source/backend/plugin/CarlaPlugin.cpp View File

@@ -20,10 +20,6 @@
#include "CarlaLibUtils.hpp"
#include "CarlaStateUtils.hpp"

#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QSettings>

CARLA_BACKEND_START_NAMESPACE

// -------------------------------------------------------------------
@@ -181,13 +177,14 @@ const char* CarlaPluginProtectedData::libError(const char* const filename)

void CarlaPluginProtectedData::saveSetting(const unsigned int option, const bool yesNo)
{
#if 0
QSettings settings("falkTX", "CarlaPluginSettings");
settings.beginGroup((const char*)idStr);

switch (option)
{
case PLUGIN_OPTION_FIXED_BUFFER:
settings.setValue("FixedBuffer", yesNo);
case PLUGIN_OPTION_FIXED_BUFFERS:
settings.setValue("FixedBuffers", yesNo);
break;
case PLUGIN_OPTION_FORCE_STEREO:
settings.setValue("ForceStereo", yesNo);
@@ -218,10 +215,12 @@ void CarlaPluginProtectedData::saveSetting(const unsigned int option, const bool
}

settings.endGroup();
#endif
}

unsigned int CarlaPluginProtectedData::loadSettings(const unsigned int options, const unsigned int availOptions)
{
#if 0
QSettings settings("falkTX", "CarlaPluginSettings");
settings.beginGroup((const char*)idStr);

@@ -239,7 +238,7 @@ unsigned int CarlaPluginProtectedData::loadSettings(const unsigned int options,
newOptions |= BIT; \
}

CHECK_AND_SET_OPTION("FixedBuffer", PLUGIN_OPTION_FIXED_BUFFER);
CHECK_AND_SET_OPTION("FixedBuffers", PLUGIN_OPTION_FIXED_BUFFERS);
CHECK_AND_SET_OPTION("ForceStereo", PLUGIN_OPTION_FORCE_STEREO);
CHECK_AND_SET_OPTION("MapProgramChanges", PLUGIN_OPTION_MAP_PROGRAM_CHANGES);
CHECK_AND_SET_OPTION("UseChunks", PLUGIN_OPTION_USE_CHUNKS);
@@ -254,6 +253,8 @@ unsigned int CarlaPluginProtectedData::loadSettings(const unsigned int options,
settings.endGroup();

return newOptions;
#endif
return 0x0;
}

// -------------------------------------------------------------------
@@ -620,7 +621,8 @@ const SaveState& CarlaPlugin::getSaveState()

if (data != nullptr && dataSize > 0)
{
saveState.chunk = carla_strdup(QByteArray((char*)data, dataSize).toBase64().constData());
// TODO
//saveState.chunk = carla_strdup(QByteArray((char*)data, dataSize).toBase64().constData());

// Don't save anything else if using chunks
return saveState;
@@ -729,7 +731,7 @@ struct ParamSymbol {
void CarlaPlugin::loadSaveState(const SaveState& saveState)
{
char strBuf[STR_MAX+1];
const bool usesMultiProgs(getType() == PLUGIN_SF2 || (getType() == PLUGIN_INTERNAL && (fHints & PLUGIN_IS_SYNTH) != 0));
const bool usesMultiProgs(getType() == PLUGIN_SF2 /*|| (getType() == PLUGIN_INTERNAL && (fHints & PLUGIN_IS_SYNTH) != 0)*/); // TODO

// ---------------------------------------------------------------------
// Part 1 - PRE-set custom data (only that which reload programs)
@@ -941,6 +943,7 @@ bool CarlaPlugin::saveStateToFile(const char* const filename)
carla_debug("CarlaPlugin::saveStateToFile(\"%s\")", filename);
CARLA_ASSERT(filename != nullptr);

#if 0
QFile file(filename);

if (! file.open(QIODevice::WriteOnly | QIODevice::Text))
@@ -958,6 +961,9 @@ bool CarlaPlugin::saveStateToFile(const char* const filename)

file.close();
return true;
#endif
pData->engine->setLastError("NIY");
return false;
}

bool CarlaPlugin::loadStateFromFile(const char* const filename)
@@ -965,6 +971,7 @@ bool CarlaPlugin::loadStateFromFile(const char* const filename)
carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename);
CARLA_ASSERT(filename != nullptr);

#if 0
QFile file(filename);

if (! file.open(QIODevice::ReadOnly | QIODevice::Text))
@@ -987,6 +994,9 @@ bool CarlaPlugin::loadStateFromFile(const char* const filename)
loadSaveState(saveState);

return true;
#endif
pData->engine->setLastError("NIY");
return false;
}

// -------------------------------------------------------------------
@@ -1537,7 +1547,7 @@ void CarlaPlugin::idleGui()
if (! fEnabled)
return;

if (fHints & PLUGIN_HAS_SINGLE_THREAD)
if (fHints & PLUGIN_NEEDS_SINGLE_THREAD)
{
// Process postponed events
postRtEventsRun();


+ 3
- 1
source/backend/plugin/CarlaPluginGui.cpp View File

@@ -17,7 +17,8 @@

#include "CarlaPluginGui.hpp"

# include <QtCore/QSettings>
#if 0
#include <QtCore/QSettings>

#ifdef Q_WS_X11
# include <QtGui/QX11EmbedContainer>
@@ -149,3 +150,4 @@ void CarlaPluginGui::setSizeSafeSlot(int width, int height)
// -------------------------------------------------------------------

CARLA_BACKEND_END_NAMESPACE
#endif

+ 2
- 0
source/backend/plugin/CarlaPluginGui.hpp View File

@@ -20,6 +20,7 @@

#include "CarlaPluginInternal.hpp"

#if 0
#include <QtGui/QCloseEvent>

# if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
@@ -78,5 +79,6 @@ private slots:
};

CARLA_BACKEND_END_NAMESPACE
#endif

#endif // CARLA_PLUGIN_GUI_HPP_INCLUDED

+ 2
- 2
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -28,7 +28,7 @@
#include "CarlaMIDI.h"
#include "RtList.hpp"

#include <QtCore/QByteArray>
// #include <QtCore/QByteArray>

#define CARLA_PROCESS_CONTINUE_CHECK if (! fEnabled) { pData->engine->callback(CALLBACK_DEBUG, fId, 0, 0, 0.0f, "Processing while plugin is disabled!!"); return; }

@@ -483,7 +483,7 @@ struct CarlaPluginProtectedData {
CarlaEngine* const engine;
CarlaEngineClient* client;
CarlaPluginGui* gui;
QByteArray guiGeometry;
//QByteArray guiGeometry;

bool active;
bool needsReset;


+ 13
- 8
source/backend/plugin/DssiPlugin.cpp View File

@@ -106,8 +106,9 @@ public:

PluginCategory getCategory() const override
{
if (fHints & PLUGIN_IS_SYNTH)
return PLUGIN_CATEGORY_SYNTH;
// TODO
//if (fHints & PLUGIN_IS_SYNTH)
// return PLUGIN_CATEGORY_SYNTH;

return getPluginCategoryFromName(fName);
}
@@ -179,7 +180,7 @@ public:
options |= PLUGIN_OPTION_FORCE_STEREO;
}

options |= PLUGIN_OPTION_FIXED_BUFFER;
options |= PLUGIN_OPTION_FIXED_BUFFERS;
}

if (fDssiDescriptor->run_synth != nullptr || fDssiDescriptor->run_multiple_synths != nullptr)
@@ -331,6 +332,8 @@ public:
if (fDssiDescriptor->set_custom_data == nullptr)
return;

// TODO
#if 0
QByteArray chunk(QByteArray::fromBase64(stringData));

CARLA_ASSERT(chunk.size() > 0);
@@ -340,6 +343,7 @@ public:
const ScopedSingleProcessLocker spl(this, true);
fDssiDescriptor->set_custom_data(fHandle, chunk.data(), chunk.size());
}
#endif
}

void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
@@ -767,8 +771,9 @@ public:
if (fGuiFilename.isNotEmpty())
fHints |= PLUGIN_HAS_GUI;

if (mIns == 1 && aIns == 0 && aOuts > 0)
fHints |= PLUGIN_IS_SYNTH;
// TODO
//if (mIns == 1 && aIns == 0 && aOuts > 0)
// fHints |= PLUGIN_IS_SYNTH;

if (aOuts > 0 && (aIns == aOuts || aIns == 1))
fHints |= PLUGIN_CAN_DRYWET;
@@ -1066,7 +1071,7 @@ public:
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = pData->event.portIn->getEventCount();
uint32_t startTime = 0;
@@ -1928,7 +1933,7 @@ public:

if (isDssiVst)
{
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getOptions().useDssiVstChunks && fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr)
fOptions |= PLUGIN_OPTION_USE_CHUNKS;
@@ -1954,7 +1959,7 @@ public:

// ignore settings, we need this anyway
if (isDssiVst)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;
}

return true;


+ 29
- 31
source/backend/plugin/FluidSynthPlugin.cpp View File

@@ -21,8 +21,6 @@

#include <fluidsynth.h>

#include <QtCore/QStringList>

#define FLUIDSYNTH_VERSION_NEW_API (FLUIDSYNTH_VERSION_MAJOR >= 1 && FLUIDSYNTH_VERSION_MINOR >= 1 && FLUIDSYNTH_VERSION_MICRO >= 4)

CARLA_BACKEND_START_NAMESPACE
@@ -444,34 +442,34 @@ public:
if (value == nullptr)
return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));

QStringList midiProgramList(QString(value).split(":", QString::SkipEmptyParts));
if (midiProgramList.count() == MAX_MIDI_CHANNELS)
{
uint i = 0;
foreach (const QString& midiProg, midiProgramList)
{
bool ok;
uint index = midiProg.toUInt(&ok);
if (ok && index < pData->midiprog.count)
{
const uint32_t bank = pData->midiprog.data[index].bank;
const uint32_t program = pData->midiprog.data[index].program;
fluid_synth_program_select(fSynth, i, fSynthId, bank, program);
fCurMidiProgs[i] = index;
if (pData->ctrlChannel == static_cast<int32_t>(i))
{
pData->midiprog.current = index;
pData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, index, 0, 0.0f, nullptr);
}
}
++i;
}
}
// QStringList midiProgramList(QString(value).split(":", QString::SkipEmptyParts));
//
// if (midiProgramList.count() == MAX_MIDI_CHANNELS)
// {
// uint i = 0;
// foreach (const QString& midiProg, midiProgramList)
// {
// bool ok;
// uint index = midiProg.toUInt(&ok);
//
// if (ok && index < pData->midiprog.count)
// {
// const uint32_t bank = pData->midiprog.data[index].bank;
// const uint32_t program = pData->midiprog.data[index].program;
//
// fluid_synth_program_select(fSynth, i, fSynthId, bank, program);
// fCurMidiProgs[i] = index;
//
// if (pData->ctrlChannel == static_cast<int32_t>(i))
// {
// pData->midiprog.current = index;
// pData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, index, 0, 0.0f, nullptr);
// }
// }
//
// ++i;
// }
// }

CarlaPlugin::setCustomData(type, key, value, sendGui);
}
@@ -876,7 +874,7 @@ public:

// plugin hints
fHints = 0x0;
fHints |= PLUGIN_IS_SYNTH;
//fHints |= PLUGIN_IS_SYNTH;
fHints |= PLUGIN_CAN_VOLUME;
fHints |= PLUGIN_CAN_BALANCE;



+ 4
- 4
source/backend/plugin/LadspaPlugin.cpp View File

@@ -173,7 +173,7 @@ public:
unsigned int options = 0x0;

if (! isDssiVst)
options |= PLUGIN_OPTION_FIXED_BUFFER;
options |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK)
{
@@ -889,7 +889,7 @@ public:
// ----------------------------------------------------------------------------------------------------
// Event Input (System)

bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = pData->event.portIn->getEventCount();
uint32_t timeOffset = 0;
@@ -1465,7 +1465,7 @@ public:
fOptions = 0x0;

if (isDssiVst)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getOptions().forceStereo)
fOptions |= PLUGIN_OPTION_FORCE_STEREO;
@@ -1481,7 +1481,7 @@ public:

// ignore settings, we need this anyway
if (isDssiVst)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;
}

return true;


+ 9
- 11
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -29,8 +29,6 @@
#define __cplusplus old__cplusplus
#undef old__cplusplus

#include <QtCore/QFileInfo>

namespace LinuxSampler {

using CarlaBackend::CarlaEngine;
@@ -422,7 +420,7 @@ public:

// plugin hints
fHints = 0x0;
fHints |= PLUGIN_IS_SYNTH;
//fHints |= PLUGIN_IS_SYNTH;
fHints |= PLUGIN_CAN_VOLUME;
fHints |= PLUGIN_CAN_BALANCE;

@@ -581,7 +579,7 @@ public:
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = pData->event.portIn->getEventCount();
uint32_t startTime = 0;
@@ -980,13 +978,13 @@ public:
// ---------------------------------------------------------------
// Check if file exists
{
QFileInfo file(filename);
if (! (file.exists() && file.isFile() && file.isReadable()))
{
pData->engine->setLastError("Requested file is not valid or does not exist");
return false;
}
// QFileInfo file(filename);
//
// if (! (file.exists() && file.isFile() && file.isReadable()))
// {
// pData->engine->setLastError("Requested file is not valid or does not exist");
// return false;
// }
}

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


+ 58
- 54
source/backend/plugin/Lv2Plugin.cpp View File

@@ -25,8 +25,6 @@

#include "../engine/CarlaEngineOsc.hpp"

#include <QtCore/QDir>

extern "C" {
#include "rtmempool/rtmempool-lv2.h"
}
@@ -338,8 +336,8 @@ struct Lv2PluginOptions {
optNull.type = CARLA_URI_MAP_ID_NULL;
optNull.value = nullptr;

opts[0] = &optMinBlockLenth;
opts[1] = &optMaxBlockLenth;
opts[0] = &optMaxBlockLenth;
opts[1] = &optMinBlockLenth;
opts[2] = &optSequenceSize;
opts[3] = &optSampleRate;
opts[4] = &optNull;
@@ -350,8 +348,8 @@ struct Lv2PluginOptions {

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

class Lv2Plugin : public CarlaPlugin,
public CarlaPluginGui::Callback
class Lv2Plugin : public CarlaPlugin/*,
public CarlaPluginGui::Callback*/
{
public:
Lv2Plugin(CarlaEngine* const engine, const unsigned int id)
@@ -646,7 +644,7 @@ public:
options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (! (hasMidiIn || needsFixedBuffer()))
options |= PLUGIN_OPTION_FIXED_BUFFER;
options |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK)
{
@@ -917,10 +915,10 @@ public:
{
CarlaPlugin::setName(newName);

QString guiTitle(QString("%1 (GUI)").arg((const char*)fName));
//QString guiTitle(QString("%1 (GUI)").arg((const char*)fName));

if (pData->gui != nullptr)
pData->gui->setWindowTitle(guiTitle);
//if (pData->gui != nullptr)
//pData->gui->setWindowTitle(guiTitle);

if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
{
@@ -929,7 +927,7 @@ public:
if (uiHost->plugin_human_id != nullptr)
delete[] uiHost->plugin_human_id;

uiHost->plugin_human_id = carla_strdup(guiTitle.toUtf8().constData());
//uiHost->plugin_human_id = carla_strdup(guiTitle.toUtf8().constData());
}
}

@@ -1164,6 +1162,7 @@ public:
}
else // means PLUGIN_UI_PARENT || PLUGIN_UI_QT
{
#if 0
if (yesNo)
{
if (pData->gui == nullptr)
@@ -1229,6 +1228,7 @@ public:
pData->gui = nullptr;
}
}
#endif
}
}

@@ -1254,8 +1254,8 @@ public:
{
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, lv2_atom_total_size(atom));
//osc_send_lv2_atom_transfer(pData->osc.data, portIndex, chunk.toBase64().constData());
}
}
else if (fUi.type != PLUGIN_UI_NULL)
@@ -2133,11 +2133,11 @@ public:
fHints |= PLUGIN_HAS_GUI;

if (fUi.type == PLUGIN_UI_QT || fUi.type == PLUGIN_UI_PARENT)
fHints |= PLUGIN_HAS_SINGLE_THREAD;
fHints |= PLUGIN_NEEDS_SINGLE_THREAD;
}

if (LV2_IS_GENERATOR(fRdfDescriptor->Type[0], fRdfDescriptor->Type[1]))
fHints |= PLUGIN_IS_SYNTH;
//if (LV2_IS_GENERATOR(fRdfDescriptor->Type[0], fRdfDescriptor->Type[1]))
// fHints |= PLUGIN_IS_SYNTH;

if (aOuts > 0 && (aIns == aOuts || aIns == 1))
fHints |= PLUGIN_CAN_DRYWET;
@@ -2676,7 +2676,7 @@ public:
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
uint32_t startTime = 0;
@@ -3621,11 +3621,11 @@ public:
// -------------------------------------------------------------------

protected:
void guiClosedCallback() override
{
showGui(false);
pData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
}
// void guiClosedCallback() override
// {
// showGui(false);
// pData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
// }

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

@@ -3756,8 +3756,8 @@ protected:

if (std::strcmp(stype, LV2_ATOM__String) == 0 || std::strcmp(stype, LV2_ATOM__Path) == 0)
data.value = carla_strdup((const char*)value);
else
data.value = carla_strdup(QByteArray((const char*)value, size).toBase64().constData());
//else
//data.value = carla_strdup(QByteArray((const char*)value, size).toBase64().constData());

return LV2_STATE_SUCCESS;
}
@@ -3770,8 +3770,8 @@ protected:

if (std::strcmp(stype, LV2_ATOM__String) == 0 || std::strcmp(stype, LV2_ATOM__Path) == 0)
newData.value = carla_strdup((const char*)value);
else
newData.value = carla_strdup(QByteArray((const char*)value, size).toBase64().constData());
//else
//newData.value = carla_strdup(QByteArray((const char*)value, size).toBase64().constData());

pData->custom.append(newData);

@@ -3835,10 +3835,11 @@ protected:
}
else
{
static QByteArray chunk;
chunk = QByteArray::fromBase64(stringData);
*size = chunk.size();
return chunk.constData();
// static QByteArray chunk;
// chunk = QByteArray::fromBase64(stringData);
// *size = chunk.size();
// return chunk.constData();
return nullptr;
}
}

@@ -3918,8 +3919,8 @@ protected:
if (width <= 0 || height <= 0)
return 1;

if (pData->gui != nullptr)
pData->gui->setSize(width, height);
//if (pData->gui != nullptr)
// pData->gui->setSize(width, height);

return 0;
}
@@ -4372,8 +4373,8 @@ public:
{
if (LV2_IS_FEATURE_REQUIRED(fRdfDescriptor->Features[i].Type) && ! is_lv2_feature_supported(fRdfDescriptor->Features[i].URI))
{
QString msg(QString("Plugin requires a feature that is not supported:\n%1").arg(fRdfDescriptor->Features[i].URI));
pData->engine->setLastError(msg.toUtf8().constData());
// QString msg(QString("Plugin requires a feature that is not supported:\n%1").arg(fRdfDescriptor->Features[i].URI));
// pData->engine->setLastError(msg.toUtf8().constData());
canContinue = false;
break;
}
@@ -4440,7 +4441,7 @@ public:
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (getMidiInCount() > 0 || needsFixedBuffer())
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getOptions().forceStereo)
fOptions |= PLUGIN_OPTION_FORCE_STEREO;
@@ -4460,7 +4461,7 @@ public:

// ignore settings, we need this anyway
if (getMidiInCount() > 0 || needsFixedBuffer())
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;
}

// ---------------------------------------------------------------
@@ -4493,7 +4494,7 @@ public:

switch (fRdfDescriptor->UIs[i].Type)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#if 0//(QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
case LV2_UI_QT4:
if (isUiBridgeable(i))
eQt4 = i;
@@ -4506,7 +4507,7 @@ public:
break;
#endif

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#if 0//(QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
case LV2_UI_QT5:
if (isUiBridgeable(i) && preferUiBridges)
eQt5 = i;
@@ -4683,7 +4684,7 @@ public:

switch (uiType)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#if 0//(QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
case LV2_UI_QT5:
carla_debug("Will use LV2 Qt5 UI");
fUi.type = PLUGIN_UI_QT;
@@ -4742,7 +4743,7 @@ public:
// -------------------------------------------------------
// initialize ui features (part 1)

QString guiTitle(QString("%1 (GUI)").arg((const char*)fName));
//QString guiTitle(QString("%1 (GUI)").arg((const char*)fName));

LV2_Extension_Data_Feature* const uiDataFt = new LV2_Extension_Data_Feature;
uiDataFt->data_access = fDescriptor->extension_data;
@@ -4757,7 +4758,7 @@ public:

LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host;
uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed;
uiExternalHostFt->plugin_human_id = carla_strdup(guiTitle.toUtf8().constData());
uiExternalHostFt->plugin_human_id = nullptr; //carla_strdup(guiTitle.toUtf8().constData());

// -------------------------------------------------------
// initialize ui features (part 2)
@@ -5020,9 +5021,10 @@ private:
if (path == nullptr)
return nullptr;

QDir dir;
dir.mkpath(path);
return strdup(path);
//QDir dir;
//dir.mkpath(path);
//return strdup(path);
return nullptr;
}

static char* carla_lv2_state_map_abstract_path(LV2_State_Map_Path_Handle handle, const char* absolute_path)
@@ -5034,8 +5036,9 @@ private:
if (absolute_path == nullptr)
return nullptr;

QDir dir(absolute_path);
return strdup(dir.canonicalPath().toUtf8().constData());
//QDir dir(absolute_path);
//return strdup(dir.canonicalPath().toUtf8().constData());
return nullptr;
}

static char* carla_lv2_state_map_absolute_path(LV2_State_Map_Path_Handle handle, const char* abstract_path)
@@ -5047,8 +5050,9 @@ private:
if (abstract_path == nullptr)
return nullptr;

QDir dir(abstract_path);
return strdup(dir.absolutePath().toUtf8().constData());
//QDir dir(abstract_path);
//return strdup(dir.absolutePath().toUtf8().constData());
return nullptr;
}

static LV2_State_Status carla_lv2_state_store(LV2_State_Handle handle, uint32_t key, const void* value, size_t size, uint32_t type, uint32_t flags)
@@ -5407,11 +5411,11 @@ int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
if (portIndex < 0)
return 0;

QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf);
LV2_Atom* const atom = (LV2_Atom*)chunk.data();
lv2PluginPtr->handleTransferAtom(portIndex, atom);
// QByteArray chunk;
// chunk = QByteArray::fromBase64(atomBuf);
//
// LV2_Atom* const atom = (LV2_Atom*)chunk.data();
// lv2PluginPtr->handleTransferAtom(portIndex, atom);
return 0;
}

@@ -5434,7 +5438,7 @@ int CarlaEngineOsc::handleMsgLv2UridMap(CARLA_ENGINE_OSC_HANDLE_ARGS2)

CARLA_BACKEND_END_NAMESPACE

#else // WANT_VST
#else // WANT_LV2
# warning Building without LV2 support
#endif



+ 5
- 5
source/backend/plugin/Makefile View File

@@ -10,11 +10,11 @@ include ../Makefile.mk

BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo)

ifeq ($(HAVE_QT4),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui QtXml)
else
BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Xml Qt5Widgets)
endif
# ifeq ($(HAVE_QT4),true)
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui QtXml)
# else
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Xml Qt5Widgets)
# endif

# --------------------------------------------------------------



+ 28
- 27
source/backend/plugin/NativePlugin.cpp View File

@@ -19,15 +19,7 @@

#ifdef WANT_NATIVE

#include "carla_native/CarlaNative.h"

#include <QtCore/Qt>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
# include <QtWidgets/QFileDialog>
#else
# include <QtGui/QFileDialog>
#endif
#include "CarlaNative.h"

extern "C" {

@@ -63,7 +55,7 @@ void carla_register_native_plugin_3BandEQ();
void carla_register_native_plugin_3BandSplitter();
void carla_register_native_plugin_Nekobi();
void carla_register_native_plugin_PingPongPan();
void carla_register_native_plugin_StereoEnhancer();
//void carla_register_native_plugin_StereoEnhancer();
#endif

// DISTRHO plugins (Qt)
@@ -109,7 +101,7 @@ void carla_register_all_plugins()
carla_register_native_plugin_3BandSplitter();
carla_register_native_plugin_Nekobi();
carla_register_native_plugin_PingPongPan();
carla_register_native_plugin_StereoEnhancer(); // unfinished
//carla_register_native_plugin_StereoEnhancer(); // unfinished
#endif

// DISTRHO plugins (Qt)
@@ -368,8 +360,8 @@ public:
if (hasMidiProgs && (fDescriptor->supports & ::PLUGIN_SUPPORTS_PROGRAM_CHANGES) == 0)
options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (getMidiInCount() == 0 && (fDescriptor->hints & ::PLUGIN_USES_STATIC_BUFFERS) == 0)
options |= PLUGIN_OPTION_FIXED_BUFFER;
if (getMidiInCount() == 0 && (fDescriptor->hints & ::PLUGIN_NEEDS_FIXED_BUFFERS) == 0)
options |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK)
{
@@ -556,7 +548,7 @@ public:
CARLA_ASSERT(fDescriptor != nullptr);
CARLA_ASSERT(fHandle != nullptr);

if (pData->midiprog.count > 0 && (fHints & PLUGIN_IS_SYNTH) != 0)
if (pData->midiprog.count > 0 /*&& (fHints & PLUGIN_IS_SYNTH) != 0*/) // TODO
{
char strBuf[STR_MAX+1];
std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i",
@@ -666,6 +658,7 @@ public:
}
else if (std::strcmp(key, "midiPrograms") == 0 && fDescriptor->set_midi_program != nullptr)
{
#if 0 // TODO
QStringList midiProgramList(QString(value).split(":", QString::SkipEmptyParts));

if (midiProgramList.count() == MAX_MIDI_CHANNELS)
@@ -698,6 +691,7 @@ public:
++i;
}
}
#endif
}
else
{
@@ -727,8 +721,9 @@ public:
else if (index > static_cast<int32_t>(pData->midiprog.count))
return;

if ((fHints & PLUGIN_IS_SYNTH) != 0 && (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS))
return;
// TODO
//if ((fHints & PLUGIN_IS_SYNTH) != 0 && (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS))
// return;

if (index >= 0)
{
@@ -1175,12 +1170,12 @@ public:
// native plugin hints
if (fDescriptor->hints & ::PLUGIN_IS_RTSAFE)
fHints |= PLUGIN_IS_RTSAFE;
if (fDescriptor->hints & ::PLUGIN_IS_SYNTH)
fHints |= PLUGIN_IS_SYNTH;
if (fDescriptor->hints & ::PLUGIN_HAS_GUI)
fHints |= PLUGIN_HAS_GUI;
if (fDescriptor->hints & ::PLUGIN_USES_SINGLE_THREAD)
fHints |= PLUGIN_HAS_SINGLE_THREAD;
if (fDescriptor->hints & ::PLUGIN_NEEDS_SINGLE_THREAD)
fHints |= PLUGIN_NEEDS_SINGLE_THREAD;
if (fDescriptor->hints & ::PLUGIN_NEEDS_FIXED_BUFFERS)
fHints |= PLUGIN_NEEDS_FIXED_BUFFERS;

// extra plugin hints
pData->extraHints = 0x0;
@@ -1438,7 +1433,7 @@ public:
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = pData->event.portIn->getEventCount();
uint32_t startTime = 0;
@@ -2183,20 +2178,22 @@ protected:
const char* handleUiOpenFile(const bool isDir, const char* const title, const char* const filter)
{
static CarlaString retStr;
#if 0
QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);

retStr = QFileDialog::getOpenFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();
#endif
return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
}

const char* handleUiSaveFile(const bool isDir, const char* const title, const char* const filter)
{
static CarlaString retStr;
#if 0
QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);

retStr = QFileDialog::getSaveFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();
#endif
return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
}

@@ -2234,6 +2231,10 @@ protected:
setPanning(opt, true, true);
break;
#endif
case HOST_OPCODE_GET_PARAMETER_MIDI_CC:
case HOST_OPCODE_SET_PARAMETER_MIDI_CC:
// TODO
break;
case ::HOST_OPCODE_SET_PROCESS_PRECISION:
// TODO
break;
@@ -2411,8 +2412,8 @@ public:
if (hasMidiProgs && (fDescriptor->supports & ::PLUGIN_SUPPORTS_PROGRAM_CHANGES) == 0)
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (getMidiInCount() > 0 || (fDescriptor->hints & ::PLUGIN_USES_STATIC_BUFFERS) != 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
if (getMidiInCount() > 0 || (fDescriptor->hints & ::PLUGIN_NEEDS_FIXED_BUFFERS) != 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;

if (pData->engine->getOptions().forceStereo)
fOptions |= PLUGIN_OPTION_FORCE_STEREO;
@@ -2432,8 +2433,8 @@ public:
fOptions = pData->loadSettings(fOptions, getAvailableOptions());

// ignore settings, we need this anyway
if (getMidiInCount() > 0 || (fDescriptor->hints & ::PLUGIN_USES_STATIC_BUFFERS) != 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
if (getMidiInCount() > 0 || (fDescriptor->hints & ::PLUGIN_NEEDS_FIXED_BUFFERS) != 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;
}

return true;


+ 37
- 35
source/backend/plugin/VstPlugin.cpp View File

@@ -42,8 +42,8 @@ const unsigned int PLUGIN_USES_OLD_VSTSDK = 0x4000; //!< VST Plugin uses a
const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x8000; //!< VST Plugin wants MIDI input
/**@}*/

class VstPlugin : public CarlaPlugin,
public CarlaPluginGui::Callback
class VstPlugin : public CarlaPlugin/*,
public CarlaPluginGui::Callback*/
{
public:
VstPlugin(CarlaEngine* const engine, const unsigned int id)
@@ -193,7 +193,7 @@ public:
options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (getMidiInCount() == 0)
options |= PLUGIN_OPTION_FIXED_BUFFER;
options |= PLUGIN_OPTION_FIXED_BUFFERS;

if (fEffect->flags & effFlagsProgramChunks)
options |= PLUGIN_OPTION_USE_CHUNKS;
@@ -292,8 +292,8 @@ public:
{
CarlaPlugin::setName(newName);

if (pData->gui != nullptr)
pData->gui->setWindowTitle(QString("%1 (GUI)").arg((const char*)fName));
//if (pData->gui != nullptr)
// pData->gui->setWindowTitle(QString("%1 (GUI)").arg((const char*)fName));
}

// -------------------------------------------------------------------
@@ -323,23 +323,23 @@ public:
fLastChunk = nullptr;
}

QByteArray chunk(QByteArray::fromBase64(stringData));
CARLA_ASSERT(chunk.size() > 0);
if (chunk.size() > 0)
{
fLastChunk = std::malloc(chunk.size());
std::memcpy(fLastChunk, chunk.constData(), chunk.size());
{
const ScopedSingleProcessLocker spl(this, true);
dispatcher(effSetChunk, 0 /* bank */, chunk.size(), fLastChunk, 0.0f);
}
// simulate an updateDisplay callback
handleAudioMasterCallback(audioMasterUpdateDisplay, 0, 0, nullptr, 0.0f);
}
// QByteArray chunk(QByteArray::fromBase64(stringData));
//
// CARLA_ASSERT(chunk.size() > 0);
//
// if (chunk.size() > 0)
// {
// fLastChunk = std::malloc(chunk.size());
// std::memcpy(fLastChunk, chunk.constData(), chunk.size());
//
// {
// const ScopedSingleProcessLocker spl(this, true);
// dispatcher(effSetChunk, 0 /* bank */, chunk.size(), fLastChunk, 0.0f);
// }
//
// // simulate an updateDisplay callback
// handleAudioMasterCallback(audioMasterUpdateDisplay, 0, 0, nullptr, 0.0f);
// }
}

void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
@@ -392,6 +392,7 @@ public:
}
else
{
#if 0
if (yesNo)
{
CARLA_ASSERT(pData->gui == nullptr);
@@ -465,6 +466,7 @@ public:
pData->gui = nullptr;
}
}
#endif
}

fGui.isVisible = yesNo;
@@ -789,15 +791,15 @@ public:

fHints = 0x0;

if (vstCategory == kPlugCategSynth || vstCategory == kPlugCategGenerator)
fHints |= PLUGIN_IS_SYNTH;
//if (vstCategory == kPlugCategSynth || vstCategory == kPlugCategGenerator)
// fHints |= PLUGIN_IS_SYNTH;

if (fEffect->flags & effFlagsHasEditor)
{
fHints |= PLUGIN_HAS_GUI;

if (! fGui.isOsc)
fHints |= PLUGIN_HAS_SINGLE_THREAD;
fHints |= PLUGIN_NEEDS_SINGLE_THREAD;
}

if (dispatcher(effGetVstVersion, 0, 0, nullptr, 0.0f) < kVstVersion)
@@ -1146,7 +1148,7 @@ public:
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = pData->event.portIn->getEventCount();
uint32_t startTime = 0;
@@ -1723,11 +1725,11 @@ public:
// -------------------------------------------------------------------

protected:
void guiClosedCallback() override
{
showGui(false);
pData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
}
// void guiClosedCallback() override
// {
// showGui(false);
// pData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
// }

intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) const
{
@@ -1971,8 +1973,8 @@ protected:
if (pData->gui != nullptr)
{
CARLA_SAFE_ASSERT(fGui.isVisible);
if (fGui.isVisible)
pData->gui->setSize(index, value);
//if (fGui.isVisible)
// pData->gui->setSize(index, value);
ret = 1;
}
break;
@@ -2298,7 +2300,7 @@ public:
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (getMidiInCount() > 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;

if (fEffect->flags & effFlagsProgramChunks)
fOptions |= PLUGIN_OPTION_USE_CHUNKS;
@@ -2320,7 +2322,7 @@ public:

// ignore settings, we need this anyway
if (getMidiInCount() > 0)
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_FIXED_BUFFERS;
}

return true;


+ 25
- 77
source/backend/standalone/CarlaStandalone.cpp View File

@@ -22,19 +22,18 @@
#include "CarlaEngine.hpp"
#include "CarlaPlugin.hpp"
#include "CarlaMIDI.h"

#include "carla_native/CarlaNative.h"
#include "CarlaNative.h"

#include "CarlaLogThread.hpp"
#include "CarlaStyle.hpp"

#include <QtCore/QSettings>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
# include <QtWidgets/QApplication>
#else
# include <QtGui/QApplication>
#endif
// #include <QtCore/QSettings>
//
// #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
// # include <QtWidgets/QApplication>
// #else
// # include <QtGui/QApplication>
// #endif

#if ! (defined(DEBUG) || defined(WANT_LOGS) || defined(BUILD_ANSI_TEST))
# define WANT_LOGS
@@ -47,6 +46,9 @@ using CB::CarlaPlugin;
using CB::EngineOptions;
using CB::EngineTimeInfo;

// TEST
int main() { return 0; }

// -------------------------------------------------------------------------------------------------------------------
// Single, standalone engine

@@ -57,82 +59,24 @@ struct CarlaBackendStandalone {
CarlaString lastError;
EngineOptions options;

QApplication* app;
CarlaStyle* style;
bool needsInit;

CarlaBackendStandalone()
: callback(nullptr),
callbackPtr(nullptr),
engine(nullptr),
app(qApp),
needsInit(app == nullptr)
engine(nullptr)
{
checkTheme();
}

~CarlaBackendStandalone()
{
CARLA_ASSERT(engine == nullptr);

if (needsInit)
{
CARLA_ASSERT(app == nullptr);
CARLA_ASSERT(style == nullptr);
}
}

void init()
{
if (! needsInit)
return;
if (app != nullptr)
return;

// try again, app might be registed now
app = qApp;

if (app != nullptr)
return;

static int argc = 0;
static char** argv = nullptr;
app = new QApplication(argc, argv, true);
checkTheme();
}

void close()
{
if (! needsInit)
return;
if (app == nullptr)
return;

app->quit();
app->processEvents();

if (style != nullptr)
{
delete style;
style = nullptr;
}

delete app;
app = nullptr;
}

void checkTheme()
{
if (app == nullptr || style != nullptr)
return;

QSettings settings("falkTX", "Carla");

if (settings.value("Main/UseProTheme", true).toBool())
{
style = new CarlaStyle();
app->setStyle(style);
}
}

CARLA_DECLARE_NON_COPY_STRUCT(CarlaBackendStandalone)
@@ -329,12 +273,12 @@ const CarlaNativePluginInfo* carla_get_internal_plugin_info(unsigned int interna

if (nativePlugin->hints & PLUGIN_IS_RTSAFE)
info.hints |= CB::PLUGIN_IS_RTSAFE;
if (nativePlugin->hints & PLUGIN_IS_SYNTH)
info.hints |= CB::PLUGIN_IS_SYNTH;
if (nativePlugin->hints & PLUGIN_HAS_GUI)
info.hints |= CB::PLUGIN_HAS_GUI;
if (nativePlugin->hints & PLUGIN_USES_SINGLE_THREAD)
info.hints |= CB::PLUGIN_HAS_SINGLE_THREAD;
if (nativePlugin->hints & PLUGIN_NEEDS_SINGLE_THREAD)
info.hints |= CB::PLUGIN_NEEDS_SINGLE_THREAD;
if (nativePlugin->hints & PLUGIN_NEEDS_FIXED_BUFFERS)
info.hints |= CB::PLUGIN_NEEDS_FIXED_BUFFERS;

info.audioIns = nativePlugin->audioIns;
info.audioOuts = nativePlugin->audioOuts;
@@ -435,6 +379,7 @@ bool carla_engine_init(const char* driverName, const char* clientName)
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_WIN64, 0, (const char*)gStandalone.options.bridge_win64);
#endif
#ifdef WANT_LV2
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_LV2_EXTERNAL,0, (const char*)gStandalone.options.bridge_lv2Extrn);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_LV2_GTK2, 0, (const char*)gStandalone.options.bridge_lv2Gtk2);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_LV2_GTK3, 0, (const char*)gStandalone.options.bridge_lv2Gtk3);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_LV2_QT4, 0, (const char*)gStandalone.options.bridge_lv2Qt4);
@@ -444,7 +389,7 @@ bool carla_engine_init(const char* driverName, const char* clientName)
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_LV2_X11, 0, (const char*)gStandalone.options.bridge_lv2X11);
#endif
#ifdef WANT_VST
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_VST_COCOA, 0, (const char*)gStandalone.options.bridge_vstCocoa);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_VST_MAC, 0, (const char*)gStandalone.options.bridge_vstMac);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_VST_HWND, 0, (const char*)gStandalone.options.bridge_vstHWND);
gStandalone.engine->setOption(CB::OPTION_PATH_BRIDGE_VST_X11, 0, (const char*)gStandalone.options.bridge_vstX11);
#endif
@@ -494,8 +439,8 @@ void carla_engine_idle()
{
CARLA_ASSERT(gStandalone.engine != nullptr);

if (gStandalone.needsInit && gStandalone.app != nullptr)
gStandalone.app->processEvents();
//if (gStandalone.needsInit && gStandalone.app != nullptr)
// gStandalone.app->processEvents();

if (gStandalone.engine != nullptr)
gStandalone.engine->idle();
@@ -642,6 +587,9 @@ void carla_set_engine_option(CarlaOptionsType option, int value, const char* val
#endif

#ifdef WANT_LV2
case CB::OPTION_PATH_BRIDGE_LV2_EXTERNAL:
gStandalone.options.bridge_lv2Extrn = valueStr;
break;
case CB::OPTION_PATH_BRIDGE_LV2_GTK2:
gStandalone.options.bridge_lv2Gtk2 = valueStr;
break;
@@ -666,8 +614,8 @@ void carla_set_engine_option(CarlaOptionsType option, int value, const char* val
#endif

#ifdef WANT_VST
case CB::OPTION_PATH_BRIDGE_VST_COCOA:
gStandalone.options.bridge_vstCocoa = valueStr;
case CB::OPTION_PATH_BRIDGE_VST_MAC:
gStandalone.options.bridge_vstMac = valueStr;
break;
case CB::OPTION_PATH_BRIDGE_VST_HWND:
gStandalone.options.bridge_vstHWND = valueStr;


+ 1
- 2
source/backend/standalone/Makefile View File

@@ -104,7 +104,6 @@ LIBS += ../../modules/carla_native.a
LIBS += ../../modules/juce_core.a
LIBS += ../../modules/juce_audio_basics.a
LIBS += ../../modules/rtmempool.a
LIBS += ../../modules/theme.a

ifeq ($(CARLA_PLUGIN_SUPPORT),true)
LIBS += ../../modules/lilv.a
@@ -149,7 +148,7 @@ debug:
$(CXX) $^ -dynamiclib $(LINK_FLAGS) -framework CoreAudio -framework CoreMIDI -framework CoreFoundation -o $@

../libcarla_standalone.so: $(OBJS) $(LIBS)
$(CXX) $^ -shared $(LINK_FLAGS) -o $@
$(CXX) $^ $(LINK_FLAGS) -o $@ # -shared

# --------------------------------------------------------------



+ 7
- 6
source/modules/CarlaNative.h View File

@@ -53,12 +53,13 @@ typedef enum {

typedef enum {
PLUGIN_IS_RTSAFE = 1 << 0,
PLUGIN_IS_SYNTH = 1 << 1,
PLUGIN_HAS_GUI = 1 << 2,
PLUGIN_USES_PANNING = 1 << 3, // uses stereo balance if unset (default)
PLUGIN_USES_SINGLE_THREAD = 1 << 4,
PLUGIN_USES_STATE = 1 << 5,
PLUGIN_USES_STATIC_BUFFERS = 1 << 6
PLUGIN_HAS_GUI = 1 << 1,
PLUGIN_NEEDS_OPENSAVE = 1 << 2,
PLUGIN_NEEDS_SINGLE_THREAD = 1 << 3,
PLUGIN_NEEDS_FIXED_BUFFERS = 1 << 4,
PLUGIN_USES_PANNING = 1 << 5, // uses stereo balance if unset (default)
PLUGIN_USES_STATE = 1 << 6,
PLUGIN_USES_TIMEPOS = 1 << 7
} PluginHints;

typedef enum {


+ 1
- 1
source/modules/carla_native/audio-file.cpp View File

@@ -245,7 +245,7 @@ private:

static const PluginDescriptor audiofileDesc = {
/* category */ PLUGIN_CATEGORY_UTILITY,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI|PLUGIN_NEEDS_OPENSAVE),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 0,
/* audioOuts */ 2,


+ 1
- 4
source/modules/carla_native/bypass.c View File

@@ -24,10 +24,7 @@
static PluginHandle bypass_instantiate(const HostDescriptor* host)
{
// dummy, return non-NULL
return (PluginHandle)0x1;

// unused
(void)host;
return (PluginHandle)host;
}

static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)


+ 2
- 2
source/modules/carla_native/distrho-nekobi.cpp View File

@@ -30,8 +30,8 @@ START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------

static const PluginDescriptor nekobiDesc = {
/* category */ PLUGIN_CATEGORY_EQ,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_IS_SYNTH|PLUGIN_HAS_GUI),
/* category */ PLUGIN_CATEGORY_SYNTH,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI),
/* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_CONTROL_CHANGES|PLUGIN_SUPPORTS_ALL_SOUND_OFF),
/* audioIns */ DISTRHO_PLUGIN_NUM_INPUTS,
/* audioOuts */ DISTRHO_PLUGIN_NUM_OUTPUTS,


+ 1
- 1
source/modules/carla_native/lfo.c View File

@@ -268,7 +268,7 @@ static void lfo_process(PluginHandle handle, float** inBuffer, float** outBuffer

static const PluginDescriptor lfoDesc = {
.category = PLUGIN_CATEGORY_UTILITY,
.hints = PLUGIN_IS_RTSAFE,
.hints = PLUGIN_IS_RTSAFE|PLUGIN_USES_TIMEPOS,
.supports = 0x0,
.audioIns = 0,
.audioOuts = 0,


+ 1
- 1
source/modules/carla_native/midi-file.cpp View File

@@ -220,7 +220,7 @@ private:

static const PluginDescriptor midifileDesc = {
/* category */ PLUGIN_CATEGORY_UTILITY,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_HAS_GUI|PLUGIN_NEEDS_OPENSAVE),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 0,
/* audioOuts */ 0,


+ 1
- 1
source/modules/carla_native/midi-gain.c View File

@@ -193,7 +193,7 @@ static void midiGain_process(PluginHandle handle, float** inBuffer, float** outB

if (value <= 0.0f)
tmpEvent.data[2] = 0;
else if (value >= 1.27f)
else if (value >= 127.0f)
tmpEvent.data[2] = 127;
else
tmpEvent.data[2] = (uint8_t)value;


+ 24
- 19
source/modules/carla_native/vex.cpp View File

@@ -232,23 +232,28 @@ protected:
}

const TimeInfo* const timeInfo(getTimeInfo());
double ppqPos, barStartPos, bpm;

if (timeInfo->bbt.valid)
{
ppqPos = 0.0;
barStartPos = 0.0;
bpm = timeInfo->bbt.beatsPerMinute;
}
else
int timeFrame = 0;
bool timePlaying = false;
double ppqPos = 0.0;
double barStartPos = 0.0;
double bpm = 120.0;
if (timeInfo != nullptr)
{
double ppqBar = double(timeInfo->bbt.bar - 1) * timeInfo->bbt.beatsPerBar;
double ppqBeat = double(timeInfo->bbt.beat - 1);
double ppqTick = double(timeInfo->bbt.tick) / timeInfo->bbt.ticksPerBeat;
timeFrame = timeInfo->frame;
timePlaying = timeInfo->playing;

if (timeInfo->bbt.valid)
{
double ppqBar = double(timeInfo->bbt.bar - 1) * timeInfo->bbt.beatsPerBar;
double ppqBeat = double(timeInfo->bbt.beat - 1);
double ppqTick = double(timeInfo->bbt.tick) / timeInfo->bbt.ticksPerBeat;

ppqPos = ppqBar + ppqBeat + ppqTick;
barStartPos = ppqBar;
bpm = 120.0;
ppqPos = ppqBar + ppqBeat + ppqTick;
barStartPos = ppqBar;
bpm = timeInfo->bbt.beatsPerMinute;
}
}

fMidiInBuffer.clear();
@@ -256,10 +261,10 @@ protected:
for (uint32_t i=0; i < midiEventCount; ++i)
{
const MidiEvent* const midiEvent(&midiEvents[i]);
fMidiInBuffer.addEvent(MidiMessage(midiEvent->data, midiEvent->size, midiEvent->time), timeInfo->frame);
fMidiInBuffer.addEvent(MidiMessage(midiEvent->data, midiEvent->size, midiEvent->time), timeFrame);
}

const MidiBuffer& outMidiBuffer(fArp.processMidi(fMidiInBuffer, timeInfo->playing, ppqPos, barStartPos, bpm, frames));
const MidiBuffer& outMidiBuffer(fArp.processMidi(fMidiInBuffer, timePlaying, ppqPos, barStartPos, bpm, frames));

MidiBuffer::Iterator outBufferIterator(outMidiBuffer);
MidiMessage midiMessage(0xf4);
@@ -508,7 +513,7 @@ protected:
carla_copyFloat(outBuffer[1], inBuffer[1], frames);

const TimeInfo* const timeInfo(getTimeInfo());
const double bpm(timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0);
const double bpm((timeInfo != nullptr && timeInfo->bbt.valid) ? timeInfo->bbt.beatsPerMinute : 120.0);

delay.processBlock(outBuffer[0], outBuffer[1], frames, bpm);
}
@@ -808,7 +813,7 @@ private:

static const PluginDescriptor vexArpDesc = {
/* category */ PLUGIN_CATEGORY_UTILITY,
/* hints */ static_cast<PluginHints>(0x0),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_TIMEPOS),
/* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_EVERYTHING),
/* audioIns */ 0,
/* audioOuts */ 0,
@@ -842,7 +847,7 @@ static const PluginDescriptor vexChorusDesc = {

static const PluginDescriptor vexDelayDesc = {
/* category */ PLUGIN_CATEGORY_DELAY,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_TIMEPOS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,


+ 3
- 0
source/modules/carla_native/vex/cVoice.cpp View File

@@ -89,6 +89,9 @@ void VexVoice::updateParameterPtr(const float* const p)
void VexVoice::doProcess(float* outBufferL, float* outBufferR, int bufferSize)
{
if (outBufferL == nullptr || outBufferR == nullptr || bufferSize == 0)
return;
//float resAmt = 0.0;
float A, B;
float amod;


+ 9
- 2
source/modules/carla_native/vex/cWaveRenderer.h View File

@@ -274,37 +274,44 @@ public:
void fillBuffer(float* buffer, int bufferSize, OscSet& o)
{
if (buffer == nullptr || bufferSize == 0)
return;
float tmp;
for (int i = 0; i < bufferSize; ++i)
{
buffer[i] = 0.0f;
float tmp = 0.0f;
int index = roundFloatToInt(o.phase - 0.5f);
float alpha = o.phase - (float)index;
const float conv = 1.0f / 65535.0f;
float sIndex = daTable[index] * conv - 0.5f;
float sIndexp1 = daTable[(index + 1) % tableSize] * conv - 0.5f;
tmp = sIndex + alpha * (sIndexp1 - sIndex);
o.buf[1] = ((tmp - o.buf[1]) * o.cut) + o.buf[1];
o.buf[2] = ((o.buf[1] - o.buf[2]) * o.cut) + o.buf[2];
o.buf[3] = ((o.buf[2] - o.buf[3]) * o.cut) + o.buf[3];
o.buf[0] = ((o.buf[3] - o.buf[0]) * o.cut) + o.buf[0];
tmp = o.buf[0];
buffer[i] += tmp;
o.phase += o.phaseInc;
if (o.phase > (float)tableSize)
o.phase -= (float)tableSize;
tmp = 0.0f;
index = roundFloatToInt(o.phase - 0.5f);
alpha = o.phase - (float)index;
sIndex = daTable[index] * conv - 0.5f;
sIndexp1 = daTable[(index + 1) % tableSize] * conv - 0.5f;
tmp = sIndex + alpha * (sIndexp1 - sIndex);
o.buf[1] = ((tmp - o.buf[1]) * o.cut) + o.buf[1];
o.buf[2] = ((o.buf[1] - o.buf[2]) * o.cut) + o.buf[2];
o.buf[3] = ((o.buf[2] - o.buf[3]) * o.cut) + o.buf[3];
o.buf[0] = ((o.buf[3] - o.buf[0]) * o.cut) + o.buf[0];
tmp = o.buf[0];
buffer[i] += tmp;
o.phase += o.phaseInc;


+ 9
- 9
source/modules/carla_native/zynaddsubfx.cpp View File

@@ -2014,7 +2014,7 @@ private:

static const PluginDescriptor fxAlienWahDesc = {
/* category */ PLUGIN_CATEGORY_MODULATOR,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2031,7 +2031,7 @@ static const PluginDescriptor fxAlienWahDesc = {

static const PluginDescriptor fxChorusDesc = {
/* category */ PLUGIN_CATEGORY_MODULATOR,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2048,7 +2048,7 @@ static const PluginDescriptor fxChorusDesc = {

static const PluginDescriptor fxDistortionDesc = {
/* category */ PLUGIN_CATEGORY_MODULATOR,
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2065,7 +2065,7 @@ static const PluginDescriptor fxDistortionDesc = {

static const PluginDescriptor fxDynamicFilterDesc = {
/* category */ PLUGIN_CATEGORY_FILTER,
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2082,7 +2082,7 @@ static const PluginDescriptor fxDynamicFilterDesc = {

static const PluginDescriptor fxEchoDesc = {
/* category */ PLUGIN_CATEGORY_DELAY,
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_IS_RTSAFE|PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2099,7 +2099,7 @@ static const PluginDescriptor fxEchoDesc = {

static const PluginDescriptor fxPhaserDesc = {
/* category */ PLUGIN_CATEGORY_MODULATOR,
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2116,7 +2116,7 @@ static const PluginDescriptor fxPhaserDesc = {

static const PluginDescriptor fxReverbDesc = {
/* category */ PLUGIN_CATEGORY_DELAY,
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_USES_STATIC_BUFFERS),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_PANNING|PLUGIN_NEEDS_FIXED_BUFFERS),
/* supports */ static_cast<PluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
@@ -2134,9 +2134,9 @@ static const PluginDescriptor fxReverbDesc = {
static const PluginDescriptor zynaddsubfxDesc = {
/* category */ PLUGIN_CATEGORY_SYNTH,
#ifdef WANT_ZYNADDSUBFX_UI
/* hints */ static_cast<PluginHints>(PLUGIN_IS_SYNTH|PLUGIN_HAS_GUI|PLUGIN_USES_STATE),
/* hints */ static_cast<PluginHints>(PLUGIN_HAS_GUI|PLUGIN_USES_STATE),
#else
/* hints */ static_cast<PluginHints>(PLUGIN_IS_SYNTH|PLUGIN_USES_STATE),
/* hints */ static_cast<PluginHints>(PLUGIN_USES_STATE),
#endif
/* supports */ static_cast<PluginSupports>(PLUGIN_SUPPORTS_CONTROL_CHANGES|PLUGIN_SUPPORTS_NOTE_AFTERTOUCH|PLUGIN_SUPPORTS_PITCHBEND|PLUGIN_SUPPORTS_ALL_SOUND_OFF),
/* audioIns */ 0,


+ 15
- 15
source/plugin/Makefile View File

@@ -93,10 +93,10 @@ LIBS += ../modules/dgl.a
endif

ifeq ($(WIN32),true)
TARGETS = carla-native-export.exe
TARGETS = carla-native-lv2-export.exe
TARGETS += carla-native.lv2/carla-native.dll
else
TARGETS = carla-native-export
TARGETS = carla-native-lv2-export
ifeq ($(MACOS),true)
TARGETS += carla-native.lv2/carla-native.dylib
else
@@ -121,31 +121,31 @@ debug:
carla-native-base.cpp.o: carla-native-base.cpp ../modules/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

carla-native-export.cpp.o: carla-native-export.cpp carla-native-base.cpp ../modules/CarlaNative.h
carla-native-lv2.cpp.o: carla-native-lv2.cpp carla-native-base.cpp ../modules/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

carla-native-plugin.cpp.o: carla-native-plugin.cpp carla-native-base.cpp ../modules/CarlaNative.h
carla-native-lv2-export.cpp.o: carla-native-lv2-export.cpp carla-native-base.cpp ../modules/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

# --------------------------------------------------------------

carla-native-export: carla-native-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@
./carla-native-export

carla-native-export.exe: carla-native-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@
./carla-native-export.exe

carla-native.lv2/carla-native.dll: carla-native-plugin.cpp.o $(LIBS)
carla-native.lv2/carla-native.dll: carla-native-lv2.cpp.o $(LIBS)
$(CXX) $^ -shared $(LINK_FLAGS) -o $@

carla-native.lv2/carla-native.dylib: carla-native-plugin.cpp.o $(LIBS)
carla-native.lv2/carla-native.dylib: carla-native-lv2.cpp.o $(LIBS)
$(CXX) $^ -dynamiclib $(LINK_FLAGS) -o $@

carla-native.lv2/carla-native.so: carla-native-plugin.cpp.o $(LIBS)
carla-native.lv2/carla-native.so: carla-native-lv2.cpp.o $(LIBS)
$(CXX) $^ -shared $(LINK_FLAGS) -o $@

carla-native-lv2-export: carla-native-lv2-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@
./carla-native-lv2-export

carla-native-lv2-export.exe: carla-native-lv2-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@
./carla-native-lv2-export.exe

# --------------------------------------------------------------

.FORCE:


+ 5
- 0
source/plugin/carla-native-base.cpp View File

@@ -132,6 +132,11 @@ static PluginListManager sPluginDescsMgr;

void carla_register_native_plugin(const PluginDescriptor* desc)
{
#ifdef CARLA_NATIVE_PLUGIN_LV2
// LV2 MIDI Out and Open/Save are not implemented yet
if (desc->midiOuts > 0 || (desc->hints & PLUGIN_NEEDS_OPENSAVE) != 0)
return;
#endif
sPluginDescsMgr.descs.append(desc);
}



source/plugin/carla-native-export.cpp → source/plugin/carla-native-lv2-export.cpp View File

@@ -15,6 +15,7 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#define CARLA_NATIVE_PLUGIN_LV2
#include "carla-native-base.cpp"

#include "juce_core.h"
@@ -123,34 +124,7 @@ void writeManifestFile()
else
text += "<http://kxstudio.sf.net/carla/plugins/" + label + ">\n";

switch (pluginDesc->category)
{
case PLUGIN_CATEGORY_SYNTH:
text += " a lv2:InstrumentPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_DELAY:
text += " a lv2:DelayPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_EQ:
text += " a lv2:EQPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_FILTER:
text += " a lv2:FilterPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_DYNAMICS:
text += " a lv2:DynamicsPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_MODULATOR:
text += " a lv2:ModulatorPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_UTILITY:
text += " a lv2:UtilityPlugin, lv2:Plugin ;\n";
break;
default:
text += " a lv2:Plugin ;\n";
break;
}

text += " a lv2:Plugin ;\n";
text += " lv2:binary <carla-native" PLUGIN_EXT "> ;\n";
text += " rdfs:seeAlso <" + label + ".ttl> .\n";
text += "\n";
@@ -237,6 +211,37 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
else
text += "<http://kxstudio.sf.net/carla/plugins/" + pluginLabel + ">\n";

// -------------------------------------------------------------------
// Category

switch (pluginDesc->category)
{
case PLUGIN_CATEGORY_SYNTH:
text += " a lv2:InstrumentPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_DELAY:
text += " a lv2:DelayPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_EQ:
text += " a lv2:EQPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_FILTER:
text += " a lv2:FilterPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_DYNAMICS:
text += " a lv2:DynamicsPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_MODULATOR:
text += " a lv2:ModulatorPlugin, lv2:Plugin ;\n";
break;
case PLUGIN_CATEGORY_UTILITY:
text += " a lv2:UtilityPlugin, lv2:Plugin ;\n";
break;
default:
text += " a lv2:Plugin ;\n";
break;
}

// -------------------------------------------------------------------
// Features

@@ -245,7 +250,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)

text += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n";

if (pluginDesc->hints & PLUGIN_USES_STATIC_BUFFERS)
if (pluginDesc->hints & PLUGIN_NEEDS_STATIC_BUFFERS)
text += " <" LV2_BUF_SIZE__fixedBlockLength "> ,\n";

text += " <" LV2_OPTIONS__options "> ,\n";
@@ -262,7 +267,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
text += " ,\n";
text += " <" LV2_STATE__interface ">";

if ((pluginDesc->hints & PLUGIN_IS_SYNTH) == 0)
if (pluginDesc->category != PLUGIN_CATEGORY_SYNTH)
{
text += " ,\n";
text += " <" LV2_PROGRAMS__Interface "> ;\n";
@@ -270,7 +275,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
else
text += " ;\n";
}
else if ((pluginDesc->hints & PLUGIN_IS_SYNTH) == 0)
else if (pluginDesc->category != PLUGIN_CATEGORY_SYNTH)
{
text += " ,\n";
text += " <" LV2_PROGRAMS__Interface "> ;\n";
@@ -292,35 +297,38 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
// -------------------------------------------------------------------
// First MIDI/Time port

text += " lv2:port [\n";
text += " a lv2:InputPort, atom:AtomPort ;\n";
text += " atom:bufferType atom:Sequence ;\n";

if (pluginDesc->midiIns > 0)
if (pluginDesc->midiIns > 0 || (pluginDesc->hints & PLUGIN_USES_TIMEPOS) != 0)
{
text += " atom:supports <" LV2_MIDI__MidiEvent "> ,\n";
text += " <" LV2_TIME__Position "> ;\n";
}
else
{
text += " atom:supports <" LV2_TIME__Position "> ;\n";
}
text += " lv2:port [\n";
text += " a lv2:InputPort, atom:AtomPort ;\n";
text += " atom:bufferType atom:Sequence ;\n";

text += " lv2:designation lv2:control ;\n";
text += " lv2:index " + String(portIndex++) + " ;\n";
if (pluginDesc->midiIns > 0 && (pluginDesc->hints & PLUGIN_USES_TIMEPOS) != 0)
{
text += " atom:supports <" LV2_MIDI__MidiEvent "> ,\n";
text += " <" LV2_TIME__Position "> ;\n";
}
else if (pluginDesc->midiIns > 0)
text += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n";
else
text += " atom:supports <" LV2_TIME__Position "> ;\n";

if (pluginDesc->midiIns > 1)
{
text += " lv2:symbol \"lv2_events_in_1\" ;\n";
text += " lv2:name \"Events Input #1\" ;\n";
}
else
{
text += " lv2:symbol \"lv2_events_in\" ;\n";
text += " lv2:name \"Events Input\" ;\n";
}
text += " lv2:designation lv2:control ;\n";
text += " lv2:index " + String(portIndex++) + " ;\n";

if (pluginDesc->midiIns > 1)
{
text += " lv2:symbol \"lv2_events_in_1\" ;\n";
text += " lv2:name \"Events Input #1\" ;\n";
}
else
{
text += " lv2:symbol \"lv2_events_in\" ;\n";
text += " lv2:name \"Events Input\" ;\n";
}

text += " ] ;\n\n";
text += " ] ;\n\n";
}

// -------------------------------------------------------------------
// MIDI inputs

source/plugin/carla-native-plugin.cpp → source/plugin/carla-native-lv2.cpp View File

@@ -15,6 +15,7 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#define CARLA_NATIVE_PLUGIN_LV2
#include "carla-native-base.cpp"

#include "juce_audio_basics.h"
@@ -30,6 +31,7 @@
#include "lv2/state.h"
#include "lv2/time.h"
#include "lv2/ui.h"
#include "lv2/urid.h"
#include "lv2/lv2_external_ui.h"
#include "lv2/lv2_programs.h"

@@ -58,8 +60,15 @@ public:
show = extui_show;
hide = extui_hide;

CarlaString resourceDir(bundlePath);
#ifdef CARLA_OS_WIN
resourceDir += "\\resources\\";
#else
resourceDir += "/resources/";
#endif

fHost.handle = this;
fHost.resourceDir = carla_strdup(bundlePath);
fHost.resourceDir = resourceDir.dup();
fHost.uiName = nullptr;

fHost.get_buffer_size = host_get_buffer_size;
@@ -74,8 +83,9 @@ public:
fHost.ui_save_file = host_ui_save_file;
fHost.dispatcher = host_dispatcher;

const LV2_Options_Option* options = nullptr;
const LV2_URID_Map* uridMap = nullptr;
const LV2_Options_Option* options = nullptr;
const LV2_URID_Map* uridMap = nullptr;
const LV2_URID_Unmap* uridUnmap = nullptr;

for (int i=0; features[i] != nullptr; ++i)
{
@@ -83,6 +93,8 @@ public:
options = (const LV2_Options_Option*)features[i]->data;
else if (std::strcmp(features[i]->URI, LV2_URID__map) == 0)
uridMap = (const LV2_URID_Map*)features[i]->data;
else if (std::strcmp(features[i]->URI, LV2_URID__unmap) == 0)
uridUnmap = (const LV2_URID_Unmap*)features[i]->data;
}

if (options == nullptr || uridMap == nullptr)
@@ -93,19 +105,34 @@ public:

for (int i=0; options[i].key != 0; ++i)
{
if (uridUnmap != nullptr)
{
carla_debug("Host option %i:\"%s\"", i, uridUnmap->unmap(uridUnmap->handle, options[i].key));
}

if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength))
{
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int))
{
fBufferSize = *(const int*)options[i].value;

if (fBufferSize == 0)
carla_stderr("Host provides maxBlockLength but has null value");
}
else
carla_stderr("Host provides maxBlockLength but has wrong value type");

break;
}
}

fUridMap = uridMap;

fUI.portOffset += (desc->midiIns > 0) ? desc->midiIns : 1;
if (fDescriptor->midiIns > 0)
fUI.portOffset += desc->midiIns;
else if (fDescriptor->hints & PLUGIN_USES_TIMEPOS)
fUI.portOffset += 1;

fUI.portOffset += desc->midiOuts;
fUI.portOffset += 1; // freewheel
fUI.portOffset += desc->audioIns;
@@ -205,125 +232,130 @@ public:
}
}

fMidiEventCount = 0;
carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2);

LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], iter)
if (fDescriptor->midiIns > 0 || (fDescriptor->hints & PLUGIN_USES_TIMEPOS) != 0)
{
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
fMidiEventCount = 0;
carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2);

if (event == nullptr)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;

if (event->body.type == fUris.midiEvent)
LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], iter)
{
if (fMidiEventCount >= kMaxMidiEvents*2)
continue;
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);

const uint8_t* const data((const uint8_t*)(event + 1));
if (event == nullptr)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;

fMidiEvents[fMidiEventCount].port = 0;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;
if (event->body.type == fUris.midiEvent)
{
if (fMidiEventCount >= kMaxMidiEvents*2)
continue;

for (uint32_t i=0; i < event->body.size; ++i)
fMidiEvents[fMidiEventCount].data[i] = data[i];
const uint8_t* const data((const uint8_t*)(event + 1));

fMidiEventCount += 1;
continue;
}
fMidiEvents[fMidiEventCount].port = 0;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;

if (event->body.type == fUris.atomBlank)
{
const LV2_Atom_Object* const obj((LV2_Atom_Object*)&event->body);
for (uint32_t i=0; i < event->body.size; ++i)
fMidiEvents[fMidiEventCount].data[i] = data[i];

if (obj->body.otype != fUris.timePos)
fMidiEventCount += 1;
continue;

LV2_Atom* bar = nullptr;
LV2_Atom* barBeat = nullptr;
LV2_Atom* beatsPerBar = nullptr;
LV2_Atom* bpm = nullptr;
LV2_Atom* beatUnit = nullptr;
LV2_Atom* frame = nullptr;
LV2_Atom* speed = nullptr;

lv2_atom_object_get(obj,
fUris.timeBar, &bar,
fUris.timeBarBeat, &barBeat,
fUris.timeBeatsPerBar, &beatsPerBar,
fUris.timeBeatsPerMinute, &bpm,
fUris.timeBeatUnit, &beatUnit,
fUris.timeFrame, &frame,
fUris.timeSpeed, &speed,
nullptr);

if (bpm != nullptr && bpm->type == fUris.atomFloat)
{
fTimeInfo.bbt.beatsPerMinute = ((LV2_Atom_Float*)bpm)->body;
fTimeInfo.bbt.valid = true;
}

if (beatsPerBar != nullptr && beatsPerBar->type == fUris.atomFloat)
if (event->body.type == fUris.atomBlank)
{
float beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
fTimeInfo.bbt.beatsPerBar = beatsPerBarValue;
const LV2_Atom_Object* const obj((LV2_Atom_Object*)&event->body);

if (obj->body.otype != fUris.timePos)
continue;

LV2_Atom* bar = nullptr;
LV2_Atom* barBeat = nullptr;
LV2_Atom* beatsPerBar = nullptr;
LV2_Atom* bpm = nullptr;
LV2_Atom* beatUnit = nullptr;
LV2_Atom* frame = nullptr;
LV2_Atom* speed = nullptr;

lv2_atom_object_get(obj,
fUris.timeBar, &bar,
fUris.timeBarBeat, &barBeat,
fUris.timeBeatsPerBar, &beatsPerBar,
fUris.timeBeatsPerMinute, &bpm,
fUris.timeBeatUnit, &beatUnit,
fUris.timeFrame, &frame,
fUris.timeSpeed, &speed,
nullptr);

if (bpm != nullptr && bpm->type == fUris.atomFloat)
{
fTimeInfo.bbt.beatsPerMinute = ((LV2_Atom_Float*)bpm)->body;
fTimeInfo.bbt.valid = true;
}

if (bar != nullptr && bar->type == fUris.atomLong)
if (beatsPerBar != nullptr && beatsPerBar->type == fUris.atomFloat)
{
//float barValue = ((LV2_Atom_Long*)bar)->body;
//curPosInfo.ppqPositionOfLastBarStart = barValue * beatsPerBarValue;
float beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
fTimeInfo.bbt.beatsPerBar = beatsPerBarValue;

if (barBeat != nullptr && barBeat->type == fUris.atomFloat)
if (bar != nullptr && bar->type == fUris.atomLong)
{
//float barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
//curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + barBeatValue;
//float barValue = ((LV2_Atom_Long*)bar)->body;
//curPosInfo.ppqPositionOfLastBarStart = barValue * beatsPerBarValue;

if (barBeat != nullptr && barBeat->type == fUris.atomFloat)
{
//float barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
//curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + barBeatValue;
}
}
}
}

if (beatUnit != nullptr && beatUnit->type == fUris.atomFloat)
fTimeInfo.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;
if (beatUnit != nullptr && beatUnit->type == fUris.atomFloat)
fTimeInfo.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;

if (frame != nullptr && frame->type == fUris.atomLong)
fTimeInfo.frame = ((LV2_Atom_Long*)frame)->body;

if (frame != nullptr && frame->type == fUris.atomLong)
fTimeInfo.frame = ((LV2_Atom_Long*)frame)->body;
if (speed != nullptr && speed->type == fUris.atomFloat)
fTimeInfo.playing = ((LV2_Atom_Float*)speed)->body == 1.0f;

if (speed != nullptr && speed->type == fUris.atomFloat)
fTimeInfo.playing = ((LV2_Atom_Float*)speed)->body == 1.0f;
continue;
}
}
}

for (uint32_t i=1; i < fDescriptor->midiIns; ++i)
{
LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], iter)
for (uint32_t i=1; i < fDescriptor->midiIns; ++i)
{
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], iter)
{
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);

if (event == nullptr)
continue;
if (event->body.type != fUris.midiEvent)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;
if (fMidiEventCount >= kMaxMidiEvents*2)
break;
if (event == nullptr)
continue;
if (event->body.type != fUris.midiEvent)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;
if (fMidiEventCount >= kMaxMidiEvents*2)
break;

const uint8_t* const data((const uint8_t*)(event + 1));
const uint8_t* const data((const uint8_t*)(event + 1));

fMidiEvents[fMidiEventCount].port = i;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;
fMidiEvents[fMidiEventCount].port = i;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;

for (uint32_t j=0; j < event->body.size; ++j)
fMidiEvents[fMidiEventCount].data[j] = data[j];
for (uint32_t j=0; j < event->body.size; ++j)
fMidiEvents[fMidiEventCount].data[j] = data[j];

fMidiEventCount += 1;
fMidiEventCount += 1;
}
}
}

@@ -392,9 +424,9 @@ public:
return LV2_OPTIONS_SUCCESS;
}

const LV2_Program_Descriptor* lv2_get_program(const uint32_t index) const
const LV2_Program_Descriptor* lv2_get_program(const uint32_t index)
{
if (fDescriptor->hints & PLUGIN_IS_SYNTH)
if (fDescriptor->category == PLUGIN_CATEGORY_SYNTH)
return nullptr;
if (fDescriptor->get_midi_program_count == nullptr)
return nullptr;
@@ -408,18 +440,16 @@ public:
if (midiProg == nullptr)
return nullptr;

static LV2_Program_Descriptor progDesc;

progDesc.bank = midiProg->bank;
progDesc.program = midiProg->program;
progDesc.name = midiProg->name;
fProgramDesc.bank = midiProg->bank;
fProgramDesc.program = midiProg->program;
fProgramDesc.name = midiProg->name;

return &progDesc;
return &fProgramDesc;
}

void lv2_select_program(uint32_t bank, uint32_t program)
{
if (fDescriptor->hints & PLUGIN_IS_SYNTH)
if (fDescriptor->category == PLUGIN_CATEGORY_SYNTH)
return;
if (fDescriptor->set_midi_program == nullptr)
return;
@@ -430,17 +460,12 @@ public:
LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle, const uint32_t /*flags*/, const LV2_Feature* const* const /*features*/) const
{
if ((fDescriptor->hints & PLUGIN_USES_STATE) == 0 || fDescriptor->get_state == nullptr)
return LV2_STATE_ERR_UNKNOWN;
return LV2_STATE_ERR_NO_FEATURE;

if (char* const state = fDescriptor->get_state(fHandle))
{
store(handle,
fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"),
state,
std::strlen(state),
fUridMap->map(fUridMap->handle, LV2_ATOM__String),
LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);

store(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), state, std::strlen(state), fUris.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);
std::free(state);
return LV2_STATE_SUCCESS;
}

@@ -450,7 +475,7 @@ public:
LV2_State_Status lv2_restore(const LV2_State_Retrieve_Function retrieve, const LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* const /*features*/) const
{
if ((fDescriptor->hints & PLUGIN_USES_STATE) == 0 || fDescriptor->set_state == nullptr)
return LV2_STATE_ERR_UNKNOWN;
return LV2_STATE_ERR_NO_FEATURE;

size_t size = 0;
uint32_t type = 0;
@@ -462,7 +487,7 @@ public:
return LV2_STATE_ERR_UNKNOWN;
if (data == nullptr)
return LV2_STATE_ERR_UNKNOWN;
if (type != fUridMap->map(fUridMap->handle, LV2_ATOM__String))
if (type != fUris.atomString)
return LV2_STATE_ERR_BAD_TYPE;

fDescriptor->set_state(fHandle, (const char*)data);
@@ -472,8 +497,7 @@ public:

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

bool lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget,
const LV2_Feature* const* features)
bool lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features)
{
for (int i=0; features[i] != nullptr; ++i)
{
@@ -529,7 +553,7 @@ public:

void lv2ui_select_program(uint32_t bank, uint32_t program) const
{
if (fDescriptor->hints & PLUGIN_IS_SYNTH)
if (fDescriptor->category == PLUGIN_CATEGORY_SYNTH)
return;
if (fDescriptor->ui_set_midi_program == nullptr)
return;
@@ -608,13 +632,13 @@ protected:
return false;
}

void handleUiParameterChanged(const uint32_t index, const float value)
void handleUiParameterChanged(const uint32_t index, const float value) const
{
if (fUI.writeFunction != nullptr && fUI.controller != nullptr)
fUI.writeFunction(fUI.controller, index+fUI.portOffset, sizeof(float), 0, &value);
}

void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/)
void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) const
{
//storeCustomData(key, value);
}
@@ -707,12 +731,13 @@ private:
PluginHandle fHandle;
HostDescriptor fHost;
const PluginDescriptor* const fDescriptor;
LV2_Program_Descriptor fProgramDesc;

uint32_t fMidiEventCount;
MidiEvent fMidiEvents[kMaxMidiEvents*2];
TimeInfo fTimeInfo;

bool fIsProcessing;
bool fIsProcessing;
float fVolume;
float fDryWet;

@@ -727,6 +752,7 @@ private:
LV2_URID atomFloat;
LV2_URID atomLong;
LV2_URID atomSequence;
LV2_URID atomString;
LV2_URID midiEvent;
LV2_URID timePos;
LV2_URID timeBar;
@@ -742,6 +768,7 @@ private:
atomFloat(0),
atomLong(0),
atomSequence(0),
atomString(0),
midiEvent(0),
timePos(0),
timeBar(0),
@@ -758,6 +785,7 @@ private:
atomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float);
atomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long);
atomSequence = uridMap->map(uridMap->handle, LV2_ATOM__Sequence);
atomString = uridMap->map(uridMap->handle, LV2_ATOM__String);
midiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent);
timePos = uridMap->map(uridMap->handle, LV2_TIME__Position);
timeBar = uridMap->map(uridMap->handle, LV2_TIME__bar);
@@ -855,7 +883,7 @@ private:
for (uint32_t i=0; i < desc->midiIns; ++i)
eventsIn[i] = nullptr;
}
else
else if (desc->hints & PLUGIN_USES_TIMEPOS)
{
eventsIn = new LV2_Atom_Sequence*[1];
eventsIn[0] = nullptr;
@@ -907,10 +935,13 @@ private:
{
uint32_t index = 0;

if (port == index++)
if (desc->midiIns > 0 || (desc->hints & PLUGIN_USES_TIMEPOS) != 0)
{
eventsIn[0] = (LV2_Atom_Sequence*)dataLocation;
return;
if (port == index++)
{
eventsIn[0] = (LV2_Atom_Sequence*)dataLocation;
return;
}
}

for (uint32_t i=1; i < desc->midiIns; ++i)
@@ -964,7 +995,6 @@ private:
}
}
}

} fPorts;

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

+ 6
- 4
source/utils/CarlaBackendUtils.hpp View File

@@ -30,8 +30,8 @@ const char* PluginOption2Str(const unsigned int option)
{
switch (option)
{
case PLUGIN_OPTION_FIXED_BUFFER:
return "PLUGIN_OPTION_FIXED_BUFFER";
case PLUGIN_OPTION_FIXED_BUFFERS:
return "PLUGIN_OPTION_FIXED_BUFFERS";
case PLUGIN_OPTION_FORCE_STEREO:
return "PLUGIN_OPTION_FORCE_STEREO";
case PLUGIN_OPTION_MAP_PROGRAM_CHANGES:
@@ -247,6 +247,8 @@ const char* OptionsType2Str(const OptionsType option)
return "OPTION_PATH_BRIDGE_WIN64";
#endif
#ifdef WANT_LV2
case OPTION_PATH_BRIDGE_LV2_EXTERNAL:
return "OPTION_PATH_BRIDGE_LV2_EXTERNAL";
case OPTION_PATH_BRIDGE_LV2_GTK2:
return "OPTION_PATH_BRIDGE_LV2_GTK2";
case OPTION_PATH_BRIDGE_LV2_GTK3:
@@ -263,8 +265,8 @@ const char* OptionsType2Str(const OptionsType option)
return "OPTION_PATH_BRIDGE_LV2_X11";
#endif
#ifdef WANT_VST
case OPTION_PATH_BRIDGE_VST_COCOA:
return "OPTION_PATH_BRIDGE_VST_COCOA";
case OPTION_PATH_BRIDGE_VST_MAC:
return "OPTION_PATH_BRIDGE_VST_MAC";
case OPTION_PATH_BRIDGE_VST_HWND:
return "OPTION_PATH_BRIDGE_VST_HWND";
case OPTION_PATH_BRIDGE_VST_X11:


+ 8
- 0
source/utils/CarlaJuceUtils.hpp View File

@@ -22,6 +22,14 @@

#include "juce_core.h"

#define juce_foreach(type, array) \
type* iter = array.getRawDataPointer(); \
for (int _i=0, _size=array.size(); _i < _size; ++_i, ++iter)

#define juce_foreach_const(type, array) \
const type* iter = array.getRawDataPointer(); \
for (int _i=0, _size=array.size(); _i < _size; ++_i, ++iter)

#define CARLA_PREVENT_HEAP_ALLOCATION \
JUCE_PREVENT_HEAP_ALLOCATION



+ 65
- 68
source/utils/CarlaStateUtils.hpp View File

@@ -22,11 +22,10 @@
#include "CarlaMIDI.h"
#include "RtList.hpp"

#if 1
#if 0
# include <QtXml/QDomNode>
#else
# include "juce_core/AppConfig.h"
# include "juce_core/juce_core.h"
# include "juce_core.h"
using juce::String;
#endif

@@ -219,7 +218,7 @@ struct SaveState {

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

#if 1
#if 0
static inline
QString xmlSafeString(const QString& string, const bool toXml)
{
@@ -257,11 +256,10 @@ const char* xmlSafeStringCharDup(const String& string, const bool toXml)

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

#if 0
static inline
void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode)
{
saveState.reset();

if (xmlNode.isNull())
return;

@@ -467,109 +465,108 @@ void fillSaveStateFromXmlNode(SaveState& saveState, const QDomNode& xmlNode)
}
}
}
#endif

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

static inline
void fillXmlStringFromSaveState(QString& content, const SaveState& saveState)
void fillXmlStringFromSaveState(String& content, const SaveState& saveState)
{
content.clear();

{
QString info(" <Info>\n");
String info(" <Info>\n");

info += QString(" <Type>%1</Type>\n").arg(saveState.type);
info += QString(" <Name>%1</Name>\n").arg(xmlSafeString(saveState.name, true));
info << " <Type>" << saveState.type << "</Type>\n";
info << " <Name>" << xmlSafeString(saveState.name, true) << "</Name>\n";

switch (getPluginTypeFromString(saveState.type))
{
case PLUGIN_NONE:
break;
case PLUGIN_INTERNAL:
info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true));
info << " <Label>" << xmlSafeString(saveState.label, true) << "</Label>\n";
break;
case PLUGIN_LADSPA:
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true));
info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true));
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID);
info << " <Binary>" << xmlSafeString(saveState.binary, true) << "</Binary>\n";
info << " <Label>" << xmlSafeString(saveState.label, true) << "</Label>\n";
info << " <UniqueID>" << saveState.uniqueID << "</UniqueID>\n";
break;
case PLUGIN_DSSI:
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true));
info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true));
info << " <Binary>" << xmlSafeString(saveState.binary, true) << "</Binary>\n";
info << " <Label>" << xmlSafeString(saveState.label, true) << "</Label>\n";
break;
case PLUGIN_LV2:
info += QString(" <URI>%1</URI>\n").arg(xmlSafeString(saveState.label, true));
info << " <URI>" << xmlSafeString(saveState.label, true) << "</URI>\n";
break;
case PLUGIN_VST:
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true));
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID);
info << " <Binary>" << xmlSafeString(saveState.binary, true) << "</Binary>\n";
info << " <UniqueID>" << saveState.uniqueID << "</UniqueID>\n";
break;
case PLUGIN_AU:
// TODO?
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true));
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID);
info << " <Binary>" << xmlSafeString(saveState.binary, true) << "</Binary>\n";
info << " <UniqueID>" << saveState.uniqueID << "</UniqueID>\n";
break;
case PLUGIN_CSOUND:
case PLUGIN_GIG:
case PLUGIN_SF2:
case PLUGIN_SFZ:
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true));
info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true));
info << " <Binary>" << xmlSafeString(saveState.binary, true) << "</Binary>\n";
info << " <Label>" << xmlSafeString(saveState.label, true) << "</Label>\n";
break;
}

info += " </Info>\n\n";
info << " </Info>\n\n";

content += info;
content << info;
}

{
QString data(" <Data>\n");
String data(" <Data>\n");

data += QString(" <Active>%1</Active>\n").arg(saveState.active ? "Yes" : "No");
data << " <Active>" << (saveState.active ? "Yes" : "No") << "</Active>\n";

if (saveState.dryWet != 1.0f)
data += QString(" <DryWet>%1</DryWet>\n").arg(saveState.dryWet);
data << " <DryWet>" << saveState.dryWet << "</DryWet>\n";
if (saveState.volume != 1.0f)
data += QString(" <Volume>%1</Volume>\n").arg(saveState.volume);
data << " <Volume>" << saveState.volume << "</Volume>\n";
if (saveState.balanceLeft != -1.0f)
data += QString(" <Balance-Left>%1</Balance-Left>\n").arg(saveState.balanceLeft);
data << " <Balance-Left>" << saveState.balanceLeft << "</Balance-Left>\n";
if (saveState.balanceRight != 1.0f)
data += QString(" <Balance-Right>%1</Balance-Right>\n").arg(saveState.balanceRight);
data << " <Balance-Right>" << saveState.balanceRight << "</Balance-Right>\n";
if (saveState.panning != 0.0f)
data += QString(" <Panning>%1</Panning>\n").arg(saveState.panning);
data << " <Panning>" << saveState.panning << "</Panning>\n";

if (saveState.ctrlChannel < 0)
data += QString(" <ControlChannel>N</ControlChannel>\n");
data << " <ControlChannel>N</ControlChannel>\n";
else
data += QString(" <ControlChannel>%1</ControlChannel>\n").arg(saveState.ctrlChannel+1);
data << " <ControlChannel>" << saveState.ctrlChannel+1 << "</ControlChannel>\n";

content += data;
content << data;
}

for (StateParameterItenerator it = saveState.parameters.begin(); it.valid(); it.next())
{
StateParameter* const stateParameter(*it);

QString parameter("\n"" <Parameter>\n");
String parameter("\n"" <Parameter>\n");

parameter += QString(" <Index>%1</Index>\n").arg(stateParameter->index);
parameter += QString(" <Name>%1</Name>\n").arg(xmlSafeString(stateParameter->name, true));
parameter << " <Index>" << (long)stateParameter->index << "</Index>\n"; // FIXME
parameter << " <Name>" << xmlSafeString(stateParameter->name, true) << "</Name>\n";

if (stateParameter->symbol != nullptr && *stateParameter->symbol != '\0')
parameter += QString(" <Symbol>%1</Symbol>\n").arg(xmlSafeString(stateParameter->symbol, true));
parameter << " <Symbol>" << xmlSafeString(stateParameter->symbol, true) << "</Symbol>\n";

parameter += QString(" <Value>%1</Value>\n").arg(stateParameter->value);
parameter << " <Value>" << stateParameter->value << "</Value>\n";

if (stateParameter->midiCC > 0)
{
parameter += QString(" <MidiCC>%1</MidiCC>\n").arg(stateParameter->midiCC);
parameter += QString(" <MidiChannel>%1</MidiChannel>\n").arg(stateParameter->midiChannel+1);
parameter << " <MidiCC>" << stateParameter->midiCC << "</MidiCC>\n";
parameter << " <MidiChannel>" << stateParameter->midiChannel+1 << "</MidiChannel>\n";
}

parameter += " </Parameter>\n";
parameter << " </Parameter>\n";

content += parameter;
content << parameter;
}

if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr)
@@ -581,55 +578,55 @@ void fillXmlStringFromSaveState(QString& content, const SaveState& saveState)
if ((saveState.currentProgramIndex > 0 || std::strcmp(saveState.currentProgramName, "Default") != 0))
#endif
{
QString program("\n");
program += QString(" <CurrentProgramIndex>%1</CurrentProgramIndex>\n").arg(saveState.currentProgramIndex+1);
program += QString(" <CurrentProgramName>%1</CurrentProgramName>\n").arg(xmlSafeString(saveState.currentProgramName, true));
String program("\n");
program << " <CurrentProgramIndex>" << saveState.currentProgramIndex+1 << "</CurrentProgramIndex>\n";
program << " <CurrentProgramName>" << xmlSafeString(saveState.currentProgramName, true) << "</CurrentProgramName>\n";

content += program;
content << program;
}
}

if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0)
{
QString midiProgram("\n");
midiProgram += QString(" <CurrentMidiBank>%1</CurrentMidiBank>\n").arg(saveState.currentMidiBank+1);
midiProgram += QString(" <CurrentMidiProgram>%1</CurrentMidiProgram>\n").arg(saveState.currentMidiProgram+1);
String midiProgram("\n");
midiProgram << " <CurrentMidiBank>" << saveState.currentMidiBank+1 << "</CurrentMidiBank>\n";
midiProgram << " <CurrentMidiProgram>" << saveState.currentMidiProgram+1 << "</CurrentMidiProgram>\n";

content += midiProgram;
content << midiProgram;
}

for (StateCustomDataItenerator it = saveState.customData.begin(); it.valid(); it.next())
{
StateCustomData* const stateCustomData(*it);

QString customData("\n"" <CustomData>\n");
customData += QString(" <Type>%1</Type>\n").arg(xmlSafeString(stateCustomData->type, true));
customData += QString(" <Key>%1</Key>\n").arg(xmlSafeString(stateCustomData->key, true));
String customData("\n"" <CustomData>\n");
customData << " <Type>" << xmlSafeString(stateCustomData->type, true) << "</Type>\n";
customData << " <Key>" << xmlSafeString(stateCustomData->key, true) << "</Key>\n";

if (std::strcmp(stateCustomData->type, CUSTOM_DATA_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128)
{
customData += " <Value>\n";
customData += QString("%1\n").arg(xmlSafeString(stateCustomData->value, true));
customData += " </Value>\n";
customData << " <Value>\n";
customData << "" << xmlSafeString(stateCustomData->value, true) << "\n";
customData << " </Value>\n";
}
else
customData += QString(" <Value>%1</Value>\n").arg(xmlSafeString(stateCustomData->value, true));
customData << " <Value>" << xmlSafeString(stateCustomData->value, true) << "</Value>\n";

customData += " </CustomData>\n";
customData << " </CustomData>\n";

content += customData;
content << customData;
}

if (saveState.chunk != nullptr && *saveState.chunk != '\0')
{
QString chunk("\n"" <Chunk>\n");
chunk += QString("%1\n").arg(saveState.chunk);
chunk += " </Chunk>\n";
String chunk("\n"" <Chunk>\n");
chunk << "" << saveState.chunk << "\n";
chunk << " </Chunk>\n";

content += chunk;
content << chunk;
}

content += " </Data>\n";
content << " </Data>\n";
}

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


+ 5
- 0
source/utils/CarlaString.hpp View File

@@ -334,6 +334,11 @@ public:
#endif
}

const char* dup() const
{
return carla_strdup(fBuffer);
}

// -------------------------------------------------------------------
// public operators



+ 6
- 6
source/utils/RtList.hpp View File

@@ -28,12 +28,12 @@ extern "C" {
}

// Declare non copyable and prevent heap allocation
#define LIST_DECLARATIONS(ClassName) \
ClassName(ClassName&); \
ClassName(const ClassName&); \
ClassName& operator=(const ClassName&); \
static void* operator new (size_t) { return nullptr; } \
static void operator delete (void*) {}
#define LIST_DECLARATIONS(ClassName) \
ClassName(ClassName&) = delete; \
ClassName(const ClassName&) = delete; \
ClassName& operator=(const ClassName&) = delete; \
static void* operator new(size_t) = delete;
//static void operator delete(void*) = delete; // FIXME?

typedef struct list_head k_list_head;



Loading…
Cancel
Save