@@ -4,34 +4,36 @@ | |||||
# Created by falkTX | # Created by falkTX | ||||
# | # | ||||
# backend ouput driver, default JACK | |||||
driver = JACK | |||||
# driver = RtAudio | |||||
CC ?= gcc | CC ?= gcc | ||||
CXX ?= g++ | CXX ?= g++ | ||||
BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -Wall -I. -I../carla-includes | BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -Wall -I. -I../carla-includes | ||||
HAVE_JACK = $(shell pkg-config --exists jack && echo true) | |||||
HAVE_RTAUDIO = $(shell pkg-config --exists rtaudio && echo true) # FIXME - needs proper check | |||||
HAVE_FLUIDSYNTH = $(shell pkg-config --exists fluidsynth && echo true) | HAVE_FLUIDSYNTH = $(shell pkg-config --exists fluidsynth && echo true) | ||||
HAVE_LINUXSAMPLER = $(shell pkg-config --exists linuxsampler && echo true) | |||||
HAVE_LINUXSAMPLER = $(shell pkg-config --exists linuxsamplerXXX && echo true) | |||||
HAVE_SUIL = $(shell pkg-config --exists suil-0 && echo true) | HAVE_SUIL = $(shell pkg-config --exists suil-0 && echo true) | ||||
CARLA_C_FLAGS = $(BASE_FLAGS) $(CFLAGS) | CARLA_C_FLAGS = $(BASE_FLAGS) $(CFLAGS) | ||||
CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) | CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) | ||||
CARLA_CXX_FLAGS += $(shell pkg-config --cflags jack liblo QtCore QtGui) -DCARLA_BACKEND_NO_NAMESPACE | |||||
ifeq ($(driver),JACK) | |||||
CARLA_CXX_FLAGS += -DCARLA_ENGINE_JACK | |||||
endif | |||||
ifeq ($(driver),RtAudio) | |||||
CARLA_CXX_FLAGS += -DCARLA_ENGINE_RTAUDIO -D_FORTIFY_SOURCE=2 -DHAVE_GETTIMEOFDAY -D__LINUX_ALSA__ -D__LINUX_PULSE__ | |||||
endif | |||||
CARLA_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtGui) | |||||
CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT | CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT | ||||
CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | |||||
# CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | |||||
CARLA_LD_FLAGS = -shared -ldl -lm -fPIC $(LDFLAGS) | |||||
CARLA_LD_FLAGS += $(shell pkg-config --libs liblo QtCore QtGui) | |||||
CARLA_LD_FLAGS = -shared -ldl -fPIC $(LDFLAGS) | |||||
CARLA_LD_FLAGS += $(shell pkg-config --libs jack liblo QtCore QtGui) | |||||
ifeq ($(HAVE_JACK),true) | |||||
CARLA_CXX_FLAGS += $(shell pkg-config --cflags jack) -DCARLA_ENGINE_JACK | |||||
CARLA_LD_FLAGS += $(shell pkg-config --libs jack) | |||||
endif | |||||
ifeq ($(HAVE_RTAUDIO),true) | |||||
CARLA_CXX_FLAGS += $(shell rtaudio-config --cppflags) -DCARLA_ENGINE_RTAUDIO | |||||
CARLA_LD_FLAGS += $(shell rtaudio-config --libs) | |||||
endif | |||||
ifeq ($(HAVE_FLUIDSYNTH),true) | ifeq ($(HAVE_FLUIDSYNTH),true) | ||||
CARLA_CXX_FLAGS += $(shell pkg-config --cflags fluidsynth) -DWANT_FLUIDSYNTH | CARLA_CXX_FLAGS += $(shell pkg-config --cflags fluidsynth) -DWANT_FLUIDSYNTH | ||||
@@ -49,8 +51,9 @@ CARLA_LD_FLAGS += $(shell pkg-config --libs suil-0) | |||||
endif | endif | ||||
OBJS = \ | OBJS = \ | ||||
carla_backend.o \ | |||||
carla_backend_standalone.o \ | |||||
carla_bridge.o \ | carla_bridge.o \ | ||||
carla_engine.o \ | |||||
carla_engine_jack.o \ | carla_engine_jack.o \ | ||||
carla_engine_rtaudio.o \ | carla_engine_rtaudio.o \ | ||||
carla_osc.o \ | carla_osc.o \ | ||||
@@ -60,11 +63,11 @@ OBJS = \ | |||||
lv2-rtmempool/rtmempool.o \ | lv2-rtmempool/rtmempool.o \ | ||||
../carla-lilv/carla_lilv.a | ../carla-lilv/carla_lilv.a | ||||
ifeq ($(driver),RtAudio) | |||||
OBJS += rtaudio/rtaudio-4.0.11/RtAudio.o | |||||
CARLA_CXX_FLAGS += $(shell pkg-config --cflags alsa libpulse-simple) -Irtaudio/rtaudio-4.0.11 | |||||
CARLA_LD_FLAGS += $(shell pkg-config --libs alsa libpulse-simple) | |||||
endif | |||||
# ifeq ($(driver),RtAudio) | |||||
# OBJS += rtaudio/rtaudio-4.0.11/RtAudio.o | |||||
# CARLA_CXX_FLAGS += $(shell pkg-config --cflags alsa libpulse-simple) -Irtaudio/rtaudio-4.0.11 | |||||
# CARLA_LD_FLAGS += $(shell pkg-config --libs alsa libpulse-simple) | |||||
# endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
@@ -148,9 +148,7 @@ bool engine_close() | |||||
} | } | ||||
bool closed = carla_engine->close(); | bool closed = carla_engine->close(); | ||||
for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++) | |||||
remove_plugin(i); | |||||
carla_engine->removeAllPlugins(); | |||||
// cleanup static data | // cleanup static data | ||||
get_plugin_info(0); | get_plugin_info(0); | ||||
@@ -1142,8 +1140,6 @@ QDialog* gui; | |||||
void main_callback(CarlaBackend::CallbackType action, unsigned short plugin_id, int value1, int value2, double value3) | void main_callback(CarlaBackend::CallbackType action, unsigned short plugin_id, int value1, int value2, double value3) | ||||
{ | { | ||||
qDebug("Callback(%i, %u, %i, %i, %f)", action, plugin_id, value1, value2, value3); | |||||
switch (action) | switch (action) | ||||
{ | { | ||||
case CarlaBackend::CALLBACK_SHOW_GUI: | case CarlaBackend::CALLBACK_SHOW_GUI: | ||||
@@ -1156,6 +1152,9 @@ void main_callback(CarlaBackend::CallbackType action, unsigned short plugin_id, | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
Q_UNUSED(plugin_id); | |||||
Q_UNUSED(value3); | |||||
} | } | ||||
int main(int argc, char* argv[]) | int main(int argc, char* argv[]) | ||||
@@ -1165,12 +1164,13 @@ int main(int argc, char* argv[]) | |||||
//set_option(CarlaBackend::OPTION_PROCESS_MODE, CarlaBackend::PROCESS_MODE_CONTINUOUS_RACK, nullptr); | //set_option(CarlaBackend::OPTION_PROCESS_MODE, CarlaBackend::PROCESS_MODE_CONTINUOUS_RACK, nullptr); | ||||
gui = new QDialog(nullptr); | gui = new QDialog(nullptr); | ||||
set_option(CarlaBackend::OPTION_PREFER_UI_BRIDGES, 0, nullptr); | |||||
if (engine_init("JACK", "carla_demo")) | if (engine_init("JACK", "carla_demo")) | ||||
{ | { | ||||
set_callback_function(main_callback); | set_callback_function(main_callback); | ||||
short id = add_plugin(CarlaBackend::BINARY_NATIVE, CarlaBackend::PLUGIN_LADSPA, "/usr/lib/ladspa/delay.so", "HAHA name!!!", "delay_5s", nullptr); | |||||
short id = add_plugin(CarlaBackend::BINARY_NATIVE, CarlaBackend::PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr); | |||||
if (id >= 0) | if (id >= 0) | ||||
{ | { | ||||
@@ -58,7 +58,7 @@ public: | |||||
params = nullptr; | params = nullptr; | ||||
m_thread = new CarlaPluginThread(this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE); | |||||
m_thread = new CarlaPluginThread(engine, this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE); | |||||
} | } | ||||
~BridgePlugin() | ~BridgePlugin() | ||||
@@ -193,13 +193,13 @@ public: | |||||
strncpy(strBuf, params[parameterId].unit.toUtf8().constData(), STR_MAX); | strncpy(strBuf, params[parameterId].unit.toUtf8().constData(), STR_MAX); | ||||
} | } | ||||
void getGuiInfo(GuiInfo* const info) | |||||
void getGuiInfo(GuiType* type, bool* resizable) | |||||
{ | { | ||||
if (m_hints & PLUGIN_HAS_GUI) | if (m_hints & PLUGIN_HAS_GUI) | ||||
info->type = GUI_EXTERNAL_OSC; | |||||
*type = GUI_EXTERNAL_OSC; | |||||
else | else | ||||
info->type = GUI_NONE; | |||||
info->resizable = false; | |||||
*type = GUI_NONE; | |||||
*resizable = false; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -252,7 +252,7 @@ public: | |||||
} | } | ||||
// create new if needed | // create new if needed | ||||
param.count = (pTotal < (int)carla_options.max_parameters) ? pTotal : 0; | |||||
param.count = (pTotal < (int)carlaOptions.max_parameters) ? pTotal : 0; | |||||
if (param.count > 0) | if (param.count > 0) | ||||
{ | { | ||||
@@ -476,7 +476,7 @@ public: | |||||
const char* key = (const char*)&argv[1]->s; | const char* key = (const char*)&argv[1]->s; | ||||
const char* value = (const char*)&argv[2]->s; | const char* value = (const char*)&argv[2]->s; | ||||
setCustomData(customdatastr2type(stype), key, value, false); | |||||
setCustomData(getCustomDataStringType(stype), key, value, false); | |||||
break; | break; | ||||
} | } | ||||
@@ -529,7 +529,7 @@ public: | |||||
if (sendGui) | if (sendGui) | ||||
{ | { | ||||
QString cData; | QString cData; | ||||
cData += customdatatype2str(type); | |||||
cData += getCustomDataTypeString(type); | |||||
cData += "·"; | cData += "·"; | ||||
cData += key; | cData += key; | ||||
cData += "·"; | cData += "·"; | ||||
@@ -574,7 +574,7 @@ public: | |||||
assert(index < (int32_t)midiprog.count); | assert(index < (int32_t)midiprog.count); | ||||
if (sendGui) | if (sendGui) | ||||
osc_send_midi_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program, (m_type == PLUGIN_DSSI)); | |||||
osc_send_midi_program(&osc.data, index); | |||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block); | ||||
} | } | ||||
@@ -634,11 +634,11 @@ public: | |||||
bool init(const char* filename, const char* const name, const char* label) | bool init(const char* filename, const char* const name, const char* label) | ||||
{ | { | ||||
const char* bridgeBinary = binarytype2str(m_binary); | |||||
const char* bridgeBinary = getBinaryBidgePath(m_binary); | |||||
if (! bridgeBinary) | if (! bridgeBinary) | ||||
{ | { | ||||
set_last_error("Bridge not possible, bridge-binary not found"); | |||||
setLastError("Bridge not possible, bridge-binary not found"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -648,9 +648,9 @@ public: | |||||
m_name = x_engine->getUniqueName(name); | m_name = x_engine->getUniqueName(name); | ||||
// register plugin now so we can receive OSC (and wait for it) | // register plugin now so we can receive OSC (and wait for it) | ||||
x_engine->addPlugin(m_id, this); | |||||
x_engine->__bridgePluginRegister(m_id, this); | |||||
m_thread->setOscData(bridgeBinary, label, plugintype2str(m_type)); | |||||
m_thread->setOscData(bridgeBinary, label, PluginType2str(m_type)); | |||||
m_thread->start(); | m_thread->start(); | ||||
for (int i=0; i < 100; i++) | for (int i=0; i < 100; i++) | ||||
@@ -662,8 +662,11 @@ public: | |||||
if (! initiated) | if (! initiated) | ||||
{ | { | ||||
// unregister so it gets handled properly | |||||
x_engine->__bridgePluginRegister(m_id, nullptr); | |||||
m_thread->quit(); | m_thread->quit(); | ||||
set_last_error("Timeout while waiting for a response from plugin-bridge"); | |||||
setLastError("Timeout while waiting for a response from plugin-bridge"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -692,32 +695,42 @@ private: | |||||
BridgeParamInfo* params; | BridgeParamInfo* params; | ||||
}; | }; | ||||
short CarlaPlugin::newBridge(const initializer& init, BinaryType btype, PluginType ptype) | |||||
CarlaPlugin* CarlaPlugin::newBridge(const initializer& init, BinaryType btype, PluginType ptype) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newBridge(%p, %s, %s, %s, %i, %i)", init.engine, init.filename, init.name, init.label, btype, ptype); | qDebug("CarlaPlugin::newBridge(%p, %s, %s, %s, %i, %i)", init.engine, init.filename, init.name, init.label, btype, ptype); | ||||
short id = init.engine->getNewPluginIndex(); | |||||
short id = init.engine->getNewPluginId(); | |||||
if (id >= 0) | |||||
if (id < 0) | |||||
{ | { | ||||
BridgePlugin* plugin = new BridgePlugin(init.engine, id, btype, ptype); | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | |||||
if (plugin->init(init.filename, init.name, init.label)) | |||||
{ | |||||
plugin->reload(); | |||||
plugin->registerToOsc(); | |||||
init.engine->addPlugin(id, plugin); | |||||
} | |||||
else | |||||
BridgePlugin* const plugin = new BridgePlugin(init.engine, id, btype, ptype); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | |||||
{ | |||||
delete plugin; | |||||
return nullptr; | |||||
} | |||||
plugin->reload(); | |||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
{ | |||||
if (/* inputs */ ((plugin->audioInCount() != 0 && plugin->audioInCount() != 2)) || /* outputs */ ((plugin->audioOutCount() != 0 && plugin->audioOutCount() != 2))) | |||||
{ | { | ||||
setLastError("Carla Rack Mode can only work with Stereo bridged plugins, sorry!"); | |||||
delete plugin; | delete plugin; | ||||
id = -1; | |||||
return nullptr; | |||||
} | } | ||||
} | } | ||||
else | |||||
set_last_error("Maximum number of plugins reached"); | |||||
return id; | |||||
plugin->registerToOsc(); | |||||
return plugin; | |||||
} | } | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE |
@@ -194,7 +194,7 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||||
return -1; | return -1; | ||||
# endif | # endif | ||||
//plugin = CarlaPlugin::newBridge(init, btype, ptype); | |||||
plugin = CarlaPlugin::newBridge(init, btype, ptype); | |||||
} | } | ||||
else | else | ||||
#endif | #endif | ||||
@@ -207,22 +207,22 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||||
plugin = CarlaPlugin::newLADSPA(init, extra); | plugin = CarlaPlugin::newLADSPA(init, extra); | ||||
break; | break; | ||||
case PLUGIN_DSSI: | case PLUGIN_DSSI: | ||||
//id = CarlaPlugin::newDSSI(init, extra); | |||||
plugin = CarlaPlugin::newDSSI(init, extra); | |||||
break; | break; | ||||
case PLUGIN_LV2: | case PLUGIN_LV2: | ||||
//id = CarlaPlugin::newLV2(init); | |||||
plugin = CarlaPlugin::newLV2(init); | |||||
break; | break; | ||||
case PLUGIN_VST: | case PLUGIN_VST: | ||||
//id = CarlaPlugin::newVST(init); | |||||
plugin = CarlaPlugin::newVST(init); | |||||
break; | break; | ||||
case PLUGIN_GIG: | case PLUGIN_GIG: | ||||
//id = CarlaPlugin::newGIG(init); | |||||
plugin = CarlaPlugin::newGIG(init); | |||||
break; | break; | ||||
case PLUGIN_SF2: | case PLUGIN_SF2: | ||||
//id = CarlaPlugin::newSF2(init); | |||||
plugin = CarlaPlugin::newSF2(init); | |||||
break; | break; | ||||
case PLUGIN_SFZ: | case PLUGIN_SFZ: | ||||
//id = CarlaPlugin::newSFZ(init); | |||||
plugin = CarlaPlugin::newSFZ(init); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -274,13 +274,35 @@ bool CarlaEngine::removePlugin(const unsigned short id) | |||||
} | } | ||||
} | } | ||||
if (isRunning()) | |||||
qCritical("remove_plugin(%i) - could not find plugin", id); | |||||
setLastError("Could not find plugin to remove"); | |||||
return false; | |||||
} | |||||
void CarlaEngine::removeAllPlugins() | |||||
{ | |||||
if (m_checkThread.isRunning()) | |||||
m_checkThread.stopNow(); | |||||
for (unsigned short i=0; i < MAX_PLUGINS; i++) | |||||
{ | { | ||||
qCritical("remove_plugin(%i) - could not find plugin", id); | |||||
setLastError("Could not find plugin to remove"); | |||||
CarlaPlugin* const plugin = m_carlaPlugins[i]; | |||||
if (plugin) | |||||
{ | |||||
processLock(); | |||||
plugin->setEnabled(false); | |||||
processUnlock(); | |||||
delete plugin; | |||||
m_carlaPlugins[i] = nullptr; | |||||
m_uniqueNames[i] = nullptr; | |||||
} | |||||
} | } | ||||
return false; | |||||
if (isRunning()) | |||||
m_checkThread.start(QThread::HighPriority); | |||||
} | } | ||||
void CarlaEngine::idlePluginGuis() | void CarlaEngine::idlePluginGuis() | ||||
@@ -19,6 +19,7 @@ | |||||
#define CARLA_ENGINE_H | #define CARLA_ENGINE_H | ||||
#include "carla_osc.h" | #include "carla_osc.h" | ||||
#include "carla_shared.h" | |||||
#include "carla_threads.h" | #include "carla_threads.h" | ||||
#include <cassert> | #include <cassert> | ||||
@@ -165,8 +166,20 @@ public: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// virtual, per-engine type calls | // virtual, per-engine type calls | ||||
virtual bool init(const char* const clientName) = 0; | |||||
virtual bool close() = 0; | |||||
virtual bool init(const char* const clientName) | |||||
{ | |||||
m_checkThread.start(QThread::HighPriority); | |||||
m_osc.init(clientName); | |||||
return true; | |||||
} | |||||
virtual bool close() | |||||
{ | |||||
if (m_checkThread.isRunning()) | |||||
m_checkThread.stopNow(); | |||||
m_osc.close(); | |||||
return true; | |||||
} | |||||
virtual bool isOnAudioThread() = 0; | virtual bool isOnAudioThread() = 0; | ||||
virtual bool isOffline() = 0; | virtual bool isOffline() = 0; | ||||
@@ -184,9 +197,16 @@ public: | |||||
short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | ||||
short addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | short addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | ||||
bool removePlugin(const unsigned short id); | bool removePlugin(const unsigned short id); | ||||
void removeAllPlugins(); | |||||
void idlePluginGuis(); | void idlePluginGuis(); | ||||
// bridge, internal use only | |||||
void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) | |||||
{ | |||||
m_carlaPlugins[id] = plugin; | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Information (base) | // Information (base) | ||||
@@ -246,12 +266,16 @@ public: | |||||
void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3) | void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3) | ||||
{ | { | ||||
qDebug("CarlaEngine::callback(%s, %i, %i, %i, %f)", CallbackType2str(action), pluginId, value1, value2, value3); | |||||
if (m_callback) | if (m_callback) | ||||
m_callback(action, pluginId, value1, value2, value3); | m_callback(action, pluginId, value1, value2, value3); | ||||
} | } | ||||
void setCallback(const CallbackFunc func) | void setCallback(const CallbackFunc func) | ||||
{ | { | ||||
qDebug("CarlaEngine::setCallback(%p)", func); | |||||
m_callback = func; | m_callback = func; | ||||
} | } | ||||
@@ -333,16 +357,6 @@ protected: | |||||
uint32_t bufferSize; | uint32_t bufferSize; | ||||
CarlaTimeInfo timeInfo; | CarlaTimeInfo timeInfo; | ||||
void oscInit() | |||||
{ | |||||
m_osc.init(name); | |||||
} | |||||
void oscClose() | |||||
{ | |||||
m_osc.close(); | |||||
} | |||||
void bufferSizeChanged(uint32_t newBufferSize); | void bufferSizeChanged(uint32_t newBufferSize); | ||||
private: | private: | ||||
@@ -150,7 +150,7 @@ bool CarlaEngineJack::init(const char* const clientName) | |||||
name = strdup(fixedName); | name = strdup(fixedName); | ||||
free((void*)fixedName); | free((void*)fixedName); | ||||
oscInit(); | |||||
CarlaEngine::init(name); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -169,6 +169,7 @@ bool CarlaEngineJack::init(const char* const clientName) | |||||
bool CarlaEngineJack::close() | bool CarlaEngineJack::close() | ||||
{ | { | ||||
qDebug("CarlaEngineJack::close()"); | qDebug("CarlaEngineJack::close()"); | ||||
CarlaEngine::close(); | |||||
if (name) | if (name) | ||||
{ | { | ||||
@@ -176,8 +177,6 @@ bool CarlaEngineJack::close() | |||||
name = nullptr; | name = nullptr; | ||||
} | } | ||||
oscClose(); | |||||
if (jack_deactivate(client) == 0) | if (jack_deactivate(client) == 0) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -175,10 +175,10 @@ int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg | |||||
return handle_note_off(plugin, argc, argv, types); | return handle_note_off(plugin, argc, argv, types); | ||||
// Plugin-specific methods | // Plugin-specific methods | ||||
//if (strcmp(method, "/lv2_atom_transfer") == 0) | |||||
// return handle_lv2_atom_transfer(plugin, argc, argv, types); | |||||
//if (strcmp(method, "/lv2_event_transfer") == 0) | |||||
// return handle_lv2_event_transfer(plugin, argc, argv, types); | |||||
if (strcmp(method, "/lv2_atom_transfer") == 0) | |||||
return handle_lv2_atom_transfer(plugin, argc, argv, types); | |||||
if (strcmp(method, "/lv2_event_transfer") == 0) | |||||
return handle_lv2_event_transfer(plugin, argc, argv, types); | |||||
// Plugin Bridges | // Plugin Bridges | ||||
if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE) | if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE) | ||||
@@ -138,7 +138,7 @@ struct PluginParameterData { | |||||
struct PluginProgramData { | struct PluginProgramData { | ||||
uint32_t count; | uint32_t count; | ||||
int32_t current; | int32_t current; | ||||
const char* const* names; | |||||
const char** names; | |||||
PluginProgramData() | PluginProgramData() | ||||
: count(0), | : count(0), | ||||
@@ -1984,14 +1984,14 @@ public: | |||||
}; | }; | ||||
static CarlaPlugin* newLADSPA(const initializer& init, const void* const extra); | static CarlaPlugin* newLADSPA(const initializer& init, const void* const extra); | ||||
///static short newDSSI(const initializer& init, const void* const extra); | |||||
//static short newLV2(const initializer& init); | |||||
//static short newVST(const initializer& init); | |||||
//static short newGIG(const initializer& init); | |||||
//static short newSF2(const initializer& init); | |||||
//static short newSFZ(const initializer& init); | |||||
static CarlaPlugin* newDSSI(const initializer& init, const void* const extra); | |||||
static CarlaPlugin* newLV2(const initializer& init); | |||||
static CarlaPlugin* newVST(const initializer& init); | |||||
static CarlaPlugin* newGIG(const initializer& init); | |||||
static CarlaPlugin* newSF2(const initializer& init); | |||||
static CarlaPlugin* newSFZ(const initializer& init); | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
//static short newBridge(const initializer& init, BinaryType btype, PluginType ptype); | |||||
static CarlaPlugin* newBridge(const initializer& init, BinaryType btype, PluginType ptype); | |||||
#endif | #endif | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -42,8 +42,8 @@ public: | |||||
m_type = PLUGIN_DSSI; | m_type = PLUGIN_DSSI; | ||||
handle = nullptr; | |||||
descriptor = nullptr; | |||||
handle = h2 = nullptr; | |||||
descriptor = nullptr; | |||||
ldescriptor = nullptr; | ldescriptor = nullptr; | ||||
param_buffers = nullptr; | param_buffers = nullptr; | ||||
@@ -61,8 +61,8 @@ public: | |||||
{ | { | ||||
if (osc.data.target) | if (osc.data.target) | ||||
{ | { | ||||
//osc_send_hide(&osc.data); | |||||
//osc_send_quit(&osc.data); | |||||
osc_send_hide(&osc.data); | |||||
osc_send_quit(&osc.data); | |||||
} | } | ||||
if (osc.thread) | if (osc.thread) | ||||
@@ -83,15 +83,28 @@ public: | |||||
delete osc.thread; | delete osc.thread; | ||||
} | } | ||||
//osc_clear_data(&osc.data); | |||||
osc_clear_data(&osc.data); | |||||
} | } | ||||
#endif | #endif | ||||
if (handle && ldescriptor && ldescriptor->deactivate && m_activeBefore) | |||||
ldescriptor->deactivate(handle); | |||||
if (ldescriptor) | |||||
{ | |||||
if (ldescriptor->deactivate && m_activeBefore) | |||||
{ | |||||
if (handle) | |||||
ldescriptor->deactivate(handle); | |||||
if (h2) | |||||
ldescriptor->deactivate(h2); | |||||
} | |||||
if (handle && ldescriptor && ldescriptor->cleanup) | |||||
ldescriptor->cleanup(handle); | |||||
if (ldescriptor->cleanup) | |||||
{ | |||||
if (handle) | |||||
ldescriptor->cleanup(handle); | |||||
if (h2) | |||||
ldescriptor->cleanup(h2); | |||||
} | |||||
} | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -101,7 +114,7 @@ public: | |||||
{ | { | ||||
if (m_hints & PLUGIN_IS_SYNTH) | if (m_hints & PLUGIN_IS_SYNTH) | ||||
return PLUGIN_CATEGORY_SYNTH; | return PLUGIN_CATEGORY_SYNTH; | ||||
return get_category_from_name(m_name); | |||||
return getPluginCategoryFromName(m_name); | |||||
} | } | ||||
long uniqueId() | long uniqueId() | ||||
@@ -187,8 +200,8 @@ public: | |||||
param_buffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]); | param_buffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
//if (sendGui) | |||||
//osc_send_control(&osc.data, param.data[parameterId].rindex, value); | |||||
if (sendGui) | |||||
osc_send_control(&osc.data, param.data[parameterId].rindex, value); | |||||
#endif | #endif | ||||
CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); | CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); | ||||
@@ -202,8 +215,8 @@ public: | |||||
descriptor->configure(handle, key, value); | descriptor->configure(handle, key, value); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
//if (sendGui) | |||||
//osc_send_configure(&osc.data, key, value); | |||||
if (sendGui) | |||||
osc_send_configure(&osc.data, key, value); | |||||
#endif | #endif | ||||
if (strcmp(key, "reloadprograms") == 0 || strcmp(key, "load") == 0 || strncmp(key, "patches", 7) == 0) | if (strcmp(key, "reloadprograms") == 0 || strcmp(key, "load") == 0 || strncmp(key, "patches", 7) == 0) | ||||
@@ -254,8 +267,8 @@ public: | |||||
} | } | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
//if (sendGui) | |||||
//osc_send_midi_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program, true); | |||||
if (sendGui) | |||||
osc_send_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -274,9 +287,9 @@ public: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
//osc_send_hide(&osc.data); | |||||
//osc_send_quit(&osc.data); | |||||
//osc_clear_data(&osc.data); | |||||
osc_send_hide(&osc.data); | |||||
osc_send_quit(&osc.data); | |||||
osc_clear_data(&osc.data); | |||||
osc.thread->quit(); // FIXME - stop thread? | osc.thread->quit(); // FIXME - stop thread? | ||||
} | } | ||||
} | } | ||||
@@ -321,6 +334,9 @@ public: | |||||
params += 1; | params += 1; | ||||
} | } | ||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK && (ains == 1 || aouts == 1) && ! h2) | |||||
h2 = ldescriptor->instantiate(ldescriptor, sampleRate); | |||||
if (descriptor->run_synth || descriptor->run_multiple_synths) | if (descriptor->run_synth || descriptor->run_multiple_synths) | ||||
mins = 1; | mins = 1; | ||||
@@ -356,7 +372,7 @@ public: | |||||
if (LADSPA_IS_PORT_AUDIO(PortType)) | if (LADSPA_IS_PORT_AUDIO(PortType)) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":"); | strcat(portName, ":"); | ||||
@@ -571,19 +587,21 @@ public: | |||||
param_buffers[j] = def; | param_buffers[j] = def; | ||||
ldescriptor->connect_port(handle, i, ¶m_buffers[j]); | ldescriptor->connect_port(handle, i, ¶m_buffers[j]); | ||||
if (h2) ldescriptor->connect_port(h2, i, ¶m_buffers[j]); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
// Not Audio or Control | // Not Audio or Control | ||||
qCritical("ERROR - Got a broken Port (neither Audio or Control)"); | qCritical("ERROR - Got a broken Port (neither Audio or Control)"); | ||||
ldescriptor->connect_port(handle, i, nullptr); | ldescriptor->connect_port(handle, i, nullptr); | ||||
if (h2) ldescriptor->connect_port(h2, i, nullptr); | |||||
} | } | ||||
} | } | ||||
if (needsCin) | if (needsCin) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-in"); | strcat(portName, ":control-in"); | ||||
@@ -598,7 +616,7 @@ public: | |||||
if (needsCout) | if (needsCout) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-out"); | strcat(portName, ":control-out"); | ||||
@@ -613,7 +631,7 @@ public: | |||||
if (mins > 0) | if (mins > 0) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":midi-in"); | strcat(portName, ":midi-in"); | ||||
@@ -636,7 +654,7 @@ public: | |||||
m_hints |= PLUGIN_IS_SYNTH; | m_hints |= PLUGIN_IS_SYNTH; | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.use_dssi_chunks && QString(m_filename).endsWith("dssi-vst.so", Qt::CaseInsensitive)) | |||||
if (carlaOptions.use_dssi_chunks && QString(m_filename).endsWith("dssi-vst.so", Qt::CaseInsensitive)) | |||||
{ | { | ||||
if (descriptor->get_custom_data && descriptor->set_custom_data) | if (descriptor->get_custom_data && descriptor->set_custom_data) | ||||
m_hints |= PLUGIN_USES_CHUNKS; | m_hints |= PLUGIN_USES_CHUNKS; | ||||
@@ -649,7 +667,7 @@ public: | |||||
if (aouts > 0) | if (aouts > 0) | ||||
m_hints |= PLUGIN_CAN_VOLUME; | m_hints |= PLUGIN_CAN_VOLUME; | ||||
if (aouts >= 2 && aouts%2 == 0) | |||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK || (aouts >= 2 && aouts%2 == 0)) | |||||
m_hints |= PLUGIN_CAN_BALANCE; | m_hints |= PLUGIN_CAN_BALANCE; | ||||
reloadPrograms(true); | reloadPrograms(true); | ||||
@@ -699,10 +717,10 @@ public: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
// Update OSC Names | // Update OSC Names | ||||
//osc_global_send_set_midi_program_count(m_id, midiprog.count); | |||||
x_engine->osc_send_set_midi_program_count(m_id, midiprog.count); | |||||
//for (i=0; i < midiprog.count; i++) | |||||
// osc_global_send_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name); | |||||
for (i=0; i < midiprog.count; i++) | |||||
x_engine->osc_send_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name); | |||||
x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | ||||
#endif | #endif | ||||
@@ -767,7 +785,9 @@ public: | |||||
if (ain.count > 0) | if (ain.count > 0) | ||||
{ | { | ||||
if (ain.count == 1) | |||||
uint32_t count = h2 ? 2 : ain.count; | |||||
if (count == 1) | |||||
{ | { | ||||
for (k=0; k < frames; k++) | for (k=0; k < frames; k++) | ||||
{ | { | ||||
@@ -775,7 +795,7 @@ public: | |||||
ains_peak_tmp[0] = abs(inBuffer[0][k]); | ains_peak_tmp[0] = abs(inBuffer[0][k]); | ||||
} | } | ||||
} | } | ||||
else if (ain.count >= 1) | |||||
else if (count > 1) | |||||
{ | { | ||||
for (k=0; k < frames; k++) | for (k=0; k < frames; k++) | ||||
{ | { | ||||
@@ -935,10 +955,16 @@ public: | |||||
sendMidiAllNotesOff(); | sendMidiAllNotesOff(); | ||||
if (ldescriptor->deactivate) | if (ldescriptor->deactivate) | ||||
{ | |||||
ldescriptor->deactivate(handle); | ldescriptor->deactivate(handle); | ||||
if (h2) ldescriptor->deactivate(h2); | |||||
} | |||||
if (ldescriptor->activate) | if (ldescriptor->activate) | ||||
{ | |||||
ldescriptor->activate(handle); | ldescriptor->activate(handle); | ||||
if (h2) ldescriptor->activate(h2); | |||||
} | |||||
allNotesOffSent = true; | allNotesOffSent = true; | ||||
} | } | ||||
@@ -968,7 +994,7 @@ public: | |||||
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | ||||
{ | { | ||||
if (! extMidiNotes[i].valid) | |||||
if (extMidiNotes[i].channel < 0) | |||||
break; | break; | ||||
snd_seq_event_t* const midiEvent = &midiEvents[midiEventCount]; | snd_seq_event_t* const midiEvent = &midiEvents[midiEventCount]; | ||||
@@ -980,7 +1006,7 @@ public: | |||||
midiEvent->data.note.note = extMidiNotes[i].note; | midiEvent->data.note.note = extMidiNotes[i].note; | ||||
midiEvent->data.note.velocity = extMidiNotes[i].velo; | midiEvent->data.note.velocity = extMidiNotes[i].velo; | ||||
extMidiNotes[i].valid = false; | |||||
extMidiNotes[i].channel = -1; | |||||
midiEventCount += 1; | midiEventCount += 1; | ||||
} | } | ||||
@@ -1122,33 +1148,51 @@ public: | |||||
} | } | ||||
if (ldescriptor->activate) | if (ldescriptor->activate) | ||||
{ | |||||
ldescriptor->activate(handle); | ldescriptor->activate(handle); | ||||
if (h2) ldescriptor->activate(h2); | |||||
} | |||||
} | } | ||||
for (i=0; i < ain.count; i++) | for (i=0; i < ain.count; i++) | ||||
{ | |||||
ldescriptor->connect_port(handle, ain.rindexes[i], inBuffer[i]); | ldescriptor->connect_port(handle, ain.rindexes[i], inBuffer[i]); | ||||
if (h2 && i == 0) ldescriptor->connect_port(h2, ain.rindexes[i], inBuffer[1]); | |||||
} | |||||
for (i=0; i < aout.count; i++) | for (i=0; i < aout.count; i++) | ||||
{ | |||||
ldescriptor->connect_port(handle, aout.rindexes[i], outBuffer[i]); | ldescriptor->connect_port(handle, aout.rindexes[i], outBuffer[i]); | ||||
if (h2 && i == 0) ldescriptor->connect_port(h2, aout.rindexes[i], outBuffer[1]); | |||||
} | |||||
if (descriptor->run_synth) | if (descriptor->run_synth) | ||||
{ | { | ||||
descriptor->run_synth(handle, frames, midiEvents, midiEventCount); | descriptor->run_synth(handle, frames, midiEvents, midiEventCount); | ||||
if (h2) descriptor->run_synth(handle, frames, midiEvents, midiEventCount); | |||||
} | } | ||||
else if (descriptor->run_multiple_synths) | else if (descriptor->run_multiple_synths) | ||||
{ | { | ||||
snd_seq_event_t* midiEventsPtr[1] = { midiEvents }; | |||||
descriptor->run_multiple_synths(1, &handle, frames, midiEventsPtr, &midiEventCount); | |||||
LADSPA_Handle handlePtr[2] = { handle, h2 }; | |||||
snd_seq_event_t* midiEventsPtr[2] = { midiEvents, midiEvents }; | |||||
unsigned long midiEventCountPtr[2] = { midiEventCount, midiEventCount }; | |||||
descriptor->run_multiple_synths(h2 ? 2 : 1, handlePtr, frames, midiEventsPtr, midiEventCountPtr); | |||||
} | } | ||||
else if (ldescriptor->run) | |||||
else | |||||
{ | |||||
ldescriptor->run(handle, frames); | ldescriptor->run(handle, frames); | ||||
if (h2) ldescriptor->run(h2, frames); | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (m_activeBefore) | if (m_activeBefore) | ||||
{ | { | ||||
if (ldescriptor->deactivate) | if (ldescriptor->deactivate) | ||||
{ | |||||
ldescriptor->deactivate(handle); | ldescriptor->deactivate(handle); | ||||
if (h2) ldescriptor->deactivate(h2); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -1166,7 +1210,9 @@ public: | |||||
double bal_rangeL, bal_rangeR; | double bal_rangeL, bal_rangeR; | ||||
float oldBufLeft[do_balance ? frames : 0]; | float oldBufLeft[do_balance ? frames : 0]; | ||||
for (i=0; i < aout.count; i++) | |||||
uint32_t count = h2 ? 2 : aout.count; | |||||
for (i=0; i < count; i++) | |||||
{ | { | ||||
// Dry/Wet and Volume | // Dry/Wet and Volume | ||||
if (do_drywet || do_volume) | if (do_drywet || do_volume) | ||||
@@ -1175,7 +1221,7 @@ public: | |||||
{ | { | ||||
if (do_drywet) | if (do_drywet) | ||||
{ | { | ||||
if (aout.count == 1) | |||||
if (aout.count == 1 && ! h2) | |||||
outBuffer[i][k] = (outBuffer[i][k]*x_drywet)+(inBuffer[0][k]*(1.0-x_drywet)); | outBuffer[i][k] = (outBuffer[i][k]*x_drywet)+(inBuffer[0][k]*(1.0-x_drywet)); | ||||
else | else | ||||
outBuffer[i][k] = (outBuffer[i][k]*x_drywet)+(inBuffer[i][k]*(1.0-x_drywet)); | outBuffer[i][k] = (outBuffer[i][k]*x_drywet)+(inBuffer[i][k]*(1.0-x_drywet)); | ||||
@@ -1292,7 +1338,7 @@ public: | |||||
if (! libOpen(filename)) | if (! libOpen(filename)) | ||||
{ | { | ||||
set_last_error(libError(filename)); | |||||
setLastError(libError(filename)); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1303,7 +1349,7 @@ public: | |||||
if (! descfn) | if (! descfn) | ||||
{ | { | ||||
set_last_error("Could not find the LASDPA Descriptor in the plugin library"); | |||||
setLastError("Could not find the LASDPA Descriptor in the plugin library"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1320,7 +1366,7 @@ public: | |||||
if (! descriptor) | if (! descriptor) | ||||
{ | { | ||||
set_last_error("Could not find the requested plugin Label in the plugin library"); | |||||
setLastError("Could not find the requested plugin Label in the plugin library"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1331,7 +1377,7 @@ public: | |||||
if (! handle) | if (! handle) | ||||
{ | { | ||||
set_last_error("Plugin failed to initialize"); | |||||
setLastError("Plugin failed to initialize"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1352,7 +1398,7 @@ public: | |||||
if (! x_client->isOk()) | if (! x_client->isOk()) | ||||
{ | { | ||||
set_last_error("Failed to register plugin client"); | |||||
setLastError("Failed to register plugin client"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1374,7 +1420,7 @@ public: | |||||
} | } | ||||
private: | private: | ||||
LADSPA_Handle handle; | |||||
LADSPA_Handle handle, h2; | |||||
const LADSPA_Descriptor* ldescriptor; | const LADSPA_Descriptor* ldescriptor; | ||||
const DSSI_Descriptor* descriptor; | const DSSI_Descriptor* descriptor; | ||||
snd_seq_event_t midiEvents[MAX_MIDI_EVENTS]; | snd_seq_event_t midiEvents[MAX_MIDI_EVENTS]; | ||||
@@ -1382,16 +1428,16 @@ private: | |||||
float* param_buffers; | float* param_buffers; | ||||
}; | }; | ||||
short CarlaPlugin::newDSSI(const initializer& init, const void* const extra) | |||||
CarlaPlugin* CarlaPlugin::newDSSI(const initializer& init, const void* const extra) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newDSSI(%p, %s, %s, %s, %p)", init.engine, init.filename, init.name, init.label, extra); | qDebug("CarlaPlugin::newDSSI(%p, %s, %s, %s, %p)", init.engine, init.filename, init.name, init.label, extra); | ||||
short id = init.engine->getNewPluginIndex(); | |||||
short id = init.engine->getNewPluginId(); | |||||
if (id < 0) | if (id < 0) | ||||
{ | { | ||||
set_last_error("Maximum number of plugins reached"); | |||||
return -1; | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | } | ||||
DssiPlugin* const plugin = new DssiPlugin(init.engine, id); | DssiPlugin* const plugin = new DssiPlugin(init.engine, id); | ||||
@@ -1399,28 +1445,29 @@ short CarlaPlugin::newDSSI(const initializer& init, const void* const extra) | |||||
if (! plugin->init(init.filename, init.name, init.label, (const char*)extra)) | if (! plugin->init(init.filename, init.name, init.label, (const char*)extra)) | ||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
plugin->reload(); | plugin->reload(); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
{ | { | ||||
if (/* inputs */ ((plugin->audioInCount() != 0 && plugin->audioInCount() != 2)) || /* outputs */ ((plugin->audioOutCount() != 0 && plugin->audioOutCount() != 2))) | |||||
uint32_t ins = plugin->audioInCount(); | |||||
uint32_t outs = plugin->audioOutCount(); | |||||
if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | |||||
{ | { | ||||
set_last_error("Carla Rack Mode can only work with Stereo plugins, sorry!"); | |||||
setLastError("Carla's Rack Mode can only work with Mono or Stereo DSSI plugins, sorry!"); | |||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
plugin->registerToOsc(); | plugin->registerToOsc(); | ||||
init.engine->addPlugin(id, plugin); | |||||
return id; | |||||
return plugin; | |||||
} | } | ||||
/**@}*/ | /**@}*/ | ||||
@@ -21,6 +21,12 @@ | |||||
#include "carla_plugin.h" | #include "carla_plugin.h" | ||||
CARLA_BACKEND_START_NAMESPACE | |||||
#if 0 | |||||
} /* adjust editor indent */ | |||||
#endif | |||||
#ifdef WANT_FLUIDSYNTH | #ifdef WANT_FLUIDSYNTH | ||||
#include <fluidsynth.h> | #include <fluidsynth.h> | ||||
@@ -28,12 +34,6 @@ | |||||
#define FLUIDSYNTH_VERSION_NEW_API | #define FLUIDSYNTH_VERSION_NEW_API | ||||
#endif | #endif | ||||
CARLA_BACKEND_START_NAMESPACE | |||||
#if 0 | |||||
} /* adjust editor indent */ | |||||
#endif | |||||
/*! | /*! | ||||
* @defgroup CarlaBackendFluidSynthPlugin Carla Backend FluidSynth Plugin | * @defgroup CarlaBackendFluidSynthPlugin Carla Backend FluidSynth Plugin | ||||
* | * | ||||
@@ -415,7 +415,7 @@ public: | |||||
// Audio Outputs | // Audio Outputs | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":out-left"); | strcat(portName, ":out-left"); | ||||
@@ -428,7 +428,7 @@ public: | |||||
aout.rindexes[0] = 0; | aout.rindexes[0] = 0; | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":out-right"); | strcat(portName, ":out-right"); | ||||
@@ -444,7 +444,7 @@ public: | |||||
// MIDI Input | // MIDI Input | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":midi-in"); | strcat(portName, ":midi-in"); | ||||
@@ -459,7 +459,7 @@ public: | |||||
// Parameters | // Parameters | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-in"); | strcat(portName, ":control-in"); | ||||
@@ -471,7 +471,7 @@ public: | |||||
param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true); | param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-out"); | strcat(portName, ":control-out"); | ||||
@@ -1013,7 +1013,7 @@ public: | |||||
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | ||||
{ | { | ||||
if (! extMidiNotes[i].valid) | |||||
if (extMidiNotes[i].channel < 0) | |||||
break; | break; | ||||
if (extMidiNotes[i].velo) | if (extMidiNotes[i].velo) | ||||
@@ -1021,7 +1021,7 @@ public: | |||||
else | else | ||||
fluid_synth_noteoff(f_synth, cin_channel, extMidiNotes[i].note); | fluid_synth_noteoff(f_synth, cin_channel, extMidiNotes[i].note); | ||||
extMidiNotes[i].valid = false; | |||||
extMidiNotes[i].channel = -1; | |||||
midiEventCount += 1; | midiEventCount += 1; | ||||
} | } | ||||
@@ -1226,7 +1226,7 @@ public: | |||||
if (f_id < 0) | if (f_id < 0) | ||||
{ | { | ||||
set_last_error("Failed to load SoundFont file"); | |||||
setLastError("Failed to load SoundFont file"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1248,7 +1248,7 @@ public: | |||||
if (! x_client->isOk()) | if (! x_client->isOk()) | ||||
{ | { | ||||
set_last_error("Failed to register plugin client"); | |||||
setLastError("Failed to register plugin client"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1283,23 +1283,23 @@ private: | |||||
}; | }; | ||||
#endif // WANT_FLUIDSYNTH | #endif // WANT_FLUIDSYNTH | ||||
short CarlaPlugin::newSF2(const initializer& init) | |||||
CarlaPlugin* CarlaPlugin::newSF2(const initializer& init) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newSF2(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | qDebug("CarlaPlugin::newSF2(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | ||||
#ifdef WANT_FLUIDSYNTH | #ifdef WANT_FLUIDSYNTH | ||||
short id = init.engine->getNewPluginIndex(); | |||||
short id = init.engine->getNewPluginId(); | |||||
if (id < 0) | if (id < 0) | ||||
{ | { | ||||
set_last_error("Maximum number of plugins reached"); | |||||
return -1; | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | } | ||||
if (! fluid_is_soundfont(init.filename)) | if (! fluid_is_soundfont(init.filename)) | ||||
{ | { | ||||
set_last_error("Requested file is not a valid SoundFont"); | |||||
return -1; | |||||
setLastError("Requested file is not a valid SoundFont"); | |||||
return nullptr; | |||||
} | } | ||||
FluidSynthPlugin* const plugin = new FluidSynthPlugin(init.engine, id); | FluidSynthPlugin* const plugin = new FluidSynthPlugin(init.engine, id); | ||||
@@ -1307,17 +1307,16 @@ short CarlaPlugin::newSF2(const initializer& init) | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
plugin->reload(); | plugin->reload(); | ||||
plugin->registerToOsc(); | plugin->registerToOsc(); | ||||
init.engine->addPlugin(id, plugin); | |||||
return id; | |||||
return plugin; | |||||
#else | #else | ||||
set_last_error("fluidsynth support not available"); | |||||
return -1; | |||||
setLastError("fluidsynth support not available"); | |||||
return nullptr; | |||||
#endif | #endif | ||||
} | } | ||||
@@ -17,7 +17,6 @@ | |||||
#include "carla_plugin.h" | #include "carla_plugin.h" | ||||
#include "carla_ladspa_includes.h" | #include "carla_ladspa_includes.h" | ||||
#include "carla_lv2_includes.h" | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -1121,8 +1120,7 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const initializer& init, const void* const e | |||||
if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | ||||
{ | { | ||||
setLastError("Carla's Rack Mode can only work with Mono or Stereo plugins, sorry!"); | |||||
qWarning("data: %i %i | %i %i %i", ins > 2, outs > 2, ins != outs, ins != 0, outs != 0); | |||||
setLastError("Carla's Rack Mode can only work with Mono or Stereo LADSPA plugins, sorry!"); | |||||
delete plugin; | delete plugin; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
@@ -19,11 +19,10 @@ | |||||
#error Should not use linuxsampler for bridges! | #error Should not use linuxsampler for bridges! | ||||
#endif | #endif | ||||
#include "carla_plugin.h" | |||||
// TODO - setMidiProgram() | |||||
#ifdef WANT_LINUXSAMPLER | |||||
#include <linuxsampler/Sampler.h> | |||||
#include "linuxsampler/EngineFactory.h" | |||||
#include "carla_plugin.h" | |||||
#include "carla_linuxsampler_includes.h" | |||||
#include <QtCore/QFileInfo> | #include <QtCore/QFileInfo> | ||||
@@ -33,6 +32,8 @@ CARLA_BACKEND_START_NAMESPACE | |||||
} /* adjust editor indent */ | } /* adjust editor indent */ | ||||
#endif | #endif | ||||
#ifdef WANT_LINUXSAMPLER | |||||
/*! | /*! | ||||
* @defgroup CarlaBackendLinuxSamplerPlugin Carla Backend LinuxSampler Plugin | * @defgroup CarlaBackendLinuxSamplerPlugin Carla Backend LinuxSampler Plugin | ||||
* | * | ||||
@@ -40,118 +41,6 @@ CARLA_BACKEND_START_NAMESPACE | |||||
* http://www.linuxsampler.org/ | * http://www.linuxsampler.org/ | ||||
* @{ | * @{ | ||||
*/ | */ | ||||
// TODO - setMidiProgram() | |||||
#define LINUXSAMPLER_VOLUME_MAX 3.16227766f // +10 dB | |||||
#define LINUXSAMPLER_VOLUME_MIN 0.0f // -inf dB | |||||
class AudioOutputDevicePlugin : public LinuxSampler::AudioOutputDevice | |||||
{ | |||||
public: | |||||
AudioOutputDevicePlugin(CarlaPlugin* const plugin) : | |||||
AudioOutputDevice(std::map<String,LinuxSampler::DeviceCreationParameter*>()), | |||||
m_engine(nullptr), | |||||
m_plugin(plugin) | |||||
{ | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// LinuxSampler virtual methods | |||||
void Play() | |||||
{ | |||||
} | |||||
bool IsPlaying() | |||||
{ | |||||
return m_engine->isRunning() && m_plugin->enabled(); | |||||
} | |||||
void Stop() | |||||
{ | |||||
} | |||||
uint MaxSamplesPerCycle() | |||||
{ | |||||
return m_engine->getBufferSize(); | |||||
} | |||||
uint SampleRate() | |||||
{ | |||||
return m_engine->getSampleRate(); | |||||
} | |||||
String Driver() | |||||
{ | |||||
return "AudioOutputDevicePlugin"; | |||||
} | |||||
LinuxSampler::AudioChannel* CreateChannel(uint channelNr) | |||||
{ | |||||
return new LinuxSampler::AudioChannel(channelNr, nullptr, 0); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
int Render(uint samples) | |||||
{ | |||||
return RenderAudio(samples); | |||||
} | |||||
private: | |||||
CarlaEngine* const m_engine; | |||||
CarlaPlugin* const m_plugin; | |||||
}; | |||||
class MidiInputDevicePlugin : public LinuxSampler::MidiInputDevice | |||||
{ | |||||
public: | |||||
MidiInputDevicePlugin(LinuxSampler::Sampler* sampler) : LinuxSampler::MidiInputDevice(std::map<String, LinuxSampler::DeviceCreationParameter*>(), sampler) | |||||
{ | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// MIDI Port implementation for this plugin MIDI input driver | |||||
class MidiInputPortPlugin : public LinuxSampler::MidiInputPort | |||||
{ | |||||
protected: | |||||
MidiInputPortPlugin(MidiInputDevicePlugin* device, int portNumber) : LinuxSampler::MidiInputPort(device, portNumber) | |||||
{ | |||||
} | |||||
friend class MidiInputDevicePlugin; | |||||
}; | |||||
// ------------------------------------------------------------------- | |||||
// LinuxSampler virtual methods | |||||
void Listen() | |||||
{ | |||||
} | |||||
void StopListen() | |||||
{ | |||||
} | |||||
String Driver() | |||||
{ | |||||
return "MidiInputDevicePlugin"; | |||||
} | |||||
LinuxSampler::MidiInputPort* CreateMidiPort() | |||||
{ | |||||
return new MidiInputPortPlugin(this, Ports.size()); | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
void DeleteMidiPort(LinuxSampler::MidiInputPort* port) | |||||
{ | |||||
delete (MidiInputPortPlugin*)port; | |||||
} | |||||
}; | |||||
class LinuxSamplerPlugin : public CarlaPlugin | class LinuxSamplerPlugin : public CarlaPlugin | ||||
{ | { | ||||
public: | public: | ||||
@@ -160,6 +49,7 @@ public: | |||||
qDebug("LinuxSamplerPlugin::LinuxSamplerPlugin()"); | qDebug("LinuxSamplerPlugin::LinuxSamplerPlugin()"); | ||||
m_type = isGIG ? PLUGIN_GIG : PLUGIN_SFZ; | m_type = isGIG ? PLUGIN_GIG : PLUGIN_SFZ; | ||||
sampler = new LinuxSampler::Sampler; | sampler = new LinuxSampler::Sampler; | ||||
sampler_channel = nullptr; | sampler_channel = nullptr; | ||||
@@ -263,7 +153,7 @@ public: | |||||
// Audio Outputs | // Audio Outputs | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":out-left"); | strcat(portName, ":out-left"); | ||||
@@ -276,7 +166,7 @@ public: | |||||
aout.rindexes[0] = 0; | aout.rindexes[0] = 0; | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":out-right"); | strcat(portName, ":out-right"); | ||||
@@ -292,7 +182,7 @@ public: | |||||
// MIDI Input | // MIDI Input | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":midi-in"); | strcat(portName, ":midi-in"); | ||||
@@ -592,7 +482,7 @@ public: | |||||
} | } | ||||
catch (LinuxSampler::Exception& e) | catch (LinuxSampler::Exception& e) | ||||
{ | { | ||||
set_last_error(e.what()); | |||||
setLastError(e.what()); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -601,7 +491,7 @@ public: | |||||
} | } | ||||
catch (LinuxSampler::Exception& e) | catch (LinuxSampler::Exception& e) | ||||
{ | { | ||||
set_last_error(e.what()); | |||||
setLastError(e.what()); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -610,7 +500,7 @@ public: | |||||
} | } | ||||
catch (LinuxSampler::Exception& e) | catch (LinuxSampler::Exception& e) | ||||
{ | { | ||||
set_last_error(e.what()); | |||||
setLastError(e.what()); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -645,20 +535,20 @@ public: | |||||
if (x_client->isOk()) | if (x_client->isOk()) | ||||
return true; | return true; | ||||
else | else | ||||
set_last_error("Failed to register plugin client"); | |||||
setLastError("Failed to register plugin client"); | |||||
} | } | ||||
else | else | ||||
set_last_error("Failed to find any instruments"); | |||||
setLastError("Failed to find any instruments"); | |||||
} | } | ||||
else | else | ||||
set_last_error("Requested file is not valid or does not exist"); | |||||
setLastError("Requested file is not valid or does not exist"); | |||||
return false; | return false; | ||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
static short newLinuxSampler(const initializer& init, bool isGIG); | |||||
static CarlaPlugin* newLinuxSampler(const initializer& init, bool isGIG); | |||||
private: | private: | ||||
LinuxSampler::Sampler* sampler; | LinuxSampler::Sampler* sampler; | ||||
@@ -676,50 +566,54 @@ private: | |||||
const char* m_label; | const char* m_label; | ||||
const char* m_maker; | const char* m_maker; | ||||
}; | }; | ||||
#endif | |||||
short LinuxSamplerPlugin::newLinuxSampler(const initializer& init, bool isGIG) | |||||
CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const initializer& init, bool isGIG) | |||||
{ | { | ||||
qDebug("LinuxSamplerPlugin::newLinuxSampler(%p, %s, %s, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG)); | qDebug("LinuxSamplerPlugin::newLinuxSampler(%p, %s, %s, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG)); | ||||
#ifdef WANT_LINUXSAMPLER | |||||
short id = init.engine->getNewPluginIndex(); | short id = init.engine->getNewPluginIndex(); | ||||
if (id < 0) | if (id < 0) | ||||
{ | { | ||||
set_last_error("Maximum number of plugins reached"); | |||||
return -1; | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | } | ||||
LinuxSamplerPlugin* plugin = new LinuxSamplerPlugin(init.engine, id, isGIG); | |||||
LinuxSamplerPlugin* const plugin = new LinuxSamplerPlugin(init.engine, id, isGIG); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
plugin->reload(); | plugin->reload(); | ||||
plugin->registerToOsc(); | plugin->registerToOsc(); | ||||
init.engine->addPlugin(id, plugin); | |||||
return id; | |||||
#else | |||||
set_last_error("linuxsampler support not available"); | |||||
return -1; | |||||
#endif | |||||
return plugin; | |||||
} | } | ||||
#endif | |||||
short CarlaPlugin::newGIG(const initializer& init) | |||||
CarlaPlugin* CarlaPlugin::newGIG(const initializer& init) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newGIG(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | qDebug("CarlaPlugin::newGIG(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | ||||
#ifdef WANT_LINUXSAMPLER | |||||
return LinuxSamplerPlugin::newLinuxSampler(init, true); | return LinuxSamplerPlugin::newLinuxSampler(init, true); | ||||
#else | |||||
setLastError("linuxsampler support not available"); | |||||
return nullptr; | |||||
#endif | |||||
} | } | ||||
short CarlaPlugin::newSFZ(const initializer& init) | |||||
CarlaPlugin* CarlaPlugin::newSFZ(const initializer& init) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newSFZ(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | qDebug("CarlaPlugin::newSFZ(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | ||||
#ifdef WANT_LINUXSAMPLER | |||||
return LinuxSamplerPlugin::newLinuxSampler(init, false); | return LinuxSamplerPlugin::newLinuxSampler(init, false); | ||||
#else | |||||
setLastError("linuxsampler support not available"); | |||||
return nullptr; | |||||
#endif | |||||
} | } | ||||
/**@}*/ | /**@}*/ | ||||
@@ -17,7 +17,7 @@ | |||||
#include "carla_plugin.h" | #include "carla_plugin.h" | ||||
#include "lv2_rdf.h" | |||||
#include "carla_lv2_includes.h" | |||||
#include "sratom/sratom.h" | #include "sratom/sratom.h" | ||||
extern "C" { | extern "C" { | ||||
@@ -142,6 +142,7 @@ const uint32_t CARLA_URI_MAP_ID_COUNT = 12; | |||||
/**@}*/ | /**@}*/ | ||||
enum Lv2ParameterDataType { | enum Lv2ParameterDataType { | ||||
LV2_PARAMETER_TYPE_NULL, | |||||
LV2_PARAMETER_TYPE_CONTROL | LV2_PARAMETER_TYPE_CONTROL | ||||
}; | }; | ||||
@@ -153,6 +154,10 @@ struct EventData { | |||||
LV2_Event_Buffer* event; | LV2_Event_Buffer* event; | ||||
LV2_MIDI* midi; | LV2_MIDI* midi; | ||||
}; | }; | ||||
EventData() | |||||
: type(0), | |||||
port(nullptr) {} | |||||
}; | }; | ||||
struct Lv2ParameterData { | struct Lv2ParameterData { | ||||
@@ -160,26 +165,35 @@ struct Lv2ParameterData { | |||||
union { | union { | ||||
float control; | float control; | ||||
}; | }; | ||||
Lv2ParameterData() | |||||
: type(LV2_PARAMETER_TYPE_NULL) {} | |||||
}; | }; | ||||
struct PluginEventData { | struct PluginEventData { | ||||
uint32_t count; | uint32_t count; | ||||
EventData* data; | EventData* data; | ||||
PluginEventData() | |||||
: count(0), | |||||
data(nullptr) {} | |||||
}; | }; | ||||
const char* lv2bridge2str(LV2_Property type) | |||||
const char* lv2bridge2str(const LV2_Property type) | |||||
{ | { | ||||
switch (type) | switch (type) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
case LV2_UI_GTK2: | case LV2_UI_GTK2: | ||||
return carla_options.bridge_lv2gtk2; | |||||
return carlaOptions.bridge_lv2gtk2; | |||||
case LV2_UI_QT4: | case LV2_UI_QT4: | ||||
return carla_options.bridge_lv2qt4; | |||||
//case LV2_UI_HWND: | |||||
// return carla_options.bridge_lv2hwnd; | |||||
return carlaOptions.bridge_lv2qt4; | |||||
case LV2_UI_COCOA: | |||||
return nullptr; //carlaOptions.bridge_lv2cocoa; | |||||
case LV2_UI_WINDOWS: | |||||
return nullptr; //carlaOptions.bridge_lv2hwnd; | |||||
case LV2_UI_X11: | case LV2_UI_X11: | ||||
return carla_options.bridge_lv2x11; | |||||
return carlaOptions.bridge_lv2x11; | |||||
#endif | #endif | ||||
default: | default: | ||||
return nullptr; | return nullptr; | ||||
@@ -195,7 +209,7 @@ public: | |||||
m_type = PLUGIN_LV2; | m_type = PLUGIN_LV2; | ||||
handle = nullptr; | |||||
handle = h2 = nullptr; | |||||
descriptor = nullptr; | descriptor = nullptr; | ||||
rdf_descriptor = nullptr; | rdf_descriptor = nullptr; | ||||
@@ -267,8 +281,8 @@ public: | |||||
case GUI_EXTERNAL_OSC: | case GUI_EXTERNAL_OSC: | ||||
if (osc.data.target) | if (osc.data.target) | ||||
{ | { | ||||
//osc_send_hide(&osc.data); | |||||
//osc_send_quit(&osc.data); | |||||
osc_send_hide(&osc.data); | |||||
osc_send_quit(&osc.data); | |||||
} | } | ||||
if (osc.thread) | if (osc.thread) | ||||
@@ -289,7 +303,7 @@ public: | |||||
delete osc.thread; | delete osc.thread; | ||||
} | } | ||||
//osc_clear_data(&osc.data); | |||||
osc_clear_data(&osc.data); | |||||
break; | break; | ||||
#endif | #endif | ||||
@@ -330,11 +344,24 @@ public: | |||||
uiLibClose(); | uiLibClose(); | ||||
} | } | ||||
if (handle && descriptor && descriptor->deactivate && m_activeBefore) | |||||
descriptor->deactivate(handle); | |||||
if (descriptor) | |||||
{ | |||||
if (descriptor->deactivate && m_activeBefore) | |||||
{ | |||||
if (handle) | |||||
descriptor->deactivate(handle); | |||||
if (h2) | |||||
descriptor->deactivate(handle); | |||||
} | |||||
if (handle && descriptor && descriptor->cleanup) | |||||
descriptor->cleanup(handle); | |||||
if (descriptor->cleanup) | |||||
{ | |||||
if (handle) | |||||
descriptor->cleanup(handle); | |||||
if (h2) | |||||
descriptor->cleanup(h2); | |||||
} | |||||
} | |||||
if (rdf_descriptor) | if (rdf_descriptor) | ||||
lv2_rdf_free(rdf_descriptor); | lv2_rdf_free(rdf_descriptor); | ||||
@@ -416,7 +443,7 @@ public: | |||||
if (LV2_IS_UTILITY(Category)) | if (LV2_IS_UTILITY(Category)) | ||||
return PLUGIN_CATEGORY_UTILITY; | return PLUGIN_CATEGORY_UTILITY; | ||||
return get_category_from_name(m_name); | |||||
return getPluginCategoryFromName(m_name); | |||||
} | } | ||||
long uniqueId() | long uniqueId() | ||||
@@ -683,7 +710,7 @@ public: | |||||
if (ext.state) | if (ext.state) | ||||
{ | { | ||||
const char* const stype = customdatatype2str(type); | |||||
const char* const stype = getCustomDataTypeString(type); | |||||
LV2_State_Status status; | LV2_State_Status status; | ||||
if (x_engine->isOffline()) | if (x_engine->isOffline()) | ||||
@@ -747,8 +774,8 @@ public: | |||||
// osc_send_midi_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program, false); | // osc_send_midi_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program, false); | ||||
//else | //else | ||||
#endif | #endif | ||||
if (ext.uiprograms) | |||||
ext.uiprograms->select_program(ui.handle, midiprog.data[index].bank, midiprog.data[index].program); | |||||
if (ext.uiprograms) | |||||
ext.uiprograms->select_program(ui.handle, midiprog.data[index].bank, midiprog.data[index].program); | |||||
} | } | ||||
} | } | ||||
@@ -1071,7 +1098,7 @@ public: | |||||
if (LV2_IS_PORT_AUDIO(PortType) || LV2_IS_PORT_ATOM_SEQUENCE(PortType) || LV2_IS_PORT_CV(PortType) || LV2_IS_PORT_EVENT(PortType) || LV2_IS_PORT_MIDI_LL(PortType)) | if (LV2_IS_PORT_AUDIO(PortType) || LV2_IS_PORT_ATOM_SEQUENCE(PortType) || LV2_IS_PORT_CV(PortType) || LV2_IS_PORT_EVENT(PortType) || LV2_IS_PORT_MIDI_LL(PortType)) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":"); | strcat(portName, ":"); | ||||
@@ -1379,7 +1406,7 @@ public: | |||||
if (needsCin) | if (needsCin) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-in"); | strcat(portName, ":control-in"); | ||||
@@ -1394,7 +1421,7 @@ public: | |||||
if (needsCout) | if (needsCout) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-out"); | strcat(portName, ":control-out"); | ||||
@@ -1822,7 +1849,7 @@ public: | |||||
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | ||||
{ | { | ||||
if (! extMidiNotes[i].valid) | |||||
if (extMidiNotes[i].channel < 0) | |||||
break; | break; | ||||
uint8_t midiEvent[4] = { 0 }; | uint8_t midiEvent[4] = { 0 }; | ||||
@@ -1855,7 +1882,7 @@ public: | |||||
} | } | ||||
} | } | ||||
extMidiNotes[i].valid = false; | |||||
extMidiNotes[i].channel = -1; | |||||
midiEventCount += 1; | midiEventCount += 1; | ||||
} | } | ||||
@@ -2467,7 +2494,7 @@ public: | |||||
if (dtype == CUSTOM_DATA_INVALID) | if (dtype == CUSTOM_DATA_INVALID) | ||||
{ | { | ||||
qCritical("Lv2Plugin::carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i) - Invalid type '%s'", handle, key, value, size, type, flags, customdatatype2str(dtype)); | |||||
qCritical("Lv2Plugin::carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i) - Invalid type '%s'", handle, key, value, size, type, flags, CustomDataType2str(dtype)); | |||||
return LV2_STATE_ERR_BAD_TYPE; | return LV2_STATE_ERR_BAD_TYPE; | ||||
} | } | ||||
@@ -2561,7 +2588,7 @@ public: | |||||
return chunk.constData(); | return chunk.constData(); | ||||
} | } | ||||
qCritical("Lv2Plugin::carla_lv2_state_retrieve(%p, %i, %p, %p, %p) - Invalid key type '%s'", handle, key, size, type, flags, customdatatype2str(dtype)); | |||||
qCritical("Lv2Plugin::carla_lv2_state_retrieve(%p, %i, %p, %p, %p) - Invalid key type '%s'", handle, key, size, type, flags, CustomDataType2str(dtype)); | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
@@ -3089,7 +3116,7 @@ public: | |||||
if (! rdf_descriptor) | if (! rdf_descriptor) | ||||
{ | { | ||||
set_last_error("Failed to find the requested plugin in the LV2 Bundle"); | |||||
setLastError("Failed to find the requested plugin in the LV2 Bundle"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3098,7 +3125,7 @@ public: | |||||
if (! libOpen(rdf_descriptor->Binary)) | if (! libOpen(rdf_descriptor->Binary)) | ||||
{ | { | ||||
set_last_error(libError(rdf_descriptor->Binary)); | |||||
setLastError(libError(rdf_descriptor->Binary)); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3109,7 +3136,7 @@ public: | |||||
if (! descfn) | if (! descfn) | ||||
{ | { | ||||
set_last_error("Could not find the LV2 Descriptor in the plugin library"); | |||||
setLastError("Could not find the LV2 Descriptor in the plugin library"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3125,7 +3152,7 @@ public: | |||||
if (! descriptor) | if (! descriptor) | ||||
{ | { | ||||
set_last_error("Could not find the requested plugin URI in the plugin library"); | |||||
setLastError("Could not find the requested plugin URI in the plugin library"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3143,7 +3170,7 @@ public: | |||||
qCritical("Got unsupported port -> %i", PortType); | qCritical("Got unsupported port -> %i", PortType); | ||||
if (! LV2_IS_PORT_OPTIONAL(rdf_descriptor->Ports[i].Properties)) | if (! LV2_IS_PORT_OPTIONAL(rdf_descriptor->Ports[i].Properties)) | ||||
{ | { | ||||
set_last_error("Plugin requires a port that is not currently supported"); | |||||
setLastError("Plugin requires a port that is not currently supported"); | |||||
canContinue = false; | canContinue = false; | ||||
break; | break; | ||||
} | } | ||||
@@ -3156,7 +3183,7 @@ public: | |||||
if (LV2_IS_FEATURE_REQUIRED(rdf_descriptor->Features[i].Type) && is_lv2_feature_supported(rdf_descriptor->Features[i].URI) == false) | if (LV2_IS_FEATURE_REQUIRED(rdf_descriptor->Features[i].Type) && is_lv2_feature_supported(rdf_descriptor->Features[i].URI) == false) | ||||
{ | { | ||||
QString msg = QString("Plugin requires a feature that is not supported:\n%1").arg(rdf_descriptor->Features[i].URI); | QString msg = QString("Plugin requires a feature that is not supported:\n%1").arg(rdf_descriptor->Features[i].URI); | ||||
set_last_error(msg.toUtf8().constData()); | |||||
setLastError(msg.toUtf8().constData()); | |||||
canContinue = false; | canContinue = false; | ||||
break; | break; | ||||
} | } | ||||
@@ -3279,7 +3306,7 @@ public: | |||||
if (! handle) | if (! handle) | ||||
{ | { | ||||
set_last_error("Plugin failed to initialize"); | |||||
setLastError("Plugin failed to initialize"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3300,7 +3327,7 @@ public: | |||||
if (! x_client->isOk()) | if (! x_client->isOk()) | ||||
{ | { | ||||
set_last_error("Failed to register plugin client"); | |||||
setLastError("Failed to register plugin client"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -3323,15 +3350,15 @@ public: | |||||
{ | { | ||||
case LV2_UI_QT4: | case LV2_UI_QT4: | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||||
if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||||
eQt4 = i; | eQt4 = i; | ||||
#endif | #endif | ||||
iQt4 = i; | iQt4 = i; | ||||
break; | break; | ||||
case LV2_UI_HWND: | |||||
case LV2_UI_WINDOWS: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||||
if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||||
eHWND = i; | eHWND = i; | ||||
#endif | #endif | ||||
iHWND = i; | iHWND = i; | ||||
@@ -3339,7 +3366,7 @@ public: | |||||
case LV2_UI_X11: | case LV2_UI_X11: | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||||
if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||||
eX11 = i; | eX11 = i; | ||||
#endif | #endif | ||||
iX11 = i; | iX11 = i; | ||||
@@ -3350,7 +3377,7 @@ public: | |||||
if (false) | if (false) | ||||
#else | #else | ||||
# ifdef HAVE_SUIL | # ifdef HAVE_SUIL | ||||
if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||||
if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||||
# else | # else | ||||
if (isUiBridgeable(i)) | if (isUiBridgeable(i)) | ||||
# endif | # endif | ||||
@@ -3569,8 +3596,14 @@ public: | |||||
updateUi(); | updateUi(); | ||||
break; | break; | ||||
case LV2_UI_HWND: | |||||
qDebug("Will use LV2 HWND UI"); | |||||
case LV2_UI_COCOA: | |||||
qDebug("Will use LV2 Cocoa UI"); | |||||
gui.type = GUI_INTERNAL_COCOA; | |||||
gui.resizable = isUiResizable(); | |||||
break; | |||||
case LV2_UI_WINDOWS: | |||||
qDebug("Will use LV2 Windows UI"); | |||||
gui.type = GUI_INTERNAL_HWND; | gui.type = GUI_INTERNAL_HWND; | ||||
gui.resizable = isUiResizable(); | gui.resizable = isUiResizable(); | ||||
break; | break; | ||||
@@ -3629,7 +3662,7 @@ public: | |||||
} | } | ||||
private: | private: | ||||
LV2_Handle handle; | |||||
LV2_Handle handle, h2; | |||||
const LV2_Descriptor* descriptor; | const LV2_Descriptor* descriptor; | ||||
const LV2_RDF_Descriptor* rdf_descriptor; | const LV2_RDF_Descriptor* rdf_descriptor; | ||||
LV2_Feature* features[lv2_feature_count+1]; | LV2_Feature* features[lv2_feature_count+1]; | ||||
@@ -3671,45 +3704,46 @@ private: | |||||
std::vector<const char*> customURIDs; | std::vector<const char*> customURIDs; | ||||
}; | }; | ||||
short CarlaPlugin::newLV2(const initializer& init) | |||||
CarlaPlugin* CarlaPlugin::newLV2(const initializer& init) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newLV2(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | qDebug("CarlaPlugin::newLV2(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | ||||
short id = init.engine->getNewPluginIndex(); | |||||
short id = init.engine->getNewPluginId(); | |||||
if (id < 0) | if (id < 0) | ||||
{ | { | ||||
set_last_error("Maximum number of plugins reached"); | |||||
return -1; | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | } | ||||
Lv2Plugin* plugin = new Lv2Plugin(init.engine, id); | |||||
Lv2Plugin* const plugin = new Lv2Plugin(init.engine, id); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
plugin->reload(); | plugin->reload(); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
{ | { | ||||
if (/* inputs */ ((plugin->audioInCount() != 0 && plugin->audioInCount() != 2)) || /* outputs */ ((plugin->audioOutCount() != 0 && plugin->audioOutCount() != 2))) | |||||
uint32_t ins = plugin->audioInCount(); | |||||
uint32_t outs = plugin->audioOutCount(); | |||||
if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | |||||
{ | { | ||||
set_last_error("Carla Rack Mode can only work with Stereo plugins, sorry!"); | |||||
setLastError("Carla's Rack Mode can only work with Mono or Stereo LV2 plugins, sorry!"); | |||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
plugin->registerToOsc(); | plugin->registerToOsc(); | ||||
init.engine->addPlugin(id, plugin); | |||||
return id; | |||||
return plugin; | |||||
} | } | ||||
/**@}*/ | /**@}*/ | ||||
@@ -3718,19 +3752,23 @@ CARLA_BACKEND_END_NAMESPACE | |||||
// ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
int osc_handle_lv2_atom_transfer(CarlaBackend::CarlaPlugin* plugin, lo_arg** /*argv*/) | |||||
int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2) | |||||
{ | { | ||||
CarlaBackend::Lv2Plugin* lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
qDebug("CarlaOsc::handle_lv2_atom_transfer()"); | |||||
//CARLA_OSC_CHECK_OSC_TYPES(2, "ii"); | |||||
CarlaBackend::Lv2Plugin* lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
lv2plugin->handleAtomTransfer(); | lv2plugin->handleAtomTransfer(); | ||||
return 0; | return 0; | ||||
} | } | ||||
int osc_handle_lv2_event_transfer(CarlaBackend::CarlaPlugin* plugin, lo_arg** argv) | |||||
int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2) | |||||
{ | { | ||||
CarlaBackend::Lv2Plugin* lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
qDebug("CarlaOsc::handle_lv2_event_transfer()"); | |||||
CARLA_OSC_CHECK_OSC_TYPES(3, "sss"); | |||||
CarlaBackend::Lv2Plugin* lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
const char* type = (const char*)&argv[0]->s; | const char* type = (const char*)&argv[0]->s; | ||||
const char* key = (const char*)&argv[1]->s; | const char* key = (const char*)&argv[1]->s; | ||||
const char* value = (const char*)&argv[2]->s; | const char* value = (const char*)&argv[2]->s; | ||||
@@ -15,16 +15,16 @@ SOURCES = \ | |||||
../carla_engine.cpp \ | ../carla_engine.cpp \ | ||||
../carla_engine_jack.cpp \ | ../carla_engine_jack.cpp \ | ||||
../carla_engine_rtaudio.cpp \ | ../carla_engine_rtaudio.cpp \ | ||||
# ../carla_bridge.cpp \ | |||||
../carla_bridge.cpp \ | |||||
../carla_osc.cpp \ | ../carla_osc.cpp \ | ||||
../carla_shared.cpp \ | ../carla_shared.cpp \ | ||||
../carla_threads.cpp \ | ../carla_threads.cpp \ | ||||
../ladspa.cpp \ | ../ladspa.cpp \ | ||||
# ../dssi.cpp \ | |||||
# ../lv2.cpp \ | |||||
# ../vst.cpp \ | |||||
# ../fluidsynth.cpp \ | |||||
# ../linuxsampler.cpp \ | |||||
../dssi.cpp \ | |||||
../lv2.cpp \ | |||||
../vst.cpp \ | |||||
../fluidsynth.cpp \ | |||||
../linuxsampler.cpp \ | |||||
../lv2-rtmempool/rtmempool.c | ../lv2-rtmempool/rtmempool.c | ||||
HEADERS = \ | HEADERS = \ | ||||
@@ -41,6 +41,7 @@ HEADERS = \ | |||||
../../carla-includes/carla_ladspa_includes.h \ | ../../carla-includes/carla_ladspa_includes.h \ | ||||
../../carla-includes/carla_lv2_includes.h \ | ../../carla-includes/carla_lv2_includes.h \ | ||||
../../carla-includes/carla_vst_includes.h \ | ../../carla-includes/carla_vst_includes.h \ | ||||
../../carla-includes/carla_linuxsampler_includes.h \ | |||||
../../carla-includes/carla_midi.h \ | ../../carla-includes/carla_midi.h \ | ||||
../../carla-includes/ladspa_rdf.h \ | ../../carla-includes/ladspa_rdf.h \ | ||||
../../carla-includes/lv2_rdf.h | ../../carla-includes/lv2_rdf.h | ||||
@@ -49,7 +50,9 @@ INCLUDEPATH = .. \ | |||||
../../carla-includes \ | ../../carla-includes \ | ||||
../../carla-includes/vst | ../../carla-includes/vst | ||||
DEFINES = HAVE_SUIL WANT_FLUIDSYNTH WANT_LINUXSAMPLER | |||||
#DEFINES += HAVE_SUIL | |||||
DEFINES += WANT_FLUIDSYNTH | |||||
#DEFINES += WANT_LINUXSAMPLER | |||||
DEFINES += CARLA_ENGINE_JACK | DEFINES += CARLA_ENGINE_JACK | ||||
#DEFINES += CARLA_ENGINE_RTAUDIO | #DEFINES += CARLA_ENGINE_RTAUDIO | ||||
DEFINES += QTCREATOR_TEST | DEFINES += QTCREATOR_TEST | ||||
@@ -114,7 +114,7 @@ public: | |||||
if (effect->flags & effFlagsIsSynth) | if (effect->flags & effFlagsIsSynth) | ||||
return PLUGIN_CATEGORY_SYNTH; | return PLUGIN_CATEGORY_SYNTH; | ||||
return get_category_from_name(m_name); | |||||
return getPluginCategoryFromName(m_name); | |||||
} | } | ||||
long uniqueId() | long uniqueId() | ||||
@@ -364,7 +364,7 @@ public: | |||||
for (j=0; j<ains; j++) | for (j=0; j<ains; j++) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
sprintf(portName, "%s:input_%02i", m_name, j+1); | sprintf(portName, "%s:input_%02i", m_name, j+1); | ||||
else | else | ||||
#endif | #endif | ||||
@@ -377,7 +377,7 @@ public: | |||||
for (j=0; j<aouts; j++) | for (j=0; j<aouts; j++) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
sprintf(portName, "%s:output_%02i", m_name, j+1); | sprintf(portName, "%s:output_%02i", m_name, j+1); | ||||
else | else | ||||
#endif | #endif | ||||
@@ -492,7 +492,7 @@ public: | |||||
if (needsCin) | if (needsCin) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":control-in"); | strcat(portName, ":control-in"); | ||||
@@ -507,7 +507,7 @@ public: | |||||
if (mins == 1) | if (mins == 1) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":midi-in"); | strcat(portName, ":midi-in"); | ||||
@@ -522,7 +522,7 @@ public: | |||||
if (mouts == 1) | if (mouts == 1) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||||
{ | { | ||||
strcpy(portName, m_name); | strcpy(portName, m_name); | ||||
strcat(portName, ":midi-out"); | strcat(portName, ":midi-out"); | ||||
@@ -874,7 +874,7 @@ public: | |||||
for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | ||||
{ | { | ||||
if (! extMidiNotes[i].valid) | |||||
if (extMidiNotes[i].channel < 0) | |||||
break; | break; | ||||
VstMidiEvent* const midiEvent = &midiEvents[midiEventCount]; | VstMidiEvent* const midiEvent = &midiEvents[midiEventCount]; | ||||
@@ -887,7 +887,7 @@ public: | |||||
midiEvent->midiData[1] = extMidiNotes[i].note; | midiEvent->midiData[1] = extMidiNotes[i].note; | ||||
midiEvent->midiData[2] = extMidiNotes[i].velo; | midiEvent->midiData[2] = extMidiNotes[i].velo; | ||||
extMidiNotes[i].valid = false; | |||||
extMidiNotes[i].channel = -1; | |||||
midiEventCount += 1; | midiEventCount += 1; | ||||
} | } | ||||
@@ -1206,7 +1206,7 @@ public: | |||||
#else | #else | ||||
if (effect && effect->resvd1) | if (effect && effect->resvd1) | ||||
{ | { | ||||
self = (VstPlugin*)get_pointer(effect->resvd1); | |||||
self = (VstPlugin*)getPointer(effect->resvd1); | |||||
#endif | #endif | ||||
if (self->unique1 != self->unique2) | if (self->unique1 != self->unique2) | ||||
self = nullptr; | self = nullptr; | ||||
@@ -1342,7 +1342,7 @@ public: | |||||
#ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
return MAX_PARAMETERS; | return MAX_PARAMETERS; | ||||
#else | #else | ||||
return carla_options.max_parameters; | |||||
return carlaOptions.max_parameters; | |||||
#endif | #endif | ||||
case audioMasterGetParameterQuantization: | case audioMasterGetParameterQuantization: | ||||
@@ -1610,7 +1610,7 @@ public: | |||||
if (! libOpen(filename)) | if (! libOpen(filename)) | ||||
{ | { | ||||
set_last_error(libError(filename)); | |||||
setLastError(libError(filename)); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1625,7 +1625,7 @@ public: | |||||
if (! vstfn) | if (! vstfn) | ||||
{ | { | ||||
set_last_error("Could not find the VST main entry in the plugin library"); | |||||
setLastError("Could not find the VST main entry in the plugin library"); | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
@@ -1637,7 +1637,7 @@ public: | |||||
if (! effect || effect->magic != kEffectMagic) | if (! effect || effect->magic != kEffectMagic) | ||||
{ | { | ||||
set_last_error("Plugin failed to initialize"); | |||||
setLastError("Plugin failed to initialize"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1693,7 +1693,7 @@ public: | |||||
if (! x_client->isOk()) | if (! x_client->isOk()) | ||||
{ | { | ||||
set_last_error("Failed to register plugin client"); | |||||
setLastError("Failed to register plugin client"); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -1730,45 +1730,44 @@ private: | |||||
int unique2; | int unique2; | ||||
}; | }; | ||||
short CarlaPlugin::newVST(const initializer& init) | |||||
CarlaPlugin* CarlaPlugin::newVST(const initializer& init) | |||||
{ | { | ||||
qDebug("CarlaPlugin::newVST(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | qDebug("CarlaPlugin::newVST(%p, %s, %s, %s)", init.engine, init.filename, init.name, init.label); | ||||
short id = init.engine->getNewPluginIndex(); | |||||
short id = init.engine->getNewPluginId(); | |||||
if (id < 0) | if (id < 0) | ||||
{ | { | ||||
set_last_error("Maximum number of plugins reached"); | |||||
return -1; | |||||
setLastError("Maximum number of plugins reached"); | |||||
return nullptr; | |||||
} | } | ||||
VstPlugin* plugin = new VstPlugin(init.engine, id); | |||||
VstPlugin* const plugin = new VstPlugin(init.engine, id); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
plugin->reload(); | plugin->reload(); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (carla_options.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
if (carlaOptions.process_mode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
{ | { | ||||
if (/* inputs */ ((plugin->audioInCount() != 0 && plugin->audioInCount() != 2)) || /* outputs */ ((plugin->audioOutCount() != 0 && plugin->audioOutCount() != 2))) | if (/* inputs */ ((plugin->audioInCount() != 0 && plugin->audioInCount() != 2)) || /* outputs */ ((plugin->audioOutCount() != 0 && plugin->audioOutCount() != 2))) | ||||
{ | { | ||||
set_last_error("Carla Rack Mode can only work with Stereo plugins, sorry!"); | |||||
setLastError("Carla Rack Mode can only work with Stereo VST plugins, sorry!"); | |||||
delete plugin; | delete plugin; | ||||
return -1; | |||||
return nullptr; | |||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
plugin->registerToOsc(); | plugin->registerToOsc(); | ||||
init.engine->addPlugin(id, plugin); | |||||
return id; | |||||
return plugin; | |||||
} | } | ||||
/**@}*/ | /**@}*/ | ||||
@@ -95,9 +95,9 @@ void osc_send_program(const CarlaOscData* const oscData, const int index) | |||||
} | } | ||||
static inline | static inline | ||||
void osc_send_program(const CarlaOscData* const oscData, const int program, const int bank) | |||||
void osc_send_program(const CarlaOscData* const oscData, const int bank, const int program) | |||||
{ | { | ||||
qDebug("osc_send_program(%s, %i, %i)", oscData->path, program, bank); | |||||
qDebug("osc_send_program(%s, %i, %i)", oscData->path, bank, program); | |||||
assert(program >= 0); | assert(program >= 0); | ||||
assert(bank >= 0); | assert(bank >= 0); | ||||
@@ -106,7 +106,7 @@ void osc_send_program(const CarlaOscData* const oscData, const int program, cons | |||||
char targetPath[strlen(oscData->path)+9]; | char targetPath[strlen(oscData->path)+9]; | ||||
strcpy(targetPath, oscData->path); | strcpy(targetPath, oscData->path); | ||||
strcat(targetPath, "/program"); | strcat(targetPath, "/program"); | ||||
lo_send(oscData->target, targetPath, "ii", program, bank); | |||||
lo_send(oscData->target, targetPath, "ii", bank, program); | |||||
} | } | ||||
} | } | ||||
@@ -1,47 +0,0 @@ | |||||
/*************************************************************************** | |||||
* * | |||||
* Copyright (C) 2005-2007 Christian Schoenebeck * | |||||
* * | |||||
* This program is free software; you can redistribute it and/or modify * | |||||
* it under the terms of the GNU General Public License as published by * | |||||
* the Free Software Foundation; either version 2 of the License, or * | |||||
* (at your option) any later version. * | |||||
* * | |||||
* This program is distributed in the hope that it will be useful, * | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||||
* GNU General Public License for more details. * | |||||
* * | |||||
* You should have received a copy of the GNU General Public License * | |||||
* along with this program; if not, write to the Free Software * | |||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, * | |||||
* MA 02111-1307 USA * | |||||
***************************************************************************/ | |||||
#ifndef __LS_ENGINEFACTORY_H__ | |||||
#define __LS_ENGINEFACTORY_H__ | |||||
#include <linuxsampler/common/global.h> | |||||
#include <linuxsampler/common/Exception.h> | |||||
#include <linuxsampler/engines/Engine.h> | |||||
#include <set> | |||||
#include <vector> | |||||
namespace LinuxSampler { | |||||
class EngineFactory { | |||||
public: | |||||
static std::vector<String> AvailableEngineTypes(); | |||||
static String AvailableEngineTypesAsString(); | |||||
static Engine* Create(String EngineType) throw (Exception); | |||||
static void Destroy(Engine* pEngine); | |||||
static const std::set<Engine*>& EngineInstances(); | |||||
protected: | |||||
static void Erase(Engine* pEngine); | |||||
friend class Engine; | |||||
}; | |||||
} // namespace LinuxSampler | |||||
#endif // __LS_ENGINEFACTORY_H__ |
@@ -2337,7 +2337,7 @@ class PluginWidget(QFrame, ui_carla_plugin.Ui_PluginWidget): | |||||
parameter_info = CarlaHost.get_parameter_info(self.plugin_id, i) | parameter_info = CarlaHost.get_parameter_info(self.plugin_id, i) | ||||
parameter_data = CarlaHost.get_parameter_data(self.plugin_id, i) | parameter_data = CarlaHost.get_parameter_data(self.plugin_id, i) | ||||
if (not parameter_info['valid']) or parameter_data['type'] != PARAMETER_INPUT: | |||||
if parameter_data['type'] != PARAMETER_INPUT: | |||||
continue | continue | ||||
x_save_state_parameter = deepcopy(save_state_parameter) | x_save_state_parameter = deepcopy(save_state_parameter) | ||||