@@ -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 | |||
@@ -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 | |||
@@ -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; | |||
@@ -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); | |||
@@ -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() | |||
@@ -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 | |||
@@ -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 | |||
@@ -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 $@ $^ | |||
@@ -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 +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(); | |||
@@ -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 |
@@ -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 |
@@ -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; | |||
@@ -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; | |||
@@ -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; | |||
@@ -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; | |||
@@ -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; | |||
// } | |||
} | |||
// --------------------------------------------------------------- | |||
@@ -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 | |||
@@ -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 | |||
# -------------------------------------------------------------- | |||
@@ -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; | |||
@@ -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; | |||
@@ -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; | |||
@@ -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 | |||
# -------------------------------------------------------------- | |||
@@ -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 { | |||
@@ -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, | |||
@@ -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) | |||
@@ -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, | |||
@@ -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, | |||
@@ -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, | |||
@@ -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; | |||
@@ -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, | |||
@@ -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; | |||
@@ -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; | |||
@@ -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, | |||
@@ -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: | |||
@@ -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); | |||
} | |||
@@ -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 |
@@ -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; | |||
// ------------------------------------------------------------------- |
@@ -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: | |||
@@ -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 | |||
@@ -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"; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -334,6 +334,11 @@ public: | |||
#endif | |||
} | |||
const char* dup() const | |||
{ | |||
return carla_strdup(fBuffer); | |||
} | |||
// ------------------------------------------------------------------- | |||
// public operators | |||
@@ -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; | |||