From 2c0ef94bbca182337f3ad738d30444ee2d668d6d Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 12 Jul 2012 20:21:43 +0100 Subject: [PATCH] CarlaBackend compiles again, but still needs work --- src/carla-backend/Makefile | 45 ++--- .../carla_backend_standalone.cpp | 12 +- src/carla-backend/carla_bridge.cpp | 71 ++++--- src/carla-backend/carla_engine.cpp | 44 +++-- src/carla-backend/carla_engine.h | 38 ++-- src/carla-backend/carla_engine_jack.cpp | 5 +- src/carla-backend/carla_osc.cpp | 8 +- src/carla-backend/carla_plugin.h | 16 +- src/carla-backend/dssi.cpp | 157 ++++++++++------ src/carla-backend/fluidsynth.cpp | 51 +++-- src/carla-backend/ladspa.cpp | 4 +- src/carla-backend/linuxsampler.cpp | 176 ++++-------------- src/carla-backend/lv2.cpp | 156 ++++++++++------ src/carla-backend/qtcreator/carla-backend.pro | 17 +- src/carla-backend/vst.cpp | 49 +++-- src/carla-includes/carla_osc_includes.h | 6 +- .../linuxsampler/EngineFactory.h | 47 ----- src/carla.py | 2 +- 18 files changed, 443 insertions(+), 461 deletions(-) delete mode 100644 src/carla-includes/linuxsampler/EngineFactory.h diff --git a/src/carla-backend/Makefile b/src/carla-backend/Makefile index d4fc33b..84cefbf 100644 --- a/src/carla-backend/Makefile +++ b/src/carla-backend/Makefile @@ -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 # -------------------------------------------------------------- diff --git a/src/carla-backend/carla_backend_standalone.cpp b/src/carla-backend/carla_backend_standalone.cpp index d6bf4a8..a4bd737 100644 --- a/src/carla-backend/carla_backend_standalone.cpp +++ b/src/carla-backend/carla_backend_standalone.cpp @@ -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) { diff --git a/src/carla-backend/carla_bridge.cpp b/src/carla-backend/carla_bridge.cpp index 9d2d8b7..a4c7a77 100644 --- a/src/carla-backend/carla_bridge.cpp +++ b/src/carla-backend/carla_bridge.cpp @@ -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 diff --git a/src/carla-backend/carla_engine.cpp b/src/carla-backend/carla_engine.cpp index 4cf8bea..b0be734 100644 --- a/src/carla-backend/carla_engine.cpp +++ b/src/carla-backend/carla_engine.cpp @@ -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() diff --git a/src/carla-backend/carla_engine.h b/src/carla-backend/carla_engine.h index d96d92e..75cc070 100644 --- a/src/carla-backend/carla_engine.h +++ b/src/carla-backend/carla_engine.h @@ -19,6 +19,7 @@ #define CARLA_ENGINE_H #include "carla_osc.h" +#include "carla_shared.h" #include "carla_threads.h" #include @@ -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: diff --git a/src/carla-backend/carla_engine_jack.cpp b/src/carla-backend/carla_engine_jack.cpp index 37a6edb..1a5e3c6 100644 --- a/src/carla-backend/carla_engine_jack.cpp +++ b/src/carla-backend/carla_engine_jack.cpp @@ -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 diff --git a/src/carla-backend/carla_osc.cpp b/src/carla-backend/carla_osc.cpp index 4c0b34f..1eea21d 100644 --- a/src/carla-backend/carla_osc.cpp +++ b/src/carla-backend/carla_osc.cpp @@ -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) diff --git a/src/carla-backend/carla_plugin.h b/src/carla-backend/carla_plugin.h index 111aa75..781b7e8 100644 --- a/src/carla-backend/carla_plugin.h +++ b/src/carla-backend/carla_plugin.h @@ -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 // ------------------------------------------------------------------- diff --git a/src/carla-backend/dssi.cpp b/src/carla-backend/dssi.cpp index 5203434..3c74330 100644 --- a/src/carla-backend/dssi.cpp +++ b/src/carla-backend/dssi.cpp @@ -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; } /**@}*/ diff --git a/src/carla-backend/fluidsynth.cpp b/src/carla-backend/fluidsynth.cpp index 9435030..533ab57 100644 --- a/src/carla-backend/fluidsynth.cpp +++ b/src/carla-backend/fluidsynth.cpp @@ -21,6 +21,12 @@ #include "carla_plugin.h" +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} /* adjust editor indent */ +#endif + #ifdef WANT_FLUIDSYNTH #include @@ -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 } diff --git a/src/carla-backend/ladspa.cpp b/src/carla-backend/ladspa.cpp index c03b74e..9db0085 100644 --- a/src/carla-backend/ladspa.cpp +++ b/src/carla-backend/ladspa.cpp @@ -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; } diff --git a/src/carla-backend/linuxsampler.cpp b/src/carla-backend/linuxsampler.cpp index 0ba0611..dc028bb 100644 --- a/src/carla-backend/linuxsampler.cpp +++ b/src/carla-backend/linuxsampler.cpp @@ -19,11 +19,10 @@ #error Should not use linuxsampler for bridges! #endif -#include "carla_plugin.h" +// TODO - setMidiProgram() -#ifdef WANT_LINUXSAMPLER -#include -#include "linuxsampler/EngineFactory.h" +#include "carla_plugin.h" +#include "carla_linuxsampler_includes.h" #include @@ -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()), - 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(), 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 } /**@}*/ diff --git a/src/carla-backend/lv2.cpp b/src/carla-backend/lv2.cpp index 150d958..5e7c8a7 100644 --- a/src/carla-backend/lv2.cpp +++ b/src/carla-backend/lv2.cpp @@ -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 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; diff --git a/src/carla-backend/qtcreator/carla-backend.pro b/src/carla-backend/qtcreator/carla-backend.pro index d79d34e..75e313a 100644 --- a/src/carla-backend/qtcreator/carla-backend.pro +++ b/src/carla-backend/qtcreator/carla-backend.pro @@ -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 diff --git a/src/carla-backend/vst.cpp b/src/carla-backend/vst.cpp index 215cc36..475faa8 100644 --- a/src/carla-backend/vst.cpp +++ b/src/carla-backend/vst.cpp @@ -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; jmidiData[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; } /**@}*/ diff --git a/src/carla-includes/carla_osc_includes.h b/src/carla-includes/carla_osc_includes.h index e4ffda3..cbe9400 100644 --- a/src/carla-includes/carla_osc_includes.h +++ b/src/carla-includes/carla_osc_includes.h @@ -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); } } diff --git a/src/carla-includes/linuxsampler/EngineFactory.h b/src/carla-includes/linuxsampler/EngineFactory.h deleted file mode 100644 index 913d763..0000000 --- a/src/carla-includes/linuxsampler/EngineFactory.h +++ /dev/null @@ -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 -#include -#include - -#include -#include - -namespace LinuxSampler { - - class EngineFactory { - public: - static std::vector AvailableEngineTypes(); - static String AvailableEngineTypesAsString(); - static Engine* Create(String EngineType) throw (Exception); - static void Destroy(Engine* pEngine); - static const std::set& EngineInstances(); - protected: - static void Erase(Engine* pEngine); - friend class Engine; - }; - -} // namespace LinuxSampler - -#endif // __LS_ENGINEFACTORY_H__ diff --git a/src/carla.py b/src/carla.py index 89ae7bb..a70c40b 100755 --- a/src/carla.py +++ b/src/carla.py @@ -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)