| @@ -457,37 +457,47 @@ typedef enum { | |||
| */ | |||
| PLUGIN_VST = 5, | |||
| /*! | |||
| * VST3 plugin. | |||
| */ | |||
| PLUGIN_VST3 = 6, | |||
| /*! | |||
| * AU plugin. | |||
| * @note MacOS only | |||
| */ | |||
| PLUGIN_AU = 6, | |||
| PLUGIN_AU = 7, | |||
| /*! | |||
| * JACK plugin. | |||
| */ | |||
| PLUGIN_JACK = 8, | |||
| /*! | |||
| * ReWire plugin. | |||
| * @note Windows and MacOS only | |||
| */ | |||
| PLUGIN_REWIRE = 7, | |||
| PLUGIN_REWIRE = 9, | |||
| /*! | |||
| * Single CSD file (Csound). | |||
| */ | |||
| PLUGIN_FILE_CSD = 8, | |||
| PLUGIN_FILE_CSD = 10, | |||
| /*! | |||
| * Single GIG file. | |||
| */ | |||
| PLUGIN_FILE_GIG = 9, | |||
| PLUGIN_FILE_GIG = 11, | |||
| /*! | |||
| * Single SF2 file (SoundFont). | |||
| */ | |||
| PLUGIN_FILE_SF2 = 10, | |||
| PLUGIN_FILE_SF2 = 12, | |||
| /*! | |||
| * Single SFZ file. | |||
| */ | |||
| PLUGIN_FILE_SFZ = 11 | |||
| PLUGIN_FILE_SFZ = 13 | |||
| } PluginType; | |||
| @@ -839,7 +839,9 @@ public: | |||
| static CarlaPlugin* newDSSI(const Initializer& init); | |||
| static CarlaPlugin* newLV2(const Initializer& init); | |||
| static CarlaPlugin* newVST(const Initializer& init); | |||
| static CarlaPlugin* newVST3(const Initializer& init); | |||
| static CarlaPlugin* newAU(const Initializer& init); | |||
| static CarlaPlugin* newJACK(const Initializer& init); | |||
| static CarlaPlugin* newReWire(const Initializer& init); | |||
| static CarlaPlugin* newCsound(const Initializer& init); | |||
| @@ -795,7 +795,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||
| bridgeBinary.clear(); | |||
| } | |||
| if (btype != BINARY_NATIVE || (pData->options.preferPluginBridges && bridgeBinary.isNotEmpty())) | |||
| if (ptype != PLUGIN_INTERNAL && ptype != PLUGIN_JACK && (btype != BINARY_NATIVE || (pData->options.preferPluginBridges && bridgeBinary.isNotEmpty()))) | |||
| { | |||
| if (bridgeBinary.isNotEmpty()) | |||
| { | |||
| @@ -891,10 +891,20 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||
| plugin = CarlaPlugin::newVST(initializer); | |||
| break; | |||
| case PLUGIN_VST3: | |||
| plugin = CarlaPlugin::newVST3(initializer); | |||
| break; | |||
| case PLUGIN_AU: | |||
| plugin = CarlaPlugin::newAU(initializer); | |||
| break; | |||
| case PLUGIN_JACK: | |||
| #ifndef BUILD_BRIDGE | |||
| plugin = CarlaPlugin::newJACK(initializer); | |||
| #endif | |||
| break; | |||
| case PLUGIN_REWIRE: | |||
| plugin = CarlaPlugin::newReWire(initializer); | |||
| break; | |||
| @@ -1661,7 +1661,9 @@ public: | |||
| pData->name = pData->engine->getUniquePluginName(name); | |||
| pData->filename = carla_strdup(filename); | |||
| fBridgeBinary = bridgeBinary; | |||
| if (bridgeBinary != nullptr) | |||
| fBridgeBinary = bridgeBinary; | |||
| // --------------------------------------------------------------- | |||
| // SHM Audio Pool | |||
| @@ -1917,6 +1919,35 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P | |||
| #endif | |||
| } | |||
| CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||
| { | |||
| carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label); | |||
| #ifndef BUILD_BRIDGE | |||
| BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, BINARY_NATIVE, PLUGIN_JACK)); | |||
| if (! plugin->init(init.filename, init.name, init.label, nullptr)) | |||
| { | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) | |||
| { | |||
| init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!"); | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| return plugin; | |||
| #else | |||
| init.engine->setLastError("JACK app bridge support not available"); | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // Bridge Helper | |||
| @@ -126,6 +126,35 @@ void CarlaPluginThread::run() | |||
| name = "(none)"; | |||
| QStringList arguments; | |||
| QProcessEnvironment env(QProcessEnvironment::systemEnvironment()); | |||
| const EngineOptions& options(fEngine->getOptions()); | |||
| char strBuf[STR_MAX+1]; | |||
| env.insert("ENGINE_OPTION_UIS_ALWAYS_ON_TOP", options.uisAlwaysOnTop ? "true" : "false"); | |||
| if (options.maxParameters != 0) | |||
| { | |||
| std::sprintf(strBuf, "%u", options.maxParameters); | |||
| env.insert("ENGINE_OPTION_MAX_PARAMETERS", strBuf); | |||
| } | |||
| if (options.uiBridgesTimeout != 0) | |||
| { | |||
| std::sprintf(strBuf, "%u", options.uiBridgesTimeout); | |||
| env.insert("ENGINE_OPTION_UI_BRIDGES_TIMEOUT", strBuf); | |||
| } | |||
| if (options.frontendWinId != 0) | |||
| { | |||
| std::sprintf(strBuf, P_INTPTR, options.frontendWinId); | |||
| env.insert("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf); | |||
| } | |||
| if (options.binaryDir != nullptr) | |||
| env.insert("ENGINE_OPTION_PATH_BINARIES", options.binaryDir); | |||
| if (options.resourceDir != nullptr) | |||
| env.insert("ENGINE_OPTION_PATH_RESOURCES", options.resourceDir); | |||
| switch (fMode) | |||
| { | |||
| @@ -153,15 +182,25 @@ void CarlaPluginThread::run() | |||
| break; | |||
| case PLUGIN_THREAD_BRIDGE: | |||
| /* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathUDP()).arg(fPlugin->getId()); | |||
| /* stype */ arguments << (const char*)fExtra1; | |||
| /* filename */ arguments << fPlugin->getFilename(); | |||
| /* name */ arguments << name; | |||
| /* label */ arguments << (const char*)fLabel; | |||
| /* SHM ids */ arguments << (const char*)fExtra2; | |||
| env.insert("ENGINE_BRIDGE_SHM_IDS", fExtra2.getBuffer()); | |||
| if (fPlugin->getType() != PLUGIN_JACK) | |||
| { | |||
| /* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathUDP()).arg(fPlugin->getId()); | |||
| /* stype */ arguments << (const char*)fExtra1; | |||
| /* filename */ arguments << fPlugin->getFilename(); | |||
| /* name */ arguments << name; | |||
| /* label */ arguments << (const char*)fLabel; | |||
| } | |||
| else | |||
| { | |||
| /* filename */ arguments << fPlugin->getFilename(); | |||
| } | |||
| break; | |||
| } | |||
| fProcess->setProcessEnvironment(env); | |||
| fProcess->start((const char*)fBinary, arguments); | |||
| fProcess->waitForStarted(); | |||
| @@ -26,6 +26,7 @@ OBJS = \ | |||
| DssiPlugin.cpp.o \ | |||
| Lv2Plugin.cpp.o \ | |||
| VstPlugin.cpp.o \ | |||
| Vst3Plugin.cpp.o \ | |||
| AuPlugin.cpp.o \ | |||
| ReWirePlugin.cpp.o \ | |||
| CsoundPlugin.cpp.o \ | |||
| @@ -85,6 +86,9 @@ Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) | |||
| VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) | |||
| $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | |||
| Vst3Plugin.cpp.o: Vst3Plugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) | |||
| $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| AuPlugin.cpp.o: AuPlugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) | |||
| $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| @@ -583,7 +583,9 @@ int main(int argc, char* argv[]) | |||
| // --------------------------------------------------------------------- | |||
| // Setup args | |||
| const bool useBridge = (argc == 7); | |||
| const char* const shmIds(std::getenv("ENGINE_BRIDGE_SHM_IDS")); | |||
| const bool useBridge = (shmIds != nullptr); | |||
| const bool useOsc = (std::strcmp(oscUrl, "null") != 0 && std::strcmp(oscUrl, "(null)") != 0 && std::strcmp(oscUrl, "NULL") != 0); | |||
| if (std::strcmp(name, "(none)") == 0) | |||
| @@ -597,9 +599,9 @@ int main(int argc, char* argv[]) | |||
| if (useBridge) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(std::strlen(argv[6]) == 6*2, 1); | |||
| std::strncpy(bridgeBaseAudioName, argv[6], 6); | |||
| std::strncpy(bridgeBaseControlName, argv[6]+6, 6); | |||
| CARLA_SAFE_ASSERT_RETURN(std::strlen(shmIds) == 6*2, 1); | |||
| std::strncpy(bridgeBaseAudioName, shmIds, 6); | |||
| std::strncpy(bridgeBaseControlName, shmIds+6, 6); | |||
| bridgeBaseAudioName[6] = '\0'; | |||
| bridgeBaseControlName[6] = '\0'; | |||
| } | |||
| @@ -416,6 +416,7 @@ OBJS_PLUGIN = \ | |||
| ../backend/plugin/DssiPlugin__native.o \ | |||
| ../backend/plugin/Lv2Plugin__native.o \ | |||
| ../backend/plugin/VstPlugin__native.o \ | |||
| ../backend/plugin/Vst3Plugin__native.o \ | |||
| ../backend/plugin/AuPlugin__native.o \ | |||
| ../backend/plugin/ReWirePlugin__native.o \ | |||
| ../backend/plugin/CsoundPlugin__native.o \ | |||
| @@ -479,6 +480,7 @@ OBJS_NATIVE += \ | |||
| ../backend/plugin/DssiPlugin__native.o \ | |||
| ../backend/plugin/Lv2Plugin__native.o \ | |||
| ../backend/plugin/VstPlugin__native.o \ | |||
| ../backend/plugin/Vst3Plugin__native.o \ | |||
| ../backend/plugin/AuPlugin__native.o \ | |||
| ../backend/plugin/ReWirePlugin__native.o \ | |||
| ../backend/plugin/CsoundPlugin__native.o \ | |||
| @@ -347,25 +347,31 @@ PLUGIN_LV2 = 4 | |||
| # VST plugin. | |||
| PLUGIN_VST = 5 | |||
| # VST3 plugin. | |||
| PLUGIN_VST3 = 6 | |||
| # AU plugin. | |||
| # @note MacOS only | |||
| PLUGIN_AU = 6 | |||
| PLUGIN_AU = 7 | |||
| # JACK plugin. | |||
| PLUGIN_JACK = 8 | |||
| # ReWire plugin. | |||
| # @note Windows and MacOS only | |||
| PLUGIN_REWIRE = 7 | |||
| PLUGIN_REWIRE = 9 | |||
| # Single CSD file (Csound). | |||
| PLUGIN_FILE_CSD = 8 | |||
| PLUGIN_FILE_CSD = 10 | |||
| # Single GIG file. | |||
| PLUGIN_FILE_GIG = 9 | |||
| PLUGIN_FILE_GIG = 11 | |||
| # Single SF2 file (SoundFont). | |||
| PLUGIN_FILE_SF2 = 10 | |||
| PLUGIN_FILE_SF2 = 12 | |||
| # Single SFZ file. | |||
| PLUGIN_FILE_SFZ = 11 | |||
| PLUGIN_FILE_SFZ = 13 | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Plugin Category | |||
| @@ -97,8 +97,12 @@ const char* PluginType2Str(const PluginType type) noexcept | |||
| return "PLUGIN_LV2"; | |||
| case PLUGIN_VST: | |||
| return "PLUGIN_VST"; | |||
| case PLUGIN_VST3: | |||
| return "PLUGIN_VST3"; | |||
| case PLUGIN_AU: | |||
| return "PLUGIN_AU"; | |||
| case PLUGIN_JACK: | |||
| return "PLUGIN_JACK"; | |||
| case PLUGIN_REWIRE: | |||
| return "PLUGIN_REWIRE"; | |||
| case PLUGIN_FILE_CSD: | |||
| @@ -402,8 +406,12 @@ const char* getPluginTypeAsString(const PluginType type) noexcept | |||
| return "LV2"; | |||
| case PLUGIN_VST: | |||
| return "VST"; | |||
| case PLUGIN_VST3: | |||
| return "VST3"; | |||
| case PLUGIN_AU: | |||
| return "AU"; | |||
| case PLUGIN_JACK: | |||
| return "JACK"; | |||
| case PLUGIN_REWIRE: | |||
| return "ReWire"; | |||
| case PLUGIN_FILE_CSD: | |||
| @@ -441,8 +449,12 @@ PluginType getPluginTypeFromString(const char* const ctype) | |||
| return PLUGIN_LV2; | |||
| if (stype == "vst") | |||
| return PLUGIN_VST; | |||
| if (stype == "vst3") | |||
| return PLUGIN_VST3; | |||
| if (stype == "au") | |||
| return PLUGIN_AU; | |||
| if (stype == "jack") | |||
| return PLUGIN_JACK; | |||
| if (stype == "rewire") | |||
| return PLUGIN_REWIRE; | |||
| if (stype == "csd") | |||
| @@ -440,11 +440,19 @@ void fillXmlStringFromSaveState(QString& content, const SaveState& saveState) | |||
| info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||
| info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | |||
| break; | |||
| case PLUGIN_VST3: | |||
| // TODO? | |||
| info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||
| info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | |||
| break; | |||
| case PLUGIN_AU: | |||
| // TODO? | |||
| info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||
| info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | |||
| break; | |||
| case PLUGIN_JACK: | |||
| info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||
| break; | |||
| case PLUGIN_REWIRE: | |||
| info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true)); | |||
| break; | |||