| @@ -4,34 +4,36 @@ | |||
| # Created by falkTX | |||
| # | |||
| # backend ouput driver, default JACK | |||
| driver = JACK | |||
| # driver = RtAudio | |||
| CC ?= gcc | |||
| CXX ?= g++ | |||
| 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_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) | |||
| CARLA_C_FLAGS = $(BASE_FLAGS) $(CFLAGS) | |||
| 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 += -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) | |||
| CARLA_CXX_FLAGS += $(shell pkg-config --cflags fluidsynth) -DWANT_FLUIDSYNTH | |||
| @@ -49,8 +51,9 @@ CARLA_LD_FLAGS += $(shell pkg-config --libs suil-0) | |||
| endif | |||
| OBJS = \ | |||
| carla_backend.o \ | |||
| carla_backend_standalone.o \ | |||
| carla_bridge.o \ | |||
| carla_engine.o \ | |||
| carla_engine_jack.o \ | |||
| carla_engine_rtaudio.o \ | |||
| carla_osc.o \ | |||
| @@ -60,11 +63,11 @@ OBJS = \ | |||
| lv2-rtmempool/rtmempool.o \ | |||
| ../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(); | |||
| for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++) | |||
| remove_plugin(i); | |||
| carla_engine->removeAllPlugins(); | |||
| // cleanup static data | |||
| 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) | |||
| { | |||
| qDebug("Callback(%i, %u, %i, %i, %f)", action, plugin_id, value1, value2, value3); | |||
| switch (action) | |||
| { | |||
| case CarlaBackend::CALLBACK_SHOW_GUI: | |||
| @@ -1156,6 +1152,9 @@ void main_callback(CarlaBackend::CallbackType action, unsigned short plugin_id, | |||
| default: | |||
| break; | |||
| } | |||
| Q_UNUSED(plugin_id); | |||
| Q_UNUSED(value3); | |||
| } | |||
| 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); | |||
| gui = new QDialog(nullptr); | |||
| set_option(CarlaBackend::OPTION_PREFER_UI_BRIDGES, 0, nullptr); | |||
| if (engine_init("JACK", "carla_demo")) | |||
| { | |||
| 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) | |||
| { | |||
| @@ -58,7 +58,7 @@ public: | |||
| params = nullptr; | |||
| m_thread = new CarlaPluginThread(this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE); | |||
| m_thread = new CarlaPluginThread(engine, this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE); | |||
| } | |||
| ~BridgePlugin() | |||
| @@ -193,13 +193,13 @@ public: | |||
| 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) | |||
| info->type = GUI_EXTERNAL_OSC; | |||
| *type = GUI_EXTERNAL_OSC; | |||
| else | |||
| info->type = GUI_NONE; | |||
| info->resizable = false; | |||
| *type = GUI_NONE; | |||
| *resizable = false; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -252,7 +252,7 @@ public: | |||
| } | |||
| // 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) | |||
| { | |||
| @@ -476,7 +476,7 @@ public: | |||
| const char* key = (const char*)&argv[1]->s; | |||
| const char* value = (const char*)&argv[2]->s; | |||
| setCustomData(customdatastr2type(stype), key, value, false); | |||
| setCustomData(getCustomDataStringType(stype), key, value, false); | |||
| break; | |||
| } | |||
| @@ -529,7 +529,7 @@ public: | |||
| if (sendGui) | |||
| { | |||
| QString cData; | |||
| cData += customdatatype2str(type); | |||
| cData += getCustomDataTypeString(type); | |||
| cData += "·"; | |||
| cData += key; | |||
| cData += "·"; | |||
| @@ -574,7 +574,7 @@ public: | |||
| assert(index < (int32_t)midiprog.count); | |||
| 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); | |||
| } | |||
| @@ -634,11 +634,11 @@ public: | |||
| 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) | |||
| { | |||
| set_last_error("Bridge not possible, bridge-binary not found"); | |||
| setLastError("Bridge not possible, bridge-binary not found"); | |||
| return false; | |||
| } | |||
| @@ -648,9 +648,9 @@ public: | |||
| m_name = x_engine->getUniqueName(name); | |||
| // 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(); | |||
| for (int i=0; i < 100; i++) | |||
| @@ -662,8 +662,11 @@ public: | |||
| if (! initiated) | |||
| { | |||
| // unregister so it gets handled properly | |||
| x_engine->__bridgePluginRegister(m_id, nullptr); | |||
| 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; | |||
| } | |||
| @@ -692,32 +695,42 @@ private: | |||
| 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); | |||
| 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; | |||
| id = -1; | |||
| return nullptr; | |||
| } | |||
| } | |||
| else | |||
| set_last_error("Maximum number of plugins reached"); | |||
| return id; | |||
| plugin->registerToOsc(); | |||
| return plugin; | |||
| } | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| @@ -194,7 +194,7 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||
| return -1; | |||
| # endif | |||
| //plugin = CarlaPlugin::newBridge(init, btype, ptype); | |||
| plugin = CarlaPlugin::newBridge(init, btype, ptype); | |||
| } | |||
| else | |||
| #endif | |||
| @@ -207,22 +207,22 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||
| plugin = CarlaPlugin::newLADSPA(init, extra); | |||
| break; | |||
| case PLUGIN_DSSI: | |||
| //id = CarlaPlugin::newDSSI(init, extra); | |||
| plugin = CarlaPlugin::newDSSI(init, extra); | |||
| break; | |||
| case PLUGIN_LV2: | |||
| //id = CarlaPlugin::newLV2(init); | |||
| plugin = CarlaPlugin::newLV2(init); | |||
| break; | |||
| case PLUGIN_VST: | |||
| //id = CarlaPlugin::newVST(init); | |||
| plugin = CarlaPlugin::newVST(init); | |||
| break; | |||
| case PLUGIN_GIG: | |||
| //id = CarlaPlugin::newGIG(init); | |||
| plugin = CarlaPlugin::newGIG(init); | |||
| break; | |||
| case PLUGIN_SF2: | |||
| //id = CarlaPlugin::newSF2(init); | |||
| plugin = CarlaPlugin::newSF2(init); | |||
| break; | |||
| case PLUGIN_SFZ: | |||
| //id = CarlaPlugin::newSFZ(init); | |||
| plugin = CarlaPlugin::newSFZ(init); | |||
| 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() | |||
| @@ -19,6 +19,7 @@ | |||
| #define CARLA_ENGINE_H | |||
| #include "carla_osc.h" | |||
| #include "carla_shared.h" | |||
| #include "carla_threads.h" | |||
| #include <cassert> | |||
| @@ -165,8 +166,20 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| // 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 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 PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | |||
| bool removePlugin(const unsigned short id); | |||
| void removeAllPlugins(); | |||
| void idlePluginGuis(); | |||
| // bridge, internal use only | |||
| void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) | |||
| { | |||
| m_carlaPlugins[id] = plugin; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // 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) | |||
| { | |||
| qDebug("CarlaEngine::callback(%s, %i, %i, %i, %f)", CallbackType2str(action), pluginId, value1, value2, value3); | |||
| if (m_callback) | |||
| m_callback(action, pluginId, value1, value2, value3); | |||
| } | |||
| void setCallback(const CallbackFunc func) | |||
| { | |||
| qDebug("CarlaEngine::setCallback(%p)", func); | |||
| m_callback = func; | |||
| } | |||
| @@ -333,16 +357,6 @@ protected: | |||
| uint32_t bufferSize; | |||
| CarlaTimeInfo timeInfo; | |||
| void oscInit() | |||
| { | |||
| m_osc.init(name); | |||
| } | |||
| void oscClose() | |||
| { | |||
| m_osc.close(); | |||
| } | |||
| void bufferSizeChanged(uint32_t newBufferSize); | |||
| private: | |||
| @@ -150,7 +150,7 @@ bool CarlaEngineJack::init(const char* const clientName) | |||
| name = strdup(fixedName); | |||
| free((void*)fixedName); | |||
| oscInit(); | |||
| CarlaEngine::init(name); | |||
| return true; | |||
| } | |||
| @@ -169,6 +169,7 @@ bool CarlaEngineJack::init(const char* const clientName) | |||
| bool CarlaEngineJack::close() | |||
| { | |||
| qDebug("CarlaEngineJack::close()"); | |||
| CarlaEngine::close(); | |||
| if (name) | |||
| { | |||
| @@ -176,8 +177,6 @@ bool CarlaEngineJack::close() | |||
| name = nullptr; | |||
| } | |||
| oscClose(); | |||
| if (jack_deactivate(client) == 0) | |||
| { | |||
| #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); | |||
| // 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 | |||
| if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE) | |||
| @@ -138,7 +138,7 @@ struct PluginParameterData { | |||
| struct PluginProgramData { | |||
| uint32_t count; | |||
| int32_t current; | |||
| const char* const* names; | |||
| const char** names; | |||
| PluginProgramData() | |||
| : count(0), | |||
| @@ -1984,14 +1984,14 @@ public: | |||
| }; | |||
| 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 | |||
| //static short newBridge(const initializer& init, BinaryType btype, PluginType ptype); | |||
| static CarlaPlugin* newBridge(const initializer& init, BinaryType btype, PluginType ptype); | |||
| #endif | |||
| // ------------------------------------------------------------------- | |||
| @@ -42,8 +42,8 @@ public: | |||
| m_type = PLUGIN_DSSI; | |||
| handle = nullptr; | |||
| descriptor = nullptr; | |||
| handle = h2 = nullptr; | |||
| descriptor = nullptr; | |||
| ldescriptor = nullptr; | |||
| param_buffers = nullptr; | |||
| @@ -61,8 +61,8 @@ public: | |||
| { | |||
| 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) | |||
| @@ -83,15 +83,28 @@ public: | |||
| delete osc.thread; | |||
| } | |||
| //osc_clear_data(&osc.data); | |||
| osc_clear_data(&osc.data); | |||
| } | |||
| #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) | |||
| return PLUGIN_CATEGORY_SYNTH; | |||
| return get_category_from_name(m_name); | |||
| return getPluginCategoryFromName(m_name); | |||
| } | |||
| long uniqueId() | |||
| @@ -187,8 +200,8 @@ public: | |||
| param_buffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]); | |||
| #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 | |||
| CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); | |||
| @@ -202,8 +215,8 @@ public: | |||
| descriptor->configure(handle, key, value); | |||
| #ifndef BUILD_BRIDGE | |||
| //if (sendGui) | |||
| //osc_send_configure(&osc.data, key, value); | |||
| if (sendGui) | |||
| osc_send_configure(&osc.data, key, value); | |||
| #endif | |||
| if (strcmp(key, "reloadprograms") == 0 || strcmp(key, "load") == 0 || strncmp(key, "patches", 7) == 0) | |||
| @@ -254,8 +267,8 @@ public: | |||
| } | |||
| #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 | |||
| } | |||
| @@ -274,9 +287,9 @@ public: | |||
| } | |||
| 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? | |||
| } | |||
| } | |||
| @@ -321,6 +334,9 @@ public: | |||
| 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) | |||
| mins = 1; | |||
| @@ -356,7 +372,7 @@ public: | |||
| if (LADSPA_IS_PORT_AUDIO(PortType)) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":"); | |||
| @@ -571,19 +587,21 @@ public: | |||
| param_buffers[j] = def; | |||
| ldescriptor->connect_port(handle, i, ¶m_buffers[j]); | |||
| if (h2) ldescriptor->connect_port(h2, i, ¶m_buffers[j]); | |||
| } | |||
| else | |||
| { | |||
| // Not Audio or Control | |||
| qCritical("ERROR - Got a broken Port (neither Audio or Control)"); | |||
| ldescriptor->connect_port(handle, i, nullptr); | |||
| if (h2) ldescriptor->connect_port(h2, i, nullptr); | |||
| } | |||
| } | |||
| if (needsCin) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-in"); | |||
| @@ -598,7 +616,7 @@ public: | |||
| if (needsCout) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-out"); | |||
| @@ -613,7 +631,7 @@ public: | |||
| if (mins > 0) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":midi-in"); | |||
| @@ -636,7 +654,7 @@ public: | |||
| m_hints |= PLUGIN_IS_SYNTH; | |||
| #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) | |||
| m_hints |= PLUGIN_USES_CHUNKS; | |||
| @@ -649,7 +667,7 @@ public: | |||
| if (aouts > 0) | |||
| 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; | |||
| reloadPrograms(true); | |||
| @@ -699,10 +717,10 @@ public: | |||
| #ifndef BUILD_BRIDGE | |||
| // 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); | |||
| #endif | |||
| @@ -767,7 +785,9 @@ public: | |||
| if (ain.count > 0) | |||
| { | |||
| if (ain.count == 1) | |||
| uint32_t count = h2 ? 2 : ain.count; | |||
| if (count == 1) | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| @@ -775,7 +795,7 @@ public: | |||
| ains_peak_tmp[0] = abs(inBuffer[0][k]); | |||
| } | |||
| } | |||
| else if (ain.count >= 1) | |||
| else if (count > 1) | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| @@ -935,10 +955,16 @@ public: | |||
| sendMidiAllNotesOff(); | |||
| if (ldescriptor->deactivate) | |||
| { | |||
| ldescriptor->deactivate(handle); | |||
| if (h2) ldescriptor->deactivate(h2); | |||
| } | |||
| if (ldescriptor->activate) | |||
| { | |||
| ldescriptor->activate(handle); | |||
| if (h2) ldescriptor->activate(h2); | |||
| } | |||
| allNotesOffSent = true; | |||
| } | |||
| @@ -968,7 +994,7 @@ public: | |||
| for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | |||
| { | |||
| if (! extMidiNotes[i].valid) | |||
| if (extMidiNotes[i].channel < 0) | |||
| break; | |||
| snd_seq_event_t* const midiEvent = &midiEvents[midiEventCount]; | |||
| @@ -980,7 +1006,7 @@ public: | |||
| midiEvent->data.note.note = extMidiNotes[i].note; | |||
| midiEvent->data.note.velocity = extMidiNotes[i].velo; | |||
| extMidiNotes[i].valid = false; | |||
| extMidiNotes[i].channel = -1; | |||
| midiEventCount += 1; | |||
| } | |||
| @@ -1122,33 +1148,51 @@ public: | |||
| } | |||
| if (ldescriptor->activate) | |||
| { | |||
| ldescriptor->activate(handle); | |||
| if (h2) ldescriptor->activate(h2); | |||
| } | |||
| } | |||
| for (i=0; i < ain.count; 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++) | |||
| { | |||
| 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) | |||
| { | |||
| descriptor->run_synth(handle, frames, midiEvents, midiEventCount); | |||
| if (h2) descriptor->run_synth(handle, frames, midiEvents, midiEventCount); | |||
| } | |||
| 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); | |||
| if (h2) ldescriptor->run(h2, frames); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (m_activeBefore) | |||
| { | |||
| if (ldescriptor->deactivate) | |||
| { | |||
| ldescriptor->deactivate(handle); | |||
| if (h2) ldescriptor->deactivate(h2); | |||
| } | |||
| } | |||
| } | |||
| @@ -1166,7 +1210,9 @@ public: | |||
| double bal_rangeL, bal_rangeR; | |||
| 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 | |||
| if (do_drywet || do_volume) | |||
| @@ -1175,7 +1221,7 @@ public: | |||
| { | |||
| 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)); | |||
| else | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_drywet)+(inBuffer[i][k]*(1.0-x_drywet)); | |||
| @@ -1292,7 +1338,7 @@ public: | |||
| if (! libOpen(filename)) | |||
| { | |||
| set_last_error(libError(filename)); | |||
| setLastError(libError(filename)); | |||
| return false; | |||
| } | |||
| @@ -1303,7 +1349,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -1320,7 +1366,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -1331,7 +1377,7 @@ public: | |||
| if (! handle) | |||
| { | |||
| set_last_error("Plugin failed to initialize"); | |||
| setLastError("Plugin failed to initialize"); | |||
| return false; | |||
| } | |||
| @@ -1352,7 +1398,7 @@ public: | |||
| if (! x_client->isOk()) | |||
| { | |||
| set_last_error("Failed to register plugin client"); | |||
| setLastError("Failed to register plugin client"); | |||
| return false; | |||
| } | |||
| @@ -1374,7 +1420,7 @@ public: | |||
| } | |||
| private: | |||
| LADSPA_Handle handle; | |||
| LADSPA_Handle handle, h2; | |||
| const LADSPA_Descriptor* ldescriptor; | |||
| const DSSI_Descriptor* descriptor; | |||
| snd_seq_event_t midiEvents[MAX_MIDI_EVENTS]; | |||
| @@ -1382,16 +1428,16 @@ private: | |||
| 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); | |||
| short id = init.engine->getNewPluginIndex(); | |||
| short id = init.engine->getNewPluginId(); | |||
| 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); | |||
| @@ -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)) | |||
| { | |||
| delete plugin; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| #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; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| } | |||
| #endif | |||
| plugin->registerToOsc(); | |||
| init.engine->addPlugin(id, plugin); | |||
| return id; | |||
| return plugin; | |||
| } | |||
| /**@}*/ | |||
| @@ -21,6 +21,12 @@ | |||
| #include "carla_plugin.h" | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| #if 0 | |||
| } /* adjust editor indent */ | |||
| #endif | |||
| #ifdef WANT_FLUIDSYNTH | |||
| #include <fluidsynth.h> | |||
| @@ -28,12 +34,6 @@ | |||
| #define FLUIDSYNTH_VERSION_NEW_API | |||
| #endif | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| #if 0 | |||
| } /* adjust editor indent */ | |||
| #endif | |||
| /*! | |||
| * @defgroup CarlaBackendFluidSynthPlugin Carla Backend FluidSynth Plugin | |||
| * | |||
| @@ -415,7 +415,7 @@ public: | |||
| // Audio Outputs | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":out-left"); | |||
| @@ -428,7 +428,7 @@ public: | |||
| aout.rindexes[0] = 0; | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":out-right"); | |||
| @@ -444,7 +444,7 @@ public: | |||
| // MIDI Input | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":midi-in"); | |||
| @@ -459,7 +459,7 @@ public: | |||
| // Parameters | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-in"); | |||
| @@ -471,7 +471,7 @@ public: | |||
| param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-out"); | |||
| @@ -1013,7 +1013,7 @@ public: | |||
| for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | |||
| { | |||
| if (! extMidiNotes[i].valid) | |||
| if (extMidiNotes[i].channel < 0) | |||
| break; | |||
| if (extMidiNotes[i].velo) | |||
| @@ -1021,7 +1021,7 @@ public: | |||
| else | |||
| fluid_synth_noteoff(f_synth, cin_channel, extMidiNotes[i].note); | |||
| extMidiNotes[i].valid = false; | |||
| extMidiNotes[i].channel = -1; | |||
| midiEventCount += 1; | |||
| } | |||
| @@ -1226,7 +1226,7 @@ public: | |||
| if (f_id < 0) | |||
| { | |||
| set_last_error("Failed to load SoundFont file"); | |||
| setLastError("Failed to load SoundFont file"); | |||
| return false; | |||
| } | |||
| @@ -1248,7 +1248,7 @@ public: | |||
| if (! x_client->isOk()) | |||
| { | |||
| set_last_error("Failed to register plugin client"); | |||
| setLastError("Failed to register plugin client"); | |||
| return false; | |||
| } | |||
| @@ -1283,23 +1283,23 @@ private: | |||
| }; | |||
| #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); | |||
| #ifdef WANT_FLUIDSYNTH | |||
| short id = init.engine->getNewPluginIndex(); | |||
| short id = init.engine->getNewPluginId(); | |||
| 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)) | |||
| { | |||
| 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); | |||
| @@ -1307,17 +1307,16 @@ short CarlaPlugin::newSF2(const initializer& init) | |||
| if (! plugin->init(init.filename, init.name, init.label)) | |||
| { | |||
| delete plugin; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| plugin->registerToOsc(); | |||
| init.engine->addPlugin(id, plugin); | |||
| return id; | |||
| return plugin; | |||
| #else | |||
| set_last_error("fluidsynth support not available"); | |||
| return -1; | |||
| setLastError("fluidsynth support not available"); | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| @@ -17,7 +17,6 @@ | |||
| #include "carla_plugin.h" | |||
| #include "carla_ladspa_includes.h" | |||
| #include "carla_lv2_includes.h" | |||
| 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)) | |||
| { | |||
| 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; | |||
| return nullptr; | |||
| } | |||
| @@ -19,11 +19,10 @@ | |||
| #error Should not use linuxsampler for bridges! | |||
| #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> | |||
| @@ -33,6 +32,8 @@ CARLA_BACKEND_START_NAMESPACE | |||
| } /* adjust editor indent */ | |||
| #endif | |||
| #ifdef WANT_LINUXSAMPLER | |||
| /*! | |||
| * @defgroup CarlaBackendLinuxSamplerPlugin Carla Backend LinuxSampler Plugin | |||
| * | |||
| @@ -40,118 +41,6 @@ CARLA_BACKEND_START_NAMESPACE | |||
| * 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 | |||
| { | |||
| public: | |||
| @@ -160,6 +49,7 @@ public: | |||
| qDebug("LinuxSamplerPlugin::LinuxSamplerPlugin()"); | |||
| m_type = isGIG ? PLUGIN_GIG : PLUGIN_SFZ; | |||
| sampler = new LinuxSampler::Sampler; | |||
| sampler_channel = nullptr; | |||
| @@ -263,7 +153,7 @@ public: | |||
| // Audio Outputs | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":out-left"); | |||
| @@ -276,7 +166,7 @@ public: | |||
| aout.rindexes[0] = 0; | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":out-right"); | |||
| @@ -292,7 +182,7 @@ public: | |||
| // MIDI Input | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":midi-in"); | |||
| @@ -592,7 +482,7 @@ public: | |||
| } | |||
| catch (LinuxSampler::Exception& e) | |||
| { | |||
| set_last_error(e.what()); | |||
| setLastError(e.what()); | |||
| return false; | |||
| } | |||
| @@ -601,7 +491,7 @@ public: | |||
| } | |||
| catch (LinuxSampler::Exception& e) | |||
| { | |||
| set_last_error(e.what()); | |||
| setLastError(e.what()); | |||
| return false; | |||
| } | |||
| @@ -610,7 +500,7 @@ public: | |||
| } | |||
| catch (LinuxSampler::Exception& e) | |||
| { | |||
| set_last_error(e.what()); | |||
| setLastError(e.what()); | |||
| return false; | |||
| } | |||
| @@ -645,20 +535,20 @@ public: | |||
| if (x_client->isOk()) | |||
| return true; | |||
| else | |||
| set_last_error("Failed to register plugin client"); | |||
| setLastError("Failed to register plugin client"); | |||
| } | |||
| else | |||
| set_last_error("Failed to find any instruments"); | |||
| setLastError("Failed to find any instruments"); | |||
| } | |||
| 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; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| static short newLinuxSampler(const initializer& init, bool isGIG); | |||
| static CarlaPlugin* newLinuxSampler(const initializer& init, bool isGIG); | |||
| private: | |||
| LinuxSampler::Sampler* sampler; | |||
| @@ -676,50 +566,54 @@ private: | |||
| const char* m_label; | |||
| 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)); | |||
| #ifdef WANT_LINUXSAMPLER | |||
| short id = init.engine->getNewPluginIndex(); | |||
| 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)) | |||
| { | |||
| delete plugin; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| 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); | |||
| #ifdef WANT_LINUXSAMPLER | |||
| 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); | |||
| #ifdef WANT_LINUXSAMPLER | |||
| return LinuxSamplerPlugin::newLinuxSampler(init, false); | |||
| #else | |||
| setLastError("linuxsampler support not available"); | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| /**@}*/ | |||
| @@ -17,7 +17,7 @@ | |||
| #include "carla_plugin.h" | |||
| #include "lv2_rdf.h" | |||
| #include "carla_lv2_includes.h" | |||
| #include "sratom/sratom.h" | |||
| extern "C" { | |||
| @@ -142,6 +142,7 @@ const uint32_t CARLA_URI_MAP_ID_COUNT = 12; | |||
| /**@}*/ | |||
| enum Lv2ParameterDataType { | |||
| LV2_PARAMETER_TYPE_NULL, | |||
| LV2_PARAMETER_TYPE_CONTROL | |||
| }; | |||
| @@ -153,6 +154,10 @@ struct EventData { | |||
| LV2_Event_Buffer* event; | |||
| LV2_MIDI* midi; | |||
| }; | |||
| EventData() | |||
| : type(0), | |||
| port(nullptr) {} | |||
| }; | |||
| struct Lv2ParameterData { | |||
| @@ -160,26 +165,35 @@ struct Lv2ParameterData { | |||
| union { | |||
| float control; | |||
| }; | |||
| Lv2ParameterData() | |||
| : type(LV2_PARAMETER_TYPE_NULL) {} | |||
| }; | |||
| struct PluginEventData { | |||
| uint32_t count; | |||
| EventData* data; | |||
| PluginEventData() | |||
| : count(0), | |||
| data(nullptr) {} | |||
| }; | |||
| const char* lv2bridge2str(LV2_Property type) | |||
| const char* lv2bridge2str(const LV2_Property type) | |||
| { | |||
| switch (type) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| case LV2_UI_GTK2: | |||
| return carla_options.bridge_lv2gtk2; | |||
| return carlaOptions.bridge_lv2gtk2; | |||
| 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: | |||
| return carla_options.bridge_lv2x11; | |||
| return carlaOptions.bridge_lv2x11; | |||
| #endif | |||
| default: | |||
| return nullptr; | |||
| @@ -195,7 +209,7 @@ public: | |||
| m_type = PLUGIN_LV2; | |||
| handle = nullptr; | |||
| handle = h2 = nullptr; | |||
| descriptor = nullptr; | |||
| rdf_descriptor = nullptr; | |||
| @@ -267,8 +281,8 @@ public: | |||
| case GUI_EXTERNAL_OSC: | |||
| 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) | |||
| @@ -289,7 +303,7 @@ public: | |||
| delete osc.thread; | |||
| } | |||
| //osc_clear_data(&osc.data); | |||
| osc_clear_data(&osc.data); | |||
| break; | |||
| #endif | |||
| @@ -330,11 +344,24 @@ public: | |||
| 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) | |||
| lv2_rdf_free(rdf_descriptor); | |||
| @@ -416,7 +443,7 @@ public: | |||
| if (LV2_IS_UTILITY(Category)) | |||
| return PLUGIN_CATEGORY_UTILITY; | |||
| return get_category_from_name(m_name); | |||
| return getPluginCategoryFromName(m_name); | |||
| } | |||
| long uniqueId() | |||
| @@ -683,7 +710,7 @@ public: | |||
| if (ext.state) | |||
| { | |||
| const char* const stype = customdatatype2str(type); | |||
| const char* const stype = getCustomDataTypeString(type); | |||
| LV2_State_Status status; | |||
| if (x_engine->isOffline()) | |||
| @@ -747,8 +774,8 @@ public: | |||
| // osc_send_midi_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program, false); | |||
| //else | |||
| #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)) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":"); | |||
| @@ -1379,7 +1406,7 @@ public: | |||
| if (needsCin) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-in"); | |||
| @@ -1394,7 +1421,7 @@ public: | |||
| if (needsCout) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-out"); | |||
| @@ -1822,7 +1849,7 @@ public: | |||
| for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | |||
| { | |||
| if (! extMidiNotes[i].valid) | |||
| if (extMidiNotes[i].channel < 0) | |||
| break; | |||
| uint8_t midiEvent[4] = { 0 }; | |||
| @@ -1855,7 +1882,7 @@ public: | |||
| } | |||
| } | |||
| extMidiNotes[i].valid = false; | |||
| extMidiNotes[i].channel = -1; | |||
| midiEventCount += 1; | |||
| } | |||
| @@ -2467,7 +2494,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -2561,7 +2588,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -3089,7 +3116,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -3098,7 +3125,7 @@ public: | |||
| if (! libOpen(rdf_descriptor->Binary)) | |||
| { | |||
| set_last_error(libError(rdf_descriptor->Binary)); | |||
| setLastError(libError(rdf_descriptor->Binary)); | |||
| return false; | |||
| } | |||
| @@ -3109,7 +3136,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -3125,7 +3152,7 @@ public: | |||
| 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; | |||
| } | |||
| @@ -3143,7 +3170,7 @@ public: | |||
| qCritical("Got unsupported port -> %i", PortType); | |||
| 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; | |||
| 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) | |||
| { | |||
| 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; | |||
| break; | |||
| } | |||
| @@ -3279,7 +3306,7 @@ public: | |||
| if (! handle) | |||
| { | |||
| set_last_error("Plugin failed to initialize"); | |||
| setLastError("Plugin failed to initialize"); | |||
| return false; | |||
| } | |||
| @@ -3300,7 +3327,7 @@ public: | |||
| if (! x_client->isOk()) | |||
| { | |||
| set_last_error("Failed to register plugin client"); | |||
| setLastError("Failed to register plugin client"); | |||
| return false; | |||
| } | |||
| @@ -3323,15 +3350,15 @@ public: | |||
| { | |||
| case LV2_UI_QT4: | |||
| #ifndef BUILD_BRIDGE | |||
| if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||
| if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||
| eQt4 = i; | |||
| #endif | |||
| iQt4 = i; | |||
| break; | |||
| case LV2_UI_HWND: | |||
| case LV2_UI_WINDOWS: | |||
| #ifndef BUILD_BRIDGE | |||
| if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||
| if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||
| eHWND = i; | |||
| #endif | |||
| iHWND = i; | |||
| @@ -3339,7 +3366,7 @@ public: | |||
| case LV2_UI_X11: | |||
| #ifndef BUILD_BRIDGE | |||
| if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||
| if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||
| eX11 = i; | |||
| #endif | |||
| iX11 = i; | |||
| @@ -3350,7 +3377,7 @@ public: | |||
| if (false) | |||
| #else | |||
| # ifdef HAVE_SUIL | |||
| if (isUiBridgeable(i) && carla_options.prefer_ui_bridges) | |||
| if (isUiBridgeable(i) && carlaOptions.prefer_ui_bridges) | |||
| # else | |||
| if (isUiBridgeable(i)) | |||
| # endif | |||
| @@ -3569,8 +3596,14 @@ public: | |||
| updateUi(); | |||
| 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.resizable = isUiResizable(); | |||
| break; | |||
| @@ -3629,7 +3662,7 @@ public: | |||
| } | |||
| private: | |||
| LV2_Handle handle; | |||
| LV2_Handle handle, h2; | |||
| const LV2_Descriptor* descriptor; | |||
| const LV2_RDF_Descriptor* rdf_descriptor; | |||
| LV2_Feature* features[lv2_feature_count+1]; | |||
| @@ -3671,45 +3704,46 @@ private: | |||
| 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); | |||
| short id = init.engine->getNewPluginIndex(); | |||
| short id = init.engine->getNewPluginId(); | |||
| 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)) | |||
| { | |||
| delete plugin; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| #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; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| } | |||
| #endif | |||
| 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(); | |||
| 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* key = (const char*)&argv[1]->s; | |||
| const char* value = (const char*)&argv[2]->s; | |||
| @@ -15,16 +15,16 @@ SOURCES = \ | |||
| ../carla_engine.cpp \ | |||
| ../carla_engine_jack.cpp \ | |||
| ../carla_engine_rtaudio.cpp \ | |||
| # ../carla_bridge.cpp \ | |||
| ../carla_bridge.cpp \ | |||
| ../carla_osc.cpp \ | |||
| ../carla_shared.cpp \ | |||
| ../carla_threads.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 | |||
| HEADERS = \ | |||
| @@ -41,6 +41,7 @@ HEADERS = \ | |||
| ../../carla-includes/carla_ladspa_includes.h \ | |||
| ../../carla-includes/carla_lv2_includes.h \ | |||
| ../../carla-includes/carla_vst_includes.h \ | |||
| ../../carla-includes/carla_linuxsampler_includes.h \ | |||
| ../../carla-includes/carla_midi.h \ | |||
| ../../carla-includes/ladspa_rdf.h \ | |||
| ../../carla-includes/lv2_rdf.h | |||
| @@ -49,7 +50,9 @@ INCLUDEPATH = .. \ | |||
| ../../carla-includes \ | |||
| ../../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_RTAUDIO | |||
| DEFINES += QTCREATOR_TEST | |||
| @@ -114,7 +114,7 @@ public: | |||
| if (effect->flags & effFlagsIsSynth) | |||
| return PLUGIN_CATEGORY_SYNTH; | |||
| return get_category_from_name(m_name); | |||
| return getPluginCategoryFromName(m_name); | |||
| } | |||
| long uniqueId() | |||
| @@ -364,7 +364,7 @@ public: | |||
| for (j=0; j<ains; j++) | |||
| { | |||
| #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); | |||
| else | |||
| #endif | |||
| @@ -377,7 +377,7 @@ public: | |||
| for (j=0; j<aouts; j++) | |||
| { | |||
| #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); | |||
| else | |||
| #endif | |||
| @@ -492,7 +492,7 @@ public: | |||
| if (needsCin) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":control-in"); | |||
| @@ -507,7 +507,7 @@ public: | |||
| if (mins == 1) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":midi-in"); | |||
| @@ -522,7 +522,7 @@ public: | |||
| if (mouts == 1) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| if (carlaOptions.process_mode != PROCESS_MODE_MULTIPLE_CLIENTS) | |||
| { | |||
| strcpy(portName, m_name); | |||
| strcat(portName, ":midi-out"); | |||
| @@ -874,7 +874,7 @@ public: | |||
| for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++) | |||
| { | |||
| if (! extMidiNotes[i].valid) | |||
| if (extMidiNotes[i].channel < 0) | |||
| break; | |||
| VstMidiEvent* const midiEvent = &midiEvents[midiEventCount]; | |||
| @@ -887,7 +887,7 @@ public: | |||
| midiEvent->midiData[1] = extMidiNotes[i].note; | |||
| midiEvent->midiData[2] = extMidiNotes[i].velo; | |||
| extMidiNotes[i].valid = false; | |||
| extMidiNotes[i].channel = -1; | |||
| midiEventCount += 1; | |||
| } | |||
| @@ -1206,7 +1206,7 @@ public: | |||
| #else | |||
| if (effect && effect->resvd1) | |||
| { | |||
| self = (VstPlugin*)get_pointer(effect->resvd1); | |||
| self = (VstPlugin*)getPointer(effect->resvd1); | |||
| #endif | |||
| if (self->unique1 != self->unique2) | |||
| self = nullptr; | |||
| @@ -1342,7 +1342,7 @@ public: | |||
| #ifdef BUILD_BRIDGE | |||
| return MAX_PARAMETERS; | |||
| #else | |||
| return carla_options.max_parameters; | |||
| return carlaOptions.max_parameters; | |||
| #endif | |||
| case audioMasterGetParameterQuantization: | |||
| @@ -1610,7 +1610,7 @@ public: | |||
| if (! libOpen(filename)) | |||
| { | |||
| set_last_error(libError(filename)); | |||
| setLastError(libError(filename)); | |||
| return false; | |||
| } | |||
| @@ -1625,7 +1625,7 @@ public: | |||
| 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; | |||
| } | |||
| } | |||
| @@ -1637,7 +1637,7 @@ public: | |||
| if (! effect || effect->magic != kEffectMagic) | |||
| { | |||
| set_last_error("Plugin failed to initialize"); | |||
| setLastError("Plugin failed to initialize"); | |||
| return false; | |||
| } | |||
| @@ -1693,7 +1693,7 @@ public: | |||
| if (! x_client->isOk()) | |||
| { | |||
| set_last_error("Failed to register plugin client"); | |||
| setLastError("Failed to register plugin client"); | |||
| return false; | |||
| } | |||
| @@ -1730,45 +1730,44 @@ private: | |||
| 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); | |||
| short id = init.engine->getNewPluginIndex(); | |||
| short id = init.engine->getNewPluginId(); | |||
| 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)) | |||
| { | |||
| delete plugin; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| #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))) | |||
| { | |||
| 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; | |||
| return -1; | |||
| return nullptr; | |||
| } | |||
| } | |||
| #endif | |||
| 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 | |||
| 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(bank >= 0); | |||
| @@ -106,7 +106,7 @@ void osc_send_program(const CarlaOscData* const oscData, const int program, cons | |||
| char targetPath[strlen(oscData->path)+9]; | |||
| strcpy(targetPath, oscData->path); | |||
| 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_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 | |||
| x_save_state_parameter = deepcopy(save_state_parameter) | |||