Cleanup
[carla.git] / source / backend / engine / CarlaEngineNative.cpp
blob0a83aaaaafc01b63f58a35df1d842f245fafeddc
1 // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
2 // SPDX-License-Identifier: GPL-2.0-or-later
4 #include "CarlaDefines.h"
6 #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
7 # error This file should not be compiled if building alternative-arch bridges
8 #endif
10 #ifdef CARLA_OS_WASM
11 # define CARLA_ENGINE_WITHOUT_UI
12 #endif
14 #include "CarlaEngineInit.hpp"
15 #include "CarlaEngineInternal.hpp"
16 #include "CarlaPlugin.hpp"
18 #include "CarlaBackendUtils.hpp"
19 #include "CarlaBase64Utils.hpp"
20 #include "CarlaBinaryUtils.hpp"
21 #include "CarlaMathUtils.hpp"
22 #include "CarlaStateUtils.hpp"
24 #include "CarlaExternalUI.hpp"
25 #include "CarlaHost.h"
26 #include "CarlaNative.hpp"
27 #include "CarlaNativePlugin.h"
29 #include "water/files/File.h"
30 #include "water/streams/MemoryOutputStream.h"
31 #include "water/xml/XmlDocument.h"
32 #include "water/xml/XmlElement.h"
34 #ifdef CARLA_OS_WIN
35 # include <direct.h>
36 #endif
38 using water::File;
39 using water::MemoryOutputStream;
40 using water::String;
41 using water::XmlDocument;
42 using water::XmlElement;
44 CARLA_BACKEND_START_NAMESPACE
46 static const uint32_t kNumInParams = 100;
47 static const uint32_t kNumOutParams = 10;
49 static const uint16_t kUiWidth = 1024;
50 static const uint16_t kUiHeight = 712;
52 // -----------------------------------------------------------------------
54 #ifndef CARLA_ENGINE_WITHOUT_UI
55 class CarlaEngineNative;
57 class CarlaEngineNativeUI : public CarlaExternalUI
59 public:
60 CarlaEngineNativeUI(CarlaEngineNative* const engine)
61 : fEngine(engine)
63 carla_debug("CarlaEngineNativeUI::CarlaEngineNativeUI(%p)", engine);
66 ~CarlaEngineNativeUI() noexcept override
68 carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()");
71 protected:
72 bool msgReceived(const char* const msg) noexcept override;
74 private:
75 CarlaEngineNative* const fEngine;
77 void _updateParamValues(const CarlaPluginPtr& plugin,
78 uint32_t pluginId,
79 bool sendCallback, bool sendPluginHost) const noexcept;
81 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeUI)
83 #endif
85 // -----------------------------------------------------------------------
87 class CarlaEngineNative : public CarlaEngine
89 public:
90 CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay,
91 const bool withMidiIn, const bool withMidiOut,
92 const uint32_t inChan = 2, uint32_t outChan = 2,
93 const uint32_t cvIns = 0, const uint32_t cvOuts = 0)
94 : CarlaEngine(),
95 pHost(host),
96 kIsPatchbay(isPatchbay),
97 kHasMidiIn(withMidiIn),
98 kHasMidiOut(withMidiOut),
99 fIsActive(false),
100 fIsRunning(false),
101 fUsesEmbed(false),
102 #ifndef CARLA_ENGINE_WITHOUT_UI
103 fUiServer(this),
104 #endif
105 fLastScaleFactor(1.0f),
106 fLastProjectFolder(),
107 fPluginDeleterMutex(),
108 fOptionsForced(false)
110 carla_debug("CarlaEngineNative::CarlaEngineNative()");
112 carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
114 pData->bufferSize = pHost->get_buffer_size(pHost->handle);
115 pData->sampleRate = pHost->get_sample_rate(pHost->handle);
116 pData->initTime(nullptr);
118 #ifndef BUILD_BRIDGE
119 // Forced OSC setup when running as plugin
120 pData->options.oscEnabled = true;
121 pData->options.oscPortTCP = -1;
122 pData->options.oscPortUDP = 0;
123 #endif
125 if (outChan == 0)
126 outChan = inChan;
128 // set-up engine
129 if (kIsPatchbay)
131 pData->options.processMode = ENGINE_PROCESS_MODE_PATCHBAY;
132 pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
133 pData->options.forceStereo = false;
134 pData->options.preferPluginBridges = false;
135 pData->options.preferUiBridges = false;
136 init("Carla-Patchbay");
137 pData->graph.create(inChan, outChan, cvIns, cvOuts, withMidiIn, withMidiOut);
139 else
141 CARLA_SAFE_ASSERT(inChan == 2);
142 CARLA_SAFE_ASSERT(outChan == 2);
143 pData->options.processMode = ENGINE_PROCESS_MODE_CONTINUOUS_RACK;
144 pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
145 pData->options.forceStereo = true;
146 pData->options.preferPluginBridges = false;
147 pData->options.preferUiBridges = false;
148 init("Carla-Rack");
149 pData->graph.create(0, 0, 0, 0); // FIXME?
152 if (pData->options.resourceDir != nullptr)
153 delete[] pData->options.resourceDir;
154 if (pData->options.binaryDir != nullptr)
155 delete[] pData->options.binaryDir;
157 const water::String binaryDir(File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName());
159 pData->options.resourceDir = carla_strdup(pHost->resourceDir);
160 pData->options.binaryDir = carla_strdup(binaryDir.toRawUTF8());
163 ~CarlaEngineNative() override
165 CARLA_SAFE_ASSERT(! fIsActive);
166 carla_debug("CarlaEngineNative::~CarlaEngineNative() - START");
168 pData->aboutToClose = true;
169 fIsRunning = false;
171 removeAllPlugins();
172 //runPendingRtEvents();
173 close();
175 pData->graph.destroy();
177 carla_debug("CarlaEngineNative::~CarlaEngineNative() - END");
180 // -------------------------------------
181 // CarlaEngine virtual calls
183 bool init(const char* const clientName) override
185 carla_debug("CarlaEngineNative::init(\"%s\")", clientName);
187 fIsRunning = true;
189 if (! pData->init(clientName))
191 close();
192 setLastError("Failed to init internal data");
193 return false;
196 pData->bufferSize = pHost->get_buffer_size(pHost->handle);
197 pData->sampleRate = pHost->get_sample_rate(pHost->handle);
199 return true;
202 bool close() override
204 fIsRunning = false;
205 CarlaEngine::close();
206 return true;
209 bool hasIdleOnMainThread() const noexcept override
211 return false;
214 bool isRunning() const noexcept override
216 return fIsRunning;
219 bool isOffline() const noexcept override
221 return pHost->is_offline(pHost->handle);
224 bool usesConstantBufferSize() const noexcept override
226 // TODO LV2 hosts can report this, till then we allow this
227 return true;
230 EngineType getType() const noexcept override
232 return kEngineTypePlugin;
235 const char* getCurrentDriverName() const noexcept override
237 return "Plugin";
240 const char* getCurrentProjectFolder() const noexcept override
242 CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);
244 static char filetype[] = "carla\0";
246 try {
247 return (const char*)(uintptr_t)pHost->dispatcher(pHost->handle,
248 NATIVE_HOST_OPCODE_GET_FILE_PATH,
249 0, 0,
250 (void*)filetype,
251 0.0f);
252 } CARLA_SAFE_EXCEPTION_RETURN("get_file_path", nullptr);
255 void callback(const bool sendHost, const bool sendOsc,
256 const EngineCallbackOpcode action, const uint pluginId,
257 const int value1, const int value2, const int value3,
258 const float valuef, const char* const valueStr) noexcept override
260 CarlaEngine::callback(sendHost, sendOsc, action, pluginId, value1, value2, value3, valuef, valueStr);
262 #ifndef CARLA_ENGINE_WITHOUT_UI
263 if (sendHost)
264 uiServerCallback(action, pluginId, value1, value2, value3, valuef, valueStr);
265 #endif
267 switch (action)
269 case ENGINE_CALLBACK_IDLE:
270 if (! pData->aboutToClose)
271 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_HOST_IDLE, 0, 0, nullptr, 0.0f);
272 break;
274 case ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
275 if (sendHost && value1 >= 0)
277 uint32_t rindex = static_cast<uint32_t>(value1);
278 if (_getRealIndexForPluginParameter(pluginId, rindex))
280 fParameters[rindex] = valuef;
282 if (fUsesEmbed
283 #ifndef CARLA_ENGINE_WITHOUT_UI
284 || fUiServer.isPipeRunning()
285 #endif
288 pHost->ui_parameter_changed(pHost->handle, rindex, valuef);
290 else
292 static uint last_pluginId = pluginId;
293 static int last_value1 = value1;
294 static bool init = true;
296 if (init || last_pluginId != pluginId || last_value1 != value1)
298 init = false;
299 last_pluginId = pluginId;
300 last_value1 = value1;
301 carla_stdout("Plugin with id %d triggered parameter %d update while UI is hidden",
302 pluginId, value1);
307 break;
309 case ENGINE_CALLBACK_UI_STATE_CHANGED:
310 if (sendHost && fUsesEmbed)
311 pHost->ui_closed(pHost->handle);
312 break;
314 case ENGINE_CALLBACK_EMBED_UI_RESIZED:
315 if (sendHost && fUsesEmbed)
316 pHost->dispatcher(pHost->handle,
317 NATIVE_HOST_OPCODE_UI_RESIZE,
318 value1, value2,
319 nullptr, 0.0f);
320 break;
322 default:
323 break;
327 const char* runFileCallback(FileCallbackOpcode action,
328 bool isDir, const char* title, const char* filter) noexcept override
330 switch (action)
332 case FILE_CALLBACK_DEBUG:
333 return nullptr;
335 case FILE_CALLBACK_OPEN:
336 return pHost->ui_open_file(pHost->handle, isDir, title, filter);
338 case FILE_CALLBACK_SAVE:
339 return pHost->ui_save_file(pHost->handle, isDir, title, filter);
342 return nullptr;
345 // -------------------------------------------------------------------
347 void touchPluginParameter(const uint id, const uint32_t parameterId, const bool touch) noexcept override
349 setParameterTouchFromUI(id, parameterId, touch);
352 // -------------------------------------------------------------------
354 void setParameterValueFromUI(const uint32_t pluginId, const uint32_t index, const float value)
356 uint32_t rindex = index;
357 if (_getRealIndexForPluginParameter(pluginId, rindex))
359 fParameters[rindex] = value;
360 pHost->ui_parameter_changed(pHost->handle, rindex, value);
364 void setParameterTouchFromUI(const uint32_t pluginId, const uint32_t index, const bool touch)
366 uint32_t rindex = index;
367 if (_getRealIndexForPluginParameter(pluginId, rindex))
369 pHost->dispatcher(pHost->handle,
370 NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER,
371 static_cast<int32_t>(rindex),
372 touch ? 1 : 0,
373 nullptr, 0.0f);
377 void reloadFromUI()
379 carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
380 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_RELOAD_PARAMETERS, 0, 0, nullptr, 0.0f);
383 protected:
384 // -------------------------------------------------------------------
386 void bufferSizeChanged(const uint32_t newBufferSize)
388 if (pData->bufferSize == newBufferSize)
389 return;
391 #ifndef CARLA_ENGINE_WITHOUT_UI
393 const CarlaMutexLocker cml(fUiServer.getPipeLock());
395 if (fUiServer.writeMessage("buffer-size\n"))
397 char tmpBuf[STR_MAX+1];
398 carla_zeroChars(tmpBuf, STR_MAX+1);
400 std::snprintf(tmpBuf, STR_MAX, "%i\n", newBufferSize);
402 if (fUiServer.writeMessage(tmpBuf))
403 fUiServer.syncMessages();
406 #endif
408 pData->bufferSize = newBufferSize;
409 CarlaEngine::bufferSizeChanged(newBufferSize);
412 void sampleRateChanged(const double newSampleRate)
414 if (carla_isEqual(pData->sampleRate, newSampleRate))
415 return;
417 #ifndef CARLA_ENGINE_WITHOUT_UI
419 const CarlaMutexLocker cml(fUiServer.getPipeLock());
421 if (fUiServer.writeMessage("sample-rate\n"))
423 char tmpBuf[STR_MAX+1];
424 carla_zeroChars(tmpBuf, STR_MAX+1);
427 const CarlaScopedLocale csl;
428 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", newSampleRate);
431 if (fUiServer.writeMessage(tmpBuf))
432 fUiServer.syncMessages();
435 #endif
437 pData->sampleRate = newSampleRate;
438 CarlaEngine::sampleRateChanged(newSampleRate);
441 #ifndef CARLA_ENGINE_WITHOUT_UI
442 // -------------------------------------------------------------------
444 void uiServerSendPluginInfo(const CarlaPluginPtr& plugin)
446 char tmpBuf[STR_MAX+1];
447 carla_zeroChars(tmpBuf, STR_MAX+1);
449 const CarlaMutexLocker cml(fUiServer.getPipeLock());
451 const uint pluginId(plugin->getId());
453 std::snprintf(tmpBuf, STR_MAX, "PLUGIN_INFO_%i\n", pluginId);
454 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
456 std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:" P_INT64 ":%i:%i\n",
457 plugin->getType(), plugin->getCategory(),
458 plugin->getHints(), plugin->getUniqueId(),
459 plugin->getOptionsAvailable(), plugin->getOptionsEnabled());
460 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
462 if (const char* const filename = plugin->getFilename())
464 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(filename),);
466 else
468 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
471 if (const char* const name = plugin->getName())
473 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(name),);
475 else
477 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
480 if (const char* const iconName = plugin->getIconName())
482 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(iconName),);
484 else
486 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
489 if (plugin->getRealName(tmpBuf)) {
490 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
491 } else {
492 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
495 if (plugin->getLabel(tmpBuf)) {
496 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
497 } else {
498 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
501 if (plugin->getMaker(tmpBuf)) {
502 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
503 } else {
504 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
507 if (plugin->getCopyright(tmpBuf)) {
508 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
509 } else {
510 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
513 std::snprintf(tmpBuf, STR_MAX, "AUDIO_COUNT_%i:%i:%i\n",
514 pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount());
515 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
517 std::snprintf(tmpBuf, STR_MAX, "MIDI_COUNT_%i:%i:%i\n",
518 pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount());
519 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
521 fUiServer.syncMessages();
524 void uiServerSendPluginParameters(const CarlaPluginPtr& plugin)
526 char tmpBuf[STR_MAX+1];
527 carla_zeroChars(tmpBuf, STR_MAX+1);
529 const CarlaMutexLocker cml(fUiServer.getPipeLock());
530 const CarlaScopedLocale csl;
532 const uint pluginId(plugin->getId());
534 for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i)
536 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%i\n", pluginId, i);
537 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
539 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getInternalParameterValue(i)));
540 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
542 fUiServer.syncMessages();
545 uint32_t ins, outs, count;
546 plugin->getParameterCountInfo(ins, outs);
547 count = plugin->getParameterCount();
549 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count);
550 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
552 for (uint32_t i=0; i<count; ++i)
554 const ParameterData& paramData(plugin->getParameterData(i));
555 const ParameterRanges& paramRanges(plugin->getParameterRanges(i));
557 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_DATA_%i:%i\n", pluginId, i);
558 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
560 std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:%i\n", paramData.type, paramData.hints,
561 paramData.mappedControlIndex, paramData.midiChannel);
562 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
564 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g\n", static_cast<double>(paramData.mappedMinimum),
565 static_cast<double>(paramData.mappedMaximum));
566 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
568 if (plugin->getParameterName(i, tmpBuf)) {
569 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
570 } else {
571 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
574 if (plugin->getParameterUnit(i, tmpBuf)) {
575 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
576 } else {
577 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
580 if (plugin->getParameterComment(i, tmpBuf)) {
581 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
582 } else {
583 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
586 if (plugin->getParameterGroupName(i, tmpBuf)) {
587 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
588 } else {
589 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
592 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_RANGES_%i:%i\n", pluginId, i);
593 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
595 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g:%.12g:%.12g\n",
596 static_cast<double>(paramRanges.def),
597 static_cast<double>(paramRanges.min),
598 static_cast<double>(paramRanges.max),
599 static_cast<double>(paramRanges.step),
600 static_cast<double>(paramRanges.stepSmall),
601 static_cast<double>(paramRanges.stepLarge));
602 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
604 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", pluginId, i);
605 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
607 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(i)));
608 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
611 fUiServer.syncMessages();
614 void uiServerSendPluginPrograms(const CarlaPluginPtr& plugin)
616 char tmpBuf[STR_MAX+1];
617 carla_zeroChars(tmpBuf, STR_MAX+1);
619 const CarlaMutexLocker cml(fUiServer.getPipeLock());
621 const uint pluginId(plugin->getId());
623 uint32_t count = plugin->getProgramCount();
624 std::snprintf(tmpBuf, STR_MAX, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram());
625 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
627 for (uint32_t i=0; i<count; ++i)
629 std::snprintf(tmpBuf, STR_MAX, "PROGRAM_NAME_%i:%i\n", pluginId, i);
630 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
632 if (plugin->getProgramName(i, tmpBuf)) {
633 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
634 } else {
635 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
639 fUiServer.syncMessages();
641 count = plugin->getMidiProgramCount();
642 std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_COUNT_%i:%i:%i\n",
643 pluginId, count, plugin->getCurrentMidiProgram());
644 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
646 for (uint32_t i=0; i<count; ++i)
648 std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i);
649 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
651 const MidiProgramData& mpData(plugin->getMidiProgramData(i));
653 std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program);
654 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
656 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(mpData.name),);
659 fUiServer.syncMessages();
662 void uiServerSendPluginProperties(const CarlaPluginPtr& plugin)
664 char tmpBuf[STR_MAX+1];
665 carla_zeroChars(tmpBuf, STR_MAX+1);
667 const CarlaMutexLocker cml(fUiServer.getPipeLock());
669 const uint pluginId(plugin->getId());
671 uint32_t count = plugin->getCustomDataCount();
672 std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_COUNT_%i:%i\n", pluginId, count);
673 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
675 for (uint32_t i=0; i<count; ++i)
677 const CustomData& customData(plugin->getCustomData(i));
678 CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
680 if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_PROPERTY) != 0)
681 continue;
683 std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_%i:%i\n", pluginId, i);
684 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
685 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.type),);
686 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.key),);
687 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.value),);
690 fUiServer.syncMessages();
693 void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId,
694 const int value1, const int value2, const int value3,
695 const float valuef, const char* const valueStr)
697 if (! fIsRunning)
698 return;
699 if (! fUiServer.isPipeRunning())
700 return;
702 switch (action)
704 case ENGINE_CALLBACK_UPDATE:
705 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
707 if (plugin->isEnabled())
709 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
710 uiServerSendPluginProperties(plugin);
713 break;
715 case ENGINE_CALLBACK_RELOAD_INFO:
716 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
718 if (plugin->isEnabled())
720 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
721 uiServerSendPluginInfo(plugin);
724 break;
726 case ENGINE_CALLBACK_RELOAD_PARAMETERS:
727 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
729 if (plugin->isEnabled())
731 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
732 uiServerSendPluginParameters(plugin);
735 break;
737 case ENGINE_CALLBACK_RELOAD_PROGRAMS:
738 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
740 if (plugin->isEnabled())
742 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
743 uiServerSendPluginPrograms(plugin);
746 break;
748 case ENGINE_CALLBACK_RELOAD_ALL:
749 case ENGINE_CALLBACK_PLUGIN_ADDED:
750 case ENGINE_CALLBACK_PLUGIN_RENAMED:
751 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
753 if (plugin->isEnabled())
755 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
756 uiServerSendPluginInfo(plugin);
757 uiServerSendPluginParameters(plugin);
758 uiServerSendPluginPrograms(plugin);
759 uiServerSendPluginProperties(plugin);
762 break;
764 default:
765 break;
768 char tmpBuf[STR_MAX+1];
769 carla_zeroChars(tmpBuf, STR_MAX+1);
771 const CarlaMutexLocker cml(fUiServer.getPipeLock());
773 std::snprintf(tmpBuf, STR_MAX, "ENGINE_CALLBACK_%i\n", int(action));
774 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
776 std::snprintf(tmpBuf, STR_MAX, "%u\n", pluginId);
777 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
779 std::snprintf(tmpBuf, STR_MAX, "%i\n", value1);
780 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
782 std::snprintf(tmpBuf, STR_MAX, "%i\n", value2);
783 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
785 std::snprintf(tmpBuf, STR_MAX, "%i\n", value3);
786 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
789 const CarlaScopedLocale csl;
790 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(valuef));
792 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
794 if (valueStr != nullptr) {
795 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(valueStr),);
796 } else {
797 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
800 fUiServer.syncMessages();
803 void uiServerInfo()
805 CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
806 CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
808 char tmpBuf[STR_MAX+1];
809 carla_zeroChars(tmpBuf, STR_MAX+1);
811 const CarlaMutexLocker cml(fUiServer.getPipeLock());
813 #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
814 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("osc-urls\n"),);
815 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathTCP()),);
816 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathUDP()),);
817 #endif
819 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("max-plugin-number\n"),);
820 std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->maxPluginNumber);
821 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
823 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("buffer-size\n"),);
824 std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->bufferSize);
825 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
827 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("sample-rate\n"),);
829 const CarlaScopedLocale csl;
830 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", pData->sampleRate);
832 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
834 fUiServer.syncMessages();
837 void uiServerOptions()
839 CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
840 CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
842 char tmpBuf[STR_MAX+1];
843 carla_zeroChars(tmpBuf, STR_MAX+1);
845 const EngineOptions& options(pData->options);
846 const CarlaMutexLocker cml(fUiServer.getPipeLock());
848 const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n");
849 const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6);
851 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE);
852 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
853 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
854 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.processMode);
855 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
856 fUiServer.syncMessages();
858 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE);
859 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
860 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
861 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.transportMode);
862 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
863 fUiServer.syncMessages();
865 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO);
866 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
867 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
868 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.forceStereo ? "true\n" : "false\n"),);
869 fUiServer.syncMessages();
871 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES);
872 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
873 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
874 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferPluginBridges ? "true\n" : "false\n"),);
875 fUiServer.syncMessages();
877 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES);
878 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
879 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
880 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferUiBridges ? "true\n" : "false\n"),);
881 fUiServer.syncMessages();
883 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP);
884 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
885 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
886 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.uisAlwaysOnTop ? "true\n" : "false\n"),);
887 fUiServer.syncMessages();
889 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS);
890 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
891 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
892 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.maxParameters);
893 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
894 fUiServer.syncMessages();
896 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT);
897 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
898 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
899 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.uiBridgesTimeout);
900 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
901 fUiServer.syncMessages();
903 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES);
904 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
905 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
906 std::snprintf(tmpBuf, STR_MAX, "%s\n", options.binaryDir);
907 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
908 fUiServer.syncMessages();
910 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES);
911 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
912 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
913 std::snprintf(tmpBuf, STR_MAX, "%s\n", options.resourceDir);
914 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
915 fUiServer.syncMessages();
917 #endif
919 // -------------------------------------------------------------------
920 // Plugin parameter calls
922 uint32_t getParameterCount() const
924 return kNumInParams + kNumOutParams;
927 const NativeParameter* getParameterInfo(const uint32_t index) const
929 static NativeParameter param;
931 static char strBufName[STR_MAX+1];
932 static char strBufUnit[STR_MAX+1];
933 static char strBufComment[STR_MAX+1];
934 static char strBufGroupName[STR_MAX+1];
935 carla_zeroChars(strBufName, STR_MAX+1);
936 carla_zeroChars(strBufUnit, STR_MAX+1);
937 carla_zeroChars(strBufComment, STR_MAX+1);
938 carla_zeroChars(strBufGroupName, STR_MAX+1);
940 uint32_t rindex = index;
941 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
943 const ParameterData& paramData(plugin->getParameterData(rindex));
944 const ParameterRanges& paramRanges(plugin->getParameterRanges(rindex));
946 if (! plugin->getParameterName(rindex, strBufName))
947 strBufName[0] = '\0';
948 if (! plugin->getParameterUnit(rindex, strBufUnit))
949 strBufUnit[0] = '\0';
950 if (! plugin->getParameterComment(rindex, strBufComment))
951 strBufComment[0] = '\0';
952 if (! plugin->getParameterGroupName(rindex, strBufGroupName))
953 std::snprintf(strBufGroupName, STR_MAX, "%u:%s", plugin->getId(), plugin->getName());
955 uint hints = 0x0;
957 if (paramData.hints & PARAMETER_IS_BOOLEAN)
958 hints |= NATIVE_PARAMETER_IS_BOOLEAN;
959 if (paramData.hints & PARAMETER_IS_INTEGER)
960 hints |= NATIVE_PARAMETER_IS_INTEGER;
961 if (paramData.hints & PARAMETER_IS_LOGARITHMIC)
962 hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
963 if (paramData.hints & PARAMETER_IS_AUTOMATABLE)
964 hints |= NATIVE_PARAMETER_IS_AUTOMATABLE;
965 if (paramData.hints & PARAMETER_USES_SAMPLERATE)
966 hints |= NATIVE_PARAMETER_USES_SAMPLE_RATE;
967 if (paramData.hints & PARAMETER_USES_SCALEPOINTS)
968 hints |= NATIVE_PARAMETER_USES_SCALEPOINTS;
970 if (paramData.type == PARAMETER_INPUT || paramData.type == PARAMETER_OUTPUT)
972 if (paramData.hints & PARAMETER_IS_ENABLED)
973 hints |= NATIVE_PARAMETER_IS_ENABLED;
974 if (paramData.type == PARAMETER_OUTPUT)
975 hints |= NATIVE_PARAMETER_IS_OUTPUT;
978 param.hints = static_cast<NativeParameterHints>(hints);
979 param.name = strBufName;
980 param.unit = strBufUnit;
981 param.comment = strBufComment;
982 param.groupName = strBufGroupName;
983 param.ranges.def = paramRanges.def;
984 param.ranges.min = paramRanges.min;
985 param.ranges.max = paramRanges.max;
986 param.ranges.step = paramRanges.step;
987 param.ranges.stepSmall = paramRanges.stepSmall;
988 param.ranges.stepLarge = paramRanges.stepLarge;
989 param.scalePointCount = 0; // TODO
990 param.scalePoints = nullptr;
992 return &param;
995 param.hints = index < kNumInParams ? static_cast<NativeParameterHints>(0x0) : NATIVE_PARAMETER_IS_OUTPUT;
996 param.name = "Unused";
997 param.unit = "";
998 param.ranges.def = 0.0f;
999 param.ranges.min = 0.0f;
1000 param.ranges.max = 1.0f;
1001 param.ranges.step = 0.01f;
1002 param.ranges.stepSmall = 0.001f;
1003 param.ranges.stepLarge = 0.1f;
1004 param.scalePointCount = 0;
1005 param.scalePoints = nullptr;
1007 return &param;
1010 float getParameterValue(const uint32_t index) const
1012 uint32_t rindex = index;
1013 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1014 return plugin->getParameterValue(rindex);
1016 return fParameters[index];
1019 // -------------------------------------------------------------------
1020 // Plugin state calls
1022 void setParameterValue(const uint32_t index, const float value)
1024 uint32_t rindex = index;
1025 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1026 plugin->setParameterValueRT(rindex, value, 0, false);
1028 fParameters[index] = value;
1031 // -------------------------------------------------------------------
1032 // Plugin process calls
1034 void activate()
1036 #if 0
1037 for (uint i=0; i < pData->curPluginCount; ++i)
1039 CarlaPluginPtr plugin = pData->plugins[i].plugin;
1041 if (plugin == nullptr || ! plugin->isEnabled())
1042 continue;
1044 plugin->setActive(true, true, false);
1046 #endif
1047 fIsActive = true;
1050 void deactivate()
1052 fIsActive = false;
1053 #if 0
1054 for (uint i=0; i < pData->curPluginCount; ++i)
1056 CarlaPluginPtr plugin = pData->plugins[i].plugin;
1058 if (plugin == nullptr || ! plugin->isEnabled())
1059 continue;
1061 plugin->setActive(false, true, false);
1063 #endif
1065 // just in case
1066 //runPendingRtEvents();
1069 void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames,
1070 const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount)
1072 if (frames > pData->bufferSize)
1074 carla_stderr2("Host is calling process with too high number of frames! %u vs %u",
1075 frames, pData->bufferSize);
1077 deactivate();
1078 bufferSizeChanged(frames);
1079 activate();
1082 const PendingRtEventsRunner prt(this, frames, true);
1084 // ---------------------------------------------------------------
1085 // Time Info
1087 const NativeTimeInfo* const timeInfo(pHost->get_time_info(pHost->handle));
1089 pData->timeInfo.playing = timeInfo->playing;
1090 pData->timeInfo.frame = timeInfo->frame;
1091 pData->timeInfo.usecs = timeInfo->usecs;
1092 pData->timeInfo.bbt.valid = timeInfo->bbt.valid;
1094 if (timeInfo->bbt.valid)
1096 pData->timeInfo.bbt.bar = timeInfo->bbt.bar;
1097 pData->timeInfo.bbt.beat = timeInfo->bbt.beat;
1098 pData->timeInfo.bbt.tick = timeInfo->bbt.tick;
1099 pData->timeInfo.bbt.barStartTick = timeInfo->bbt.barStartTick;
1101 pData->timeInfo.bbt.beatsPerBar = timeInfo->bbt.beatsPerBar;
1102 pData->timeInfo.bbt.beatType = timeInfo->bbt.beatType;
1104 pData->timeInfo.bbt.ticksPerBeat = timeInfo->bbt.ticksPerBeat;
1105 pData->timeInfo.bbt.beatsPerMinute = timeInfo->bbt.beatsPerMinute;
1108 // ---------------------------------------------------------------
1109 // Do nothing if no plugins and rack mode
1111 if (pData->curPluginCount == 0 && ! kIsPatchbay)
1113 if (outBuffer[0] != inBuffer[0])
1114 carla_copyFloats(outBuffer[0], inBuffer[0], frames);
1116 if (outBuffer[1] != inBuffer[1])
1117 carla_copyFloats(outBuffer[1], inBuffer[1], frames);
1119 for (uint32_t i=0; i < midiEventCount; ++i)
1121 if (! pHost->write_midi_event(pHost->handle, &midiEvents[i]))
1122 break;
1124 return;
1127 // ---------------------------------------------------------------
1128 // initialize events
1130 carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
1131 carla_zeroStructs(pData->events.out, kMaxEngineEventInternalCount);
1133 // ---------------------------------------------------------------
1134 // events input (before processing)
1136 if (kHasMidiIn)
1138 uint32_t engineEventIndex = 0;
1140 for (uint32_t i=0; i < midiEventCount && engineEventIndex < kMaxEngineEventInternalCount; ++i)
1142 const NativeMidiEvent& midiEvent(midiEvents[i]);
1143 EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);
1145 engineEvent.time = midiEvent.time;
1146 engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data, 0);
1148 if (engineEventIndex >= kMaxEngineEventInternalCount)
1149 break;
1153 if (kIsPatchbay)
1155 // -----------------------------------------------------------
1156 // process
1158 pData->graph.process(pData, inBuffer, outBuffer, frames);
1160 else
1162 // -----------------------------------------------------------
1163 // create audio buffers
1165 const float* inBuf[2] = { inBuffer[0], inBuffer[1] };
1166 /* */ float* outBuf[2] = { outBuffer[0], outBuffer[1] };
1168 // -----------------------------------------------------------
1169 // process
1171 pData->graph.processRack(pData, inBuf, outBuf, frames);
1174 // ---------------------------------------------------------------
1175 // events output (after processing)
1177 carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
1179 if (kHasMidiOut)
1181 NativeMidiEvent midiEvent;
1183 for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
1185 const EngineEvent& engineEvent(pData->events.out[i]);
1187 if (engineEvent.type == kEngineEventTypeNull)
1188 break;
1190 carla_zeroStruct(midiEvent);
1191 midiEvent.time = engineEvent.time;
1193 /**/ if (engineEvent.type == kEngineEventTypeControl)
1195 midiEvent.port = 0;
1196 midiEvent.size = engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.data);
1198 else if (engineEvent.type == kEngineEventTypeMidi)
1200 if (engineEvent.midi.size > 4)
1201 continue;
1203 midiEvent.port = engineEvent.midi.port;
1204 midiEvent.size = engineEvent.midi.size;
1206 midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
1208 for (uint8_t j=1; j < midiEvent.size; ++j)
1209 midiEvent.data[j] = engineEvent.midi.data[j];
1211 else
1213 continue;
1216 if (midiEvent.size > 0)
1217 pHost->write_midi_event(pHost->handle, &midiEvent);
1222 // -------------------------------------------------------------------
1223 // Plugin UI calls
1225 #ifndef CARLA_ENGINE_WITHOUT_UI
1226 void uiShow(const bool show)
1228 if (show)
1230 if (fUiServer.isPipeRunning())
1232 fUiServer.writeFocusMessage();
1233 return;
1236 CarlaString path(pHost->resourceDir);
1238 if (kIsPatchbay)
1239 path += CARLA_OS_SEP_STR "carla-plugin-patchbay";
1240 else
1241 path += CARLA_OS_SEP_STR "carla-plugin";
1242 #ifdef CARLA_OS_WIN
1243 path += ".exe";
1244 #endif
1245 carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer());
1247 fUiServer.setData(path, pData->sampleRate, pHost->uiName);
1249 #ifdef CARLA_OS_WIN
1250 // Fix conflict with other tools using Carla
1251 char* const oldcwd = _getcwd(nullptr, 0);
1252 chdir(pHost->resourceDir);
1253 #endif
1255 if (! fUiServer.startPipeServer(false))
1257 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
1258 return;
1261 uiServerInfo();
1262 uiServerOptions();
1263 uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED,
1264 pData->curPluginCount,
1265 pData->options.processMode,
1266 pData->options.transportMode,
1267 static_cast<int>(pData->bufferSize),
1268 static_cast<float>(pData->sampleRate),
1269 "Plugin");
1271 fUiServer.writeShowMessage();
1273 for (uint i=0; i < pData->curPluginCount; ++i)
1275 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1276 if (plugin->isEnabled())
1277 uiServerCallback(ENGINE_CALLBACK_PLUGIN_ADDED, i, plugin->getType(),
1278 0, 0, 0.0f,
1279 plugin->getName());
1282 if (kIsPatchbay)
1283 patchbayRefresh(true, false, false);
1285 #ifdef CARLA_OS_WIN
1286 chdir(oldcwd);
1287 std::free(oldcwd);
1288 #endif
1290 else
1292 fUiServer.stopPipeServer(2000);
1294 // hide all custom uis
1295 for (uint i=0; i < pData->curPluginCount; ++i)
1297 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1299 if (plugin->isEnabled())
1301 if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
1303 try {
1304 plugin->showCustomUI(false);
1305 } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin showCustomUI (hide)");
1312 #endif
1314 void uiIdle()
1316 for (uint i=0; i < pData->curPluginCount; ++i)
1318 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1320 if (plugin->isEnabled())
1322 const uint hints = plugin->getHints();
1324 if ((hints & PLUGIN_HAS_CUSTOM_UI) != 0 && (hints & PLUGIN_NEEDS_UI_MAIN_THREAD) != 0)
1326 try {
1327 plugin->uiIdle();
1328 } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin uiIdle");
1334 #ifndef CARLA_ENGINE_WITHOUT_UI
1335 idlePipe();
1337 switch (fUiServer.getAndResetUiState())
1339 case CarlaExternalUI::UiNone:
1340 case CarlaExternalUI::UiShow:
1341 break;
1342 case CarlaExternalUI::UiCrashed:
1343 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
1344 break;
1345 case CarlaExternalUI::UiHide:
1346 pHost->ui_closed(pHost->handle);
1347 fUiServer.stopPipeServer(1000);
1348 break;
1350 #endif
1352 if (carla_isNotEqual(fLastScaleFactor, pData->options.uiScale))
1354 fLastScaleFactor = pData->options.uiScale;
1356 if (! fUsesEmbed)
1357 pHost->dispatcher(pHost->handle,
1358 NATIVE_HOST_OPCODE_UI_RESIZE,
1359 static_cast<int>(kUiWidth * fLastScaleFactor + 0.5f),
1360 static_cast<int>(kUiHeight * fLastScaleFactor + 0.5f),
1361 nullptr, 0.0f);
1365 const CarlaMutexLocker cml(fPluginDeleterMutex);
1366 pData->deletePluginsAsNeeded();
1370 void uiSetParameterValue(const uint32_t index, const float value)
1372 uint32_t rindex = index;
1373 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1375 if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
1376 plugin->uiParameterChange(rindex, value);
1378 #ifndef CARLA_ENGINE_WITHOUT_UI
1379 if (index >= kNumInParams || ! fUiServer.isPipeRunning())
1380 return;
1382 uiServerCallback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
1383 plugin->getId(),
1384 static_cast<int>(rindex),
1385 0, 0,
1386 value,
1387 nullptr);
1388 #endif
1392 #ifndef CARLA_ENGINE_WITHOUT_UI
1393 void idlePipe()
1395 if (! fUiServer.isPipeRunning())
1396 return;
1398 fUiServer.idlePipe();
1400 if (! fUiServer.isPipeRunning())
1401 return;
1403 char tmpBuf[STR_MAX+1];
1404 carla_zeroChars(tmpBuf, STR_MAX+1);
1406 const CarlaMutexLocker cml(fUiServer.getPipeLock());
1407 const CarlaScopedLocale csl;
1408 const EngineTimeInfo& timeInfo(pData->timeInfo);
1410 // ------------------------------------------------------------------------------------------------------------
1411 // send engine info
1413 std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad()));
1414 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("runtime-info\n"),);
1415 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1417 fUiServer.syncMessages();
1419 if (const char* const projFolder = getCurrentProjectFolder())
1421 if (fLastProjectFolder != projFolder)
1423 carla_stdout("Project folder changed to %s", projFolder);
1424 fLastProjectFolder = projFolder;
1425 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("project-folder\n"),);
1426 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(projFolder),);
1427 fUiServer.syncMessages();
1431 // ------------------------------------------------------------------------------------------------------------
1432 // send transport
1434 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("transport\n"),);
1435 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),);
1437 if (timeInfo.bbt.valid)
1439 std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":%i:%i:%i\n", timeInfo.frame,
1440 timeInfo.bbt.bar,
1441 timeInfo.bbt.beat,
1442 static_cast<int>(timeInfo.bbt.tick + 0.5));
1443 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1444 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", timeInfo.bbt.beatsPerMinute);
1445 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1447 else
1449 std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":0:0:0\n", timeInfo.frame);
1450 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1451 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("0.0\n"),);
1454 fUiServer.syncMessages();
1456 // ------------------------------------------------------------------------------------------------------------
1457 // send peaks and param outputs for all plugins
1459 for (uint i=0; i < pData->curPluginCount; ++i)
1461 const EnginePluginData& plugData(pData->plugins[i]);
1462 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1464 std::snprintf(tmpBuf, STR_MAX, "PEAKS_%i\n", i);
1465 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1466 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g\n",
1467 static_cast<double>(plugData.peaks[0]),
1468 static_cast<double>(plugData.peaks[1]),
1469 static_cast<double>(plugData.peaks[2]),
1470 static_cast<double>(plugData.peaks[3]));
1471 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1473 fUiServer.syncMessages();
1475 for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j)
1477 if (! plugin->isParameterOutput(j))
1478 continue;
1480 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", i, j);
1481 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1482 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(j)));
1483 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1485 fUiServer.syncMessages();
1489 #endif
1491 // -------------------------------------------------------------------
1492 // Plugin state calls
1494 char* getState() const
1496 MemoryOutputStream out;
1497 saveProjectInternal(out);
1498 return strdup(out.toString().toRawUTF8());
1501 void setState(const char* const data)
1503 // remove all plugins from UI side
1504 for (uint i=0, count=pData->curPluginCount; i < count; ++i)
1505 CarlaEngine::callback(true, true, ENGINE_CALLBACK_PLUGIN_REMOVED, count-i-1, 0, 0, 0, 0.0f, nullptr);
1507 // remove all plugins from backend, no lock
1508 fIsRunning = false;
1509 removeAllPlugins();
1510 fIsRunning = true;
1513 const CarlaMutexLocker cml(fPluginDeleterMutex);
1514 pData->deletePluginsAsNeeded();
1517 // stopped during removeAllPlugins()
1518 if (! pData->runner.isRunnerActive())
1519 pData->runner.start();
1521 fOptionsForced = true;
1522 const String state(data);
1523 XmlDocument xml(state);
1524 loadProjectInternal(xml, true);
1526 reloadFromUI();
1529 // -------------------------------------------------------------------
1531 public:
1532 #define handlePtr ((CarlaEngineNative*)handle)
1534 static NativePluginHandle _instantiateRack(const NativeHostDescriptor* host)
1536 return new CarlaEngineNative(host, false, true, true);
1539 static NativePluginHandle _instantiateRackNoMidiOut(const NativeHostDescriptor* host)
1541 return new CarlaEngineNative(host, false, true, false);
1544 static NativePluginHandle _instantiatePatchbay(const NativeHostDescriptor* host)
1546 return new CarlaEngineNative(host, true, true, true);
1549 static NativePluginHandle _instantiatePatchbay3s(const NativeHostDescriptor* host)
1551 return new CarlaEngineNative(host, true, true, true, 3, 2);
1554 static NativePluginHandle _instantiatePatchbay16(const NativeHostDescriptor* host)
1556 return new CarlaEngineNative(host, true, true, true, 16, 16);
1559 static NativePluginHandle _instantiatePatchbay32(const NativeHostDescriptor* host)
1561 return new CarlaEngineNative(host, true, true, true, 32, 32);
1564 static NativePluginHandle _instantiatePatchbay64(const NativeHostDescriptor* host)
1566 return new CarlaEngineNative(host, true, true, true, 64, 64);
1569 static NativePluginHandle _instantiatePatchbayCV(const NativeHostDescriptor* host)
1571 return new CarlaEngineNative(host, true, true, true, 2, 2, 5, 5);
1574 static NativePluginHandle _instantiatePatchbayCV8(const NativeHostDescriptor* host)
1576 return new CarlaEngineNative(host, true, true, true, 2, 2, 8, 8);
1579 static NativePluginHandle _instantiatePatchbayCV32(const NativeHostDescriptor* host)
1581 return new CarlaEngineNative(host, true, true, true, 64, 64, 32, 32);
1584 static NativePluginHandle _instantiatePatchbayOBS(const NativeHostDescriptor* host)
1586 return new CarlaEngineNative(host, true, false, false, 8, 8);
1589 static void _cleanup(NativePluginHandle handle)
1591 delete handlePtr;
1594 static uint32_t _get_parameter_count(NativePluginHandle handle)
1596 return handlePtr->getParameterCount();
1599 static const NativeParameter* _get_parameter_info(NativePluginHandle handle, uint32_t index)
1601 return handlePtr->getParameterInfo(index);
1604 static float _get_parameter_value(NativePluginHandle handle, uint32_t index)
1606 return handlePtr->getParameterValue(index);
1609 static void _set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
1611 handlePtr->setParameterValue(index, value);
1614 #ifndef CARLA_ENGINE_WITHOUT_UI
1615 static void _ui_show(NativePluginHandle handle, bool show)
1617 handlePtr->uiShow(show);
1619 #endif
1621 static void _ui_idle(NativePluginHandle handle)
1623 handlePtr->uiIdle();
1626 static void _ui_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
1628 handlePtr->uiSetParameterValue(index, value);
1631 static void _activate(NativePluginHandle handle)
1633 handlePtr->activate();
1636 static void _deactivate(NativePluginHandle handle)
1638 handlePtr->deactivate();
1641 // FIXME for v3.0, use const for the input buffer
1642 static void _process(NativePluginHandle handle,
1643 float** inBuffer, float** outBuffer, const uint32_t frames,
1644 const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
1646 handlePtr->process(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
1649 static char* _get_state(NativePluginHandle handle)
1651 return handlePtr->getState();
1654 static void _set_state(NativePluginHandle handle, const char* data)
1656 handlePtr->setState(data);
1659 static intptr_t _dispatcher(NativePluginHandle handle,
1660 NativePluginDispatcherOpcode opcode,
1661 int32_t index, intptr_t value, void* ptr, float opt)
1663 switch(opcode)
1665 case NATIVE_PLUGIN_OPCODE_NULL:
1666 return 0;
1667 case NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
1668 CARLA_SAFE_ASSERT_RETURN(value > 0, 0);
1669 handlePtr->bufferSizeChanged(static_cast<uint32_t>(value));
1670 return 0;
1671 case NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
1672 CARLA_SAFE_ASSERT_RETURN(opt > 0.0f, 0);
1673 handlePtr->sampleRateChanged(static_cast<double>(opt));
1674 return 0;
1675 case NATIVE_PLUGIN_OPCODE_OFFLINE_CHANGED:
1676 handlePtr->offlineModeChanged(value != 0);
1677 return 0;
1678 case NATIVE_PLUGIN_OPCODE_UI_NAME_CHANGED:
1679 //handlePtr->uiNameChanged(static_cast<const char*>(ptr));
1680 return 0;
1681 case NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE: {
1682 CarlaEngineNative* const engine = handlePtr;
1683 return (intptr_t)(CarlaEngine*)engine;
1685 case NATIVE_PLUGIN_OPCODE_IDLE:
1686 //handlePtr->idle();
1687 return 0;
1688 case NATIVE_PLUGIN_OPCODE_UI_MIDI_EVENT:
1689 return 0;
1690 case NATIVE_PLUGIN_OPCODE_HOST_USES_EMBED:
1691 handlePtr->fUsesEmbed = true;
1692 return 0;
1693 case NATIVE_PLUGIN_OPCODE_HOST_OPTION:
1694 handlePtr->setOption(static_cast<EngineOption>(index), value, static_cast<const char*>(ptr));
1695 return 0;
1698 return 0;
1700 // unused
1701 (void)index;
1702 (void)ptr;
1705 // -------------------------------------------------------------------
1707 #undef handlePtr
1709 private:
1710 const NativeHostDescriptor* const pHost;
1712 const bool kIsPatchbay; // rack if false
1713 const bool kHasMidiIn;
1714 const bool kHasMidiOut;
1715 bool fIsActive, fIsRunning, fUsesEmbed;
1716 #ifndef CARLA_ENGINE_WITHOUT_UI
1717 CarlaEngineNativeUI fUiServer;
1718 #endif
1719 float fLastScaleFactor;
1721 float fParameters[kNumInParams+kNumOutParams];
1722 CarlaString fLastProjectFolder;
1723 CarlaMutex fPluginDeleterMutex;
1725 bool fOptionsForced;
1727 CarlaPluginPtr _getPluginForParameterIndex(uint32_t& index) const noexcept
1729 if (pData->curPluginCount == 0 || pData->plugins == nullptr)
1730 return nullptr;
1732 for (uint32_t i=0; i<pData->curPluginCount; ++i)
1734 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1736 if (plugin.get() == nullptr || ! plugin->isEnabled())
1737 break;
1739 if (const uint32_t paramCount = plugin->getParameterCount())
1741 if (index >= paramCount)
1743 index -= paramCount;
1744 continue;
1747 return plugin;
1751 return nullptr;
1754 bool _getRealIndexForPluginParameter(const uint32_t pluginId, uint32_t& rindex) const noexcept
1756 if (pData->curPluginCount == 0 || pluginId >= pData->curPluginCount || pData->plugins == nullptr)
1757 return false;
1759 for (uint32_t i=0; i<pluginId; ++i)
1761 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1763 if (plugin.get() == nullptr || ! plugin->isEnabled())
1764 return false;
1766 rindex += plugin->getParameterCount();
1769 if (rindex >= kNumInParams)
1770 return false;
1772 return true;
1775 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNative)
1778 // -----------------------------------------------------------------------
1780 #ifndef CARLA_ENGINE_WITHOUT_UI
1781 bool CarlaEngineNativeUI::msgReceived(const char* const msg) noexcept
1783 if (CarlaExternalUI::msgReceived(msg))
1784 return true;
1786 bool ok = true;
1788 if (std::strcmp(msg, "set_engine_option") == 0)
1790 uint32_t option;
1791 int32_t value;
1792 const char* valueStr = nullptr;
1794 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
1795 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(value), true);
1796 readNextLineAsString(valueStr, false); // can be null
1798 try {
1799 fEngine->setOption(static_cast<EngineOption>(option), value, valueStr);
1800 } CARLA_SAFE_EXCEPTION("setOption");
1802 else if (std::strcmp(msg, "clear_engine_xruns") == 0)
1804 fEngine->clearXruns();
1806 else if (std::strcmp(msg, "cancel_engine_action") == 0)
1808 fEngine->setActionCanceled(true);
1810 else if (std::strcmp(msg, "load_file") == 0)
1812 const char* filename;
1814 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1816 try {
1817 ok = fEngine->loadFile(filename);
1818 } CARLA_SAFE_EXCEPTION("loadFile");
1820 fEngine->reloadFromUI();
1822 else if (std::strcmp(msg, "load_project") == 0)
1824 const char* filename;
1826 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1828 try {
1829 ok = fEngine->loadProject(filename, true);
1830 } CARLA_SAFE_EXCEPTION("loadProject");
1832 fEngine->reloadFromUI();
1834 else if (std::strcmp(msg, "save_project") == 0)
1836 const char* filename;
1838 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1840 try {
1841 ok = fEngine->saveProject(filename, true);
1842 } CARLA_SAFE_EXCEPTION("saveProject");
1844 else if (std::strcmp(msg, "clear_project_filename") == 0)
1846 fEngine->clearCurrentProjectFilename();
1848 else if (std::strcmp(msg, "patchbay_connect") == 0)
1850 bool external;
1851 uint32_t groupA, portA, groupB, portB;
1853 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1854 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupA), true);
1855 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portA), true);
1856 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupB), true);
1857 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portB), true);
1859 try {
1860 ok = fEngine->patchbayConnect(external, groupA, portA, groupB, portB);
1861 } CARLA_SAFE_EXCEPTION("patchbayConnect");
1863 else if (std::strcmp(msg, "patchbay_disconnect") == 0)
1865 bool external;
1866 uint32_t connectionId;
1868 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1869 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(connectionId), true);
1871 try {
1872 ok = fEngine->patchbayDisconnect(external, connectionId);
1873 } CARLA_SAFE_EXCEPTION("patchbayDisconnect");
1875 else if (std::strcmp(msg, "patchbay_set_group_pos") == 0)
1877 bool external;
1878 uint32_t groupId;
1879 int x1, y1, x2, y2;
1880 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1881 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupId), true);
1882 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x1), true);
1883 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y1), true);
1884 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x2), true);
1885 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y2), true);
1887 try {
1888 ok = fEngine->patchbaySetGroupPos(false, true, external, groupId, x1, y1, x2, y2);
1889 } CARLA_SAFE_EXCEPTION("patchbaySetGroupPos");
1891 else if (std::strcmp(msg, "patchbay_refresh") == 0)
1893 bool external;
1894 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1896 try {
1897 ok = fEngine->patchbayRefresh(true, false, external);
1898 } CARLA_SAFE_EXCEPTION("patchbayRefresh");
1900 else if (std::strcmp(msg, "transport_play") == 0)
1902 fEngine->transportPlay();
1904 else if (std::strcmp(msg, "transport_pause") == 0)
1906 fEngine->transportPause();
1908 else if (std::strcmp(msg, "transport_bpm") == 0)
1910 double bpm;
1912 CARLA_SAFE_ASSERT_RETURN(readNextLineAsDouble(bpm), true);
1914 fEngine->transportBPM(bpm);
1916 else if (std::strcmp(msg, "transport_relocate") == 0)
1918 uint64_t frame;
1920 CARLA_SAFE_ASSERT_RETURN(readNextLineAsULong(frame), true);
1922 fEngine->transportRelocate(frame);
1924 else if (std::strcmp(msg, "add_plugin") == 0)
1926 uint32_t btype, ptype;
1927 const char* filename = nullptr;
1928 const char* name;
1929 const char* label;
1930 int64_t uniqueId;
1931 uint options;
1933 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(btype), true);
1934 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(ptype), true);
1935 readNextLineAsString(filename, true); // can be null
1936 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(name, true), true);
1937 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(label, true), true);
1938 CARLA_SAFE_ASSERT_RETURN(readNextLineAsLong(uniqueId), true);
1939 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(options), true);
1941 if (filename != nullptr && std::strcmp(filename, "(null)") == 0)
1943 std::free(const_cast<char*>(filename));
1944 filename = nullptr;
1947 if (std::strcmp(name, "(null)") == 0)
1949 std::free(const_cast<char*>(name));
1950 name = nullptr;
1953 ok = fEngine->addPlugin(static_cast<BinaryType>(btype), static_cast<PluginType>(ptype),
1954 filename, name, label, uniqueId, nullptr, options);
1956 if (filename != nullptr)
1957 std::free(const_cast<char*>(filename));
1958 if (name != nullptr)
1959 std::free(const_cast<char*>(name));
1960 std::free(const_cast<char*>(label));
1962 fEngine->reloadFromUI();
1964 else if (std::strcmp(msg, "remove_plugin") == 0)
1966 uint32_t pluginId;
1968 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
1970 ok = fEngine->removePlugin(pluginId);
1971 fEngine->reloadFromUI();
1973 else if (std::strcmp(msg, "remove_all_plugins") == 0)
1975 ok = fEngine->removeAllPlugins();
1976 fEngine->reloadFromUI();
1978 else if (std::strcmp(msg, "rename_plugin") == 0)
1980 uint32_t pluginId;
1981 const char* newName;
1983 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
1984 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName, false), true);
1986 ok = fEngine->renamePlugin(pluginId, newName);
1988 else if (std::strcmp(msg, "clone_plugin") == 0)
1990 uint32_t pluginId;
1992 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
1994 ok = fEngine->clonePlugin(pluginId);
1995 fEngine->reloadFromUI();
1997 else if (std::strcmp(msg, "replace_plugin") == 0)
1999 uint32_t pluginId;
2001 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2003 ok = fEngine->replacePlugin(pluginId);
2005 else if (std::strcmp(msg, "switch_plugins") == 0)
2007 uint32_t pluginIdA, pluginIdB;
2009 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdA), true);
2010 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdB), true);
2012 ok = fEngine->switchPlugins(pluginIdA, pluginIdB);
2013 fEngine->reloadFromUI();
2015 else if (std::strcmp(msg, "load_plugin_state") == 0)
2017 uint32_t pluginId;
2018 const char* filename;
2020 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2021 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
2023 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2025 plugin->loadStateFromFile(filename);
2026 _updateParamValues(plugin, pluginId, false, true);
2029 else if (std::strcmp(msg, "save_plugin_state") == 0)
2031 uint32_t pluginId;
2032 const char* filename;
2034 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2035 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
2037 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2038 plugin->saveStateToFile(filename);
2040 else if (std::strcmp(msg, "set_option") == 0)
2042 uint32_t pluginId, option;
2043 bool yesNo;
2045 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2046 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
2047 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
2049 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2050 plugin->setOption(option, yesNo, false);
2052 else if (std::strcmp(msg, "set_active") == 0)
2054 uint32_t pluginId;
2055 bool onOff;
2057 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2058 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(onOff), true);
2060 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2061 plugin->setActive(onOff, true, false);
2063 else if (std::strcmp(msg, "set_drywet") == 0)
2065 uint32_t pluginId;
2066 float value;
2068 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2069 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2071 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2072 plugin->setDryWet(value, true, false);
2074 else if (std::strcmp(msg, "set_volume") == 0)
2076 uint32_t pluginId;
2077 float value;
2079 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2080 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2082 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2083 plugin->setVolume(value, true, false);
2085 else if (std::strcmp(msg, "set_balance_left") == 0)
2087 uint32_t pluginId;
2088 float value;
2090 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2091 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2093 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2094 plugin->setBalanceLeft(value, true, false);
2096 else if (std::strcmp(msg, "set_balance_right") == 0)
2098 uint32_t pluginId;
2099 float value;
2101 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2102 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2104 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2105 plugin->setBalanceRight(value, true, false);
2107 else if (std::strcmp(msg, "set_panning") == 0)
2109 uint32_t pluginId;
2110 float value;
2112 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2113 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2115 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2116 plugin->setPanning(value, true, false);
2118 else if (std::strcmp(msg, "set_ctrl_channel") == 0)
2120 uint32_t pluginId;
2121 int32_t channel;
2123 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2124 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel), true);
2125 CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS, true);
2127 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2128 plugin->setCtrlChannel(int8_t(channel), true, false);
2130 else if (std::strcmp(msg, "set_parameter_value") == 0)
2132 uint32_t pluginId, parameterId;
2133 float value;
2135 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2136 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2137 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2139 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2141 plugin->setParameterValue(parameterId, value, true, true, false);
2142 fEngine->setParameterValueFromUI(pluginId, parameterId, value);
2145 else if (std::strcmp(msg, "set_parameter_midi_channel") == 0)
2147 uint32_t pluginId, parameterId, channel;
2149 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2150 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2151 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
2152 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
2154 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2155 plugin->setParameterMidiChannel(parameterId, static_cast<uint8_t>(channel), true, false);
2157 else if (std::strcmp(msg, "set_parameter_mapped_control_index") == 0)
2159 uint32_t pluginId, parameterId;
2160 int32_t ctrl;
2162 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2163 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2164 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(ctrl), true);
2165 CARLA_SAFE_ASSERT_RETURN(ctrl >= CONTROL_INDEX_NONE && ctrl <= CONTROL_INDEX_MAX_ALLOWED, true);
2167 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2168 plugin->setParameterMappedControlIndex(parameterId, static_cast<int16_t>(ctrl), true, false, true);
2170 else if (std::strcmp(msg, "set_parameter_mapped_range") == 0)
2172 uint32_t pluginId, parameterId;
2173 float minimum, maximum;
2175 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2176 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2177 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(minimum), true);
2178 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(maximum), true);
2180 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2181 plugin->setParameterMappedRange(parameterId, minimum, maximum, true, false);
2183 else if (std::strcmp(msg, "set_parameter_touch") == 0)
2185 uint32_t pluginId, parameterId;
2186 bool touching;
2188 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2189 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2190 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(touching), true);
2192 if (fEngine->getPlugin(pluginId))
2193 fEngine->setParameterTouchFromUI(pluginId, parameterId, touching);
2195 else if (std::strcmp(msg, "set_program") == 0)
2197 uint32_t pluginId;
2198 int32_t index;
2200 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2201 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
2203 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2205 plugin->setProgram(index, true, true, false);
2206 _updateParamValues(plugin, pluginId, true, true);
2209 else if (std::strcmp(msg, "set_midi_program") == 0)
2211 uint32_t pluginId;
2212 int32_t index;
2214 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2215 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
2217 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2219 plugin->setMidiProgram(index, true, true, false);
2220 _updateParamValues(plugin, pluginId, true, true);
2223 else if (std::strcmp(msg, "set_custom_data") == 0)
2225 uint32_t pluginId;
2226 const char* type;
2227 const char* key;
2228 const char* value;
2230 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2231 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(type, true), true);
2232 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key, true), true);
2233 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value, false), true);
2235 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2236 plugin->setCustomData(type, key, value, true);
2238 std::free(const_cast<char*>(type));
2239 std::free(const_cast<char*>(key));
2241 else if (std::strcmp(msg, "set_chunk_data") == 0)
2243 uint32_t pluginId;
2244 const char* cdata;
2246 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2247 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(cdata, false), true);
2249 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2251 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(cdata));
2252 #ifdef CARLA_PROPER_CPP11_SUPPORT
2253 plugin->setChunkData(chunk.data(), chunk.size());
2254 #else
2255 plugin->setChunkData(&chunk.front(), chunk.size());
2256 #endif
2257 _updateParamValues(plugin, pluginId, false, true);
2260 else if (std::strcmp(msg, "prepare_for_save") == 0)
2262 uint32_t pluginId;
2264 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2266 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2267 plugin->prepareForSave(false);
2269 else if (std::strcmp(msg, "reset_parameters") == 0)
2271 uint32_t pluginId;
2273 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2275 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2277 plugin->resetParameters();
2278 _updateParamValues(plugin, pluginId, false, true);
2281 else if (std::strcmp(msg, "randomize_parameters") == 0)
2283 uint32_t pluginId;
2285 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2287 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2289 plugin->randomizeParameters();
2290 _updateParamValues(plugin, pluginId, false, true);
2293 else if (std::strcmp(msg, "send_midi_note") == 0)
2295 uint32_t pluginId, channel, note, velocity;
2297 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2298 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
2299 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(note), true);
2300 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(velocity), true);
2301 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
2302 CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_VALUE, true);
2303 CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE, true);
2305 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2306 plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(velocity), true, true, false);
2308 else if (std::strcmp(msg, "show_custom_ui") == 0)
2310 uint32_t pluginId;
2311 bool yesNo;
2313 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2314 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
2316 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2317 plugin->showCustomUI(yesNo);
2319 else
2321 carla_stderr("CarlaEngineNativeUI::msgReceived : %s", msg);
2322 return false;
2325 if (! ok)
2327 const CarlaMutexLocker cml(getPipeLock());
2329 if (writeMessage("error\n", 6) && writeAndFixMessage(fEngine->getLastError()))
2330 syncMessages();
2333 return true;
2336 void CarlaEngineNativeUI::_updateParamValues(const CarlaPluginPtr& plugin,
2337 const uint32_t pluginId,
2338 const bool sendCallback, const bool sendPluginHost) const noexcept
2340 float value;
2342 for (uint32_t i=0, count=plugin->getParameterCount(); i<count; ++i) {
2343 value = plugin->getParameterValue(i);
2345 if (sendCallback) {
2346 fEngine->callback(true, true,
2347 ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
2348 pluginId,
2349 static_cast<int>(i),
2350 0, 0,
2351 value,
2352 nullptr);
2355 if (sendPluginHost) {
2356 carla_stdout("_updateParamValues");
2357 fEngine->setParameterValueFromUI(pluginId, i, value);
2361 #endif
2363 // -----------------------------------------------------------------------
2365 static const NativePluginDescriptor carlaRackDesc = {
2366 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2367 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2368 |NATIVE_PLUGIN_HAS_UI
2369 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2370 |NATIVE_PLUGIN_USES_STATE
2371 |NATIVE_PLUGIN_USES_TIME
2372 |NATIVE_PLUGIN_USES_UI_SIZE),
2373 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2374 /* audioIns */ 2,
2375 /* audioOuts */ 2,
2376 /* midiIns */ 1,
2377 /* midiOuts */ 1,
2378 /* paramIns */ kNumInParams,
2379 /* paramOuts */ kNumOutParams,
2380 /* name */ "Carla-Rack",
2381 /* label */ "carlarack",
2382 /* maker */ "falkTX",
2383 /* copyright */ "GNU GPL v2+",
2384 CarlaEngineNative::_instantiateRack,
2385 CarlaEngineNative::_cleanup,
2386 CarlaEngineNative::_get_parameter_count,
2387 CarlaEngineNative::_get_parameter_info,
2388 CarlaEngineNative::_get_parameter_value,
2389 /* _get_midi_program_count */ nullptr,
2390 /* _get_midi_program_info */ nullptr,
2391 CarlaEngineNative::_set_parameter_value,
2392 /* _set_midi_program */ nullptr,
2393 /* _set_custom_data */ nullptr,
2394 #ifndef CARLA_ENGINE_WITHOUT_UI
2395 CarlaEngineNative::_ui_show,
2396 #else
2397 nullptr,
2398 #endif
2399 CarlaEngineNative::_ui_idle,
2400 CarlaEngineNative::_ui_set_parameter_value,
2401 /* _ui_set_midi_program */ nullptr,
2402 /* _ui_set_custom_data */ nullptr,
2403 CarlaEngineNative::_activate,
2404 CarlaEngineNative::_deactivate,
2405 CarlaEngineNative::_process,
2406 CarlaEngineNative::_get_state,
2407 CarlaEngineNative::_set_state,
2408 CarlaEngineNative::_dispatcher,
2409 /* _render_inline_dsplay */ nullptr,
2410 /* cvIns */ 0,
2411 /* cvOuts */ 0,
2412 /* _get_buffer_port_name */ nullptr,
2413 /* _get_buffer_port_range */ nullptr,
2414 /* ui_width */ kUiWidth,
2415 /* ui_height */ kUiHeight
2418 static const NativePluginDescriptor carlaRackNoMidiOutDesc = {
2419 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2420 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2421 |NATIVE_PLUGIN_HAS_UI
2422 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2423 |NATIVE_PLUGIN_USES_STATE
2424 |NATIVE_PLUGIN_USES_TIME
2425 |NATIVE_PLUGIN_USES_UI_SIZE),
2426 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2427 /* audioIns */ 2,
2428 /* audioOuts */ 2,
2429 /* midiIns */ 1,
2430 /* midiOuts */ 0,
2431 /* paramIns */ kNumInParams,
2432 /* paramOuts */ kNumOutParams,
2433 /* name */ "Carla-Rack (no midi out)",
2434 /* label */ "carlarack-nomidiout",
2435 /* maker */ "falkTX",
2436 /* copyright */ "GNU GPL v2+",
2437 CarlaEngineNative::_instantiateRackNoMidiOut,
2438 CarlaEngineNative::_cleanup,
2439 CarlaEngineNative::_get_parameter_count,
2440 CarlaEngineNative::_get_parameter_info,
2441 CarlaEngineNative::_get_parameter_value,
2442 /* _get_midi_program_count */ nullptr,
2443 /* _get_midi_program_info */ nullptr,
2444 CarlaEngineNative::_set_parameter_value,
2445 /* _set_midi_program */ nullptr,
2446 /* _set_custom_data */ nullptr,
2447 #ifndef CARLA_ENGINE_WITHOUT_UI
2448 CarlaEngineNative::_ui_show,
2449 #else
2450 nullptr,
2451 #endif
2452 CarlaEngineNative::_ui_idle,
2453 CarlaEngineNative::_ui_set_parameter_value,
2454 /* _ui_set_midi_program */ nullptr,
2455 /* _ui_set_custom_data */ nullptr,
2456 CarlaEngineNative::_activate,
2457 CarlaEngineNative::_deactivate,
2458 CarlaEngineNative::_process,
2459 CarlaEngineNative::_get_state,
2460 CarlaEngineNative::_set_state,
2461 CarlaEngineNative::_dispatcher,
2462 /* _render_inline_dsplay */ nullptr,
2463 /* cvIns */ 0,
2464 /* cvOuts */ 0,
2465 /* _get_buffer_port_name */ nullptr,
2466 /* _get_buffer_port_range */ nullptr,
2467 /* ui_width */ kUiWidth,
2468 /* ui_height */ kUiHeight
2471 static const NativePluginDescriptor carlaPatchbayDesc = {
2472 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2473 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2474 |NATIVE_PLUGIN_HAS_UI
2475 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2476 |NATIVE_PLUGIN_USES_STATE
2477 |NATIVE_PLUGIN_USES_TIME
2478 |NATIVE_PLUGIN_USES_UI_SIZE),
2479 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2480 /* audioIns */ 2,
2481 /* audioOuts */ 2,
2482 /* midiIns */ 1,
2483 /* midiOuts */ 1,
2484 /* paramIns */ kNumInParams,
2485 /* paramOuts */ kNumOutParams,
2486 /* name */ "Carla-Patchbay",
2487 /* label */ "carlapatchbay",
2488 /* maker */ "falkTX",
2489 /* copyright */ "GNU GPL v2+",
2490 CarlaEngineNative::_instantiatePatchbay,
2491 CarlaEngineNative::_cleanup,
2492 CarlaEngineNative::_get_parameter_count,
2493 CarlaEngineNative::_get_parameter_info,
2494 CarlaEngineNative::_get_parameter_value,
2495 /* _get_midi_program_count */ nullptr,
2496 /* _get_midi_program_info */ nullptr,
2497 CarlaEngineNative::_set_parameter_value,
2498 /* _set_midi_program */ nullptr,
2499 /* _set_custom_data */ nullptr,
2500 #ifndef CARLA_ENGINE_WITHOUT_UI
2501 CarlaEngineNative::_ui_show,
2502 #else
2503 nullptr,
2504 #endif
2505 CarlaEngineNative::_ui_idle,
2506 CarlaEngineNative::_ui_set_parameter_value,
2507 /* _ui_set_midi_program */ nullptr,
2508 /* _ui_set_custom_data */ nullptr,
2509 CarlaEngineNative::_activate,
2510 CarlaEngineNative::_deactivate,
2511 CarlaEngineNative::_process,
2512 CarlaEngineNative::_get_state,
2513 CarlaEngineNative::_set_state,
2514 CarlaEngineNative::_dispatcher,
2515 /* _render_inline_dsplay */ nullptr,
2516 /* cvIns */ 0,
2517 /* cvOuts */ 0,
2518 /* _get_buffer_port_name */ nullptr,
2519 /* _get_buffer_port_range */ nullptr,
2520 /* ui_width */ kUiWidth,
2521 /* ui_height */ kUiHeight
2524 static const NativePluginDescriptor carlaPatchbay3sDesc = {
2525 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2526 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2527 |NATIVE_PLUGIN_HAS_UI
2528 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2529 |NATIVE_PLUGIN_USES_STATE
2530 |NATIVE_PLUGIN_USES_TIME
2531 |NATIVE_PLUGIN_USES_UI_SIZE),
2532 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2533 /* audioIns */ 3,
2534 /* audioOuts */ 2,
2535 /* midiIns */ 1,
2536 /* midiOuts */ 1,
2537 /* paramIns */ kNumInParams,
2538 /* paramOuts */ kNumOutParams,
2539 /* name */ "Carla-Patchbay (sidechain)",
2540 /* label */ "carlapatchbay3s",
2541 /* maker */ "falkTX",
2542 /* copyright */ "GNU GPL v2+",
2543 CarlaEngineNative::_instantiatePatchbay3s,
2544 CarlaEngineNative::_cleanup,
2545 CarlaEngineNative::_get_parameter_count,
2546 CarlaEngineNative::_get_parameter_info,
2547 CarlaEngineNative::_get_parameter_value,
2548 /* _get_midi_program_count */ nullptr,
2549 /* _get_midi_program_info */ nullptr,
2550 CarlaEngineNative::_set_parameter_value,
2551 /* _set_midi_program */ nullptr,
2552 /* _set_custom_data */ nullptr,
2553 #ifndef CARLA_ENGINE_WITHOUT_UI
2554 CarlaEngineNative::_ui_show,
2555 #else
2556 nullptr,
2557 #endif
2558 CarlaEngineNative::_ui_idle,
2559 CarlaEngineNative::_ui_set_parameter_value,
2560 /* _ui_set_midi_program */ nullptr,
2561 /* _ui_set_custom_data */ nullptr,
2562 CarlaEngineNative::_activate,
2563 CarlaEngineNative::_deactivate,
2564 CarlaEngineNative::_process,
2565 CarlaEngineNative::_get_state,
2566 CarlaEngineNative::_set_state,
2567 CarlaEngineNative::_dispatcher,
2568 /* _render_inline_dsplay */ nullptr,
2569 /* cvIns */ 0,
2570 /* cvOuts */ 0,
2571 /* _get_buffer_port_name */ nullptr,
2572 /* _get_buffer_port_range */ nullptr,
2573 /* ui_width */ kUiWidth,
2574 /* ui_height */ kUiHeight
2577 static const NativePluginDescriptor carlaPatchbay16Desc = {
2578 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2579 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2580 |NATIVE_PLUGIN_HAS_UI
2581 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2582 |NATIVE_PLUGIN_USES_STATE
2583 |NATIVE_PLUGIN_USES_TIME
2584 |NATIVE_PLUGIN_USES_UI_SIZE),
2585 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2586 /* audioIns */ 16,
2587 /* audioOuts */ 16,
2588 /* midiIns */ 1,
2589 /* midiOuts */ 1,
2590 /* paramIns */ kNumInParams,
2591 /* paramOuts */ kNumOutParams,
2592 /* name */ "Carla-Patchbay (16chan)",
2593 /* label */ "carlapatchbay16",
2594 /* maker */ "falkTX",
2595 /* copyright */ "GNU GPL v2+",
2596 CarlaEngineNative::_instantiatePatchbay16,
2597 CarlaEngineNative::_cleanup,
2598 CarlaEngineNative::_get_parameter_count,
2599 CarlaEngineNative::_get_parameter_info,
2600 CarlaEngineNative::_get_parameter_value,
2601 /* _get_midi_program_count */ nullptr,
2602 /* _get_midi_program_info */ nullptr,
2603 CarlaEngineNative::_set_parameter_value,
2604 /* _set_midi_program */ nullptr,
2605 /* _set_custom_data */ nullptr,
2606 #ifndef CARLA_ENGINE_WITHOUT_UI
2607 CarlaEngineNative::_ui_show,
2608 #else
2609 nullptr,
2610 #endif
2611 CarlaEngineNative::_ui_idle,
2612 CarlaEngineNative::_ui_set_parameter_value,
2613 /* _ui_set_midi_program */ nullptr,
2614 /* _ui_set_custom_data */ nullptr,
2615 CarlaEngineNative::_activate,
2616 CarlaEngineNative::_deactivate,
2617 CarlaEngineNative::_process,
2618 CarlaEngineNative::_get_state,
2619 CarlaEngineNative::_set_state,
2620 CarlaEngineNative::_dispatcher,
2621 /* _render_inline_dsplay */ nullptr,
2622 /* cvIns */ 0,
2623 /* cvOuts */ 0,
2624 /* _get_buffer_port_name */ nullptr,
2625 /* _get_buffer_port_range */ nullptr,
2626 /* ui_width */ kUiWidth,
2627 /* ui_height */ kUiHeight
2630 static const NativePluginDescriptor carlaPatchbay32Desc = {
2631 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2632 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2633 |NATIVE_PLUGIN_HAS_UI
2634 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2635 |NATIVE_PLUGIN_USES_STATE
2636 |NATIVE_PLUGIN_USES_TIME
2637 |NATIVE_PLUGIN_USES_UI_SIZE),
2638 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2639 /* audioIns */ 32,
2640 /* audioOuts */ 32,
2641 /* midiIns */ 1,
2642 /* midiOuts */ 1,
2643 /* paramIns */ kNumInParams,
2644 /* paramOuts */ kNumOutParams,
2645 /* name */ "Carla-Patchbay (32chan)",
2646 /* label */ "carlapatchbay32",
2647 /* maker */ "falkTX",
2648 /* copyright */ "GNU GPL v2+",
2649 CarlaEngineNative::_instantiatePatchbay32,
2650 CarlaEngineNative::_cleanup,
2651 CarlaEngineNative::_get_parameter_count,
2652 CarlaEngineNative::_get_parameter_info,
2653 CarlaEngineNative::_get_parameter_value,
2654 /* _get_midi_program_count */ nullptr,
2655 /* _get_midi_program_info */ nullptr,
2656 CarlaEngineNative::_set_parameter_value,
2657 /* _set_midi_program */ nullptr,
2658 /* _set_custom_data */ nullptr,
2659 #ifndef CARLA_ENGINE_WITHOUT_UI
2660 CarlaEngineNative::_ui_show,
2661 #else
2662 nullptr,
2663 #endif
2664 CarlaEngineNative::_ui_idle,
2665 CarlaEngineNative::_ui_set_parameter_value,
2666 /* _ui_set_midi_program */ nullptr,
2667 /* _ui_set_custom_data */ nullptr,
2668 CarlaEngineNative::_activate,
2669 CarlaEngineNative::_deactivate,
2670 CarlaEngineNative::_process,
2671 CarlaEngineNative::_get_state,
2672 CarlaEngineNative::_set_state,
2673 CarlaEngineNative::_dispatcher,
2674 /* _render_inline_dsplay */ nullptr,
2675 /* cvIns */ 0,
2676 /* cvOuts */ 0,
2677 /* _get_buffer_port_name */ nullptr,
2678 /* _get_buffer_port_range */ nullptr,
2679 /* ui_width */ kUiWidth,
2680 /* ui_height */ kUiHeight
2683 static const NativePluginDescriptor carlaPatchbay64Desc = {
2684 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2685 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2686 |NATIVE_PLUGIN_HAS_UI
2687 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2688 |NATIVE_PLUGIN_USES_STATE
2689 |NATIVE_PLUGIN_USES_TIME
2690 |NATIVE_PLUGIN_USES_UI_SIZE),
2691 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2692 /* audioIns */ 64,
2693 /* audioOuts */ 64,
2694 /* midiIns */ 1,
2695 /* midiOuts */ 1,
2696 /* paramIns */ kNumInParams,
2697 /* paramOuts */ kNumOutParams,
2698 /* name */ "Carla-Patchbay (64chan)",
2699 /* label */ "carlapatchbay64",
2700 /* maker */ "falkTX",
2701 /* copyright */ "GNU GPL v2+",
2702 CarlaEngineNative::_instantiatePatchbay64,
2703 CarlaEngineNative::_cleanup,
2704 CarlaEngineNative::_get_parameter_count,
2705 CarlaEngineNative::_get_parameter_info,
2706 CarlaEngineNative::_get_parameter_value,
2707 /* _get_midi_program_count */ nullptr,
2708 /* _get_midi_program_info */ nullptr,
2709 CarlaEngineNative::_set_parameter_value,
2710 /* _set_midi_program */ nullptr,
2711 /* _set_custom_data */ nullptr,
2712 #ifndef CARLA_ENGINE_WITHOUT_UI
2713 CarlaEngineNative::_ui_show,
2714 #else
2715 nullptr,
2716 #endif
2717 CarlaEngineNative::_ui_idle,
2718 CarlaEngineNative::_ui_set_parameter_value,
2719 /* _ui_set_midi_program */ nullptr,
2720 /* _ui_set_custom_data */ nullptr,
2721 CarlaEngineNative::_activate,
2722 CarlaEngineNative::_deactivate,
2723 CarlaEngineNative::_process,
2724 CarlaEngineNative::_get_state,
2725 CarlaEngineNative::_set_state,
2726 CarlaEngineNative::_dispatcher,
2727 /* _render_inline_dsplay */ nullptr,
2728 /* cvIns */ 0,
2729 /* cvOuts */ 0,
2730 /* _get_buffer_port_name */ nullptr,
2731 /* _get_buffer_port_range */ nullptr,
2732 /* ui_width */ kUiWidth,
2733 /* ui_height */ kUiHeight
2736 static const NativePluginDescriptor carlaPatchbayCVDesc = {
2737 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2738 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2739 |NATIVE_PLUGIN_HAS_UI
2740 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2741 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2742 |NATIVE_PLUGIN_USES_STATE
2743 |NATIVE_PLUGIN_USES_TIME
2744 |NATIVE_PLUGIN_USES_UI_SIZE),
2745 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2746 /* audioIns */ 2,
2747 /* audioOuts */ 2,
2748 /* midiIns */ 1,
2749 /* midiOuts */ 1,
2750 /* paramIns */ kNumInParams,
2751 /* paramOuts */ kNumOutParams,
2752 /* name */ "Carla-Patchbay (CV)",
2753 /* label */ "carlapatchbaycv",
2754 /* maker */ "falkTX",
2755 /* copyright */ "GNU GPL v2+",
2756 CarlaEngineNative::_instantiatePatchbayCV,
2757 CarlaEngineNative::_cleanup,
2758 CarlaEngineNative::_get_parameter_count,
2759 CarlaEngineNative::_get_parameter_info,
2760 CarlaEngineNative::_get_parameter_value,
2761 /* _get_midi_program_count */ nullptr,
2762 /* _get_midi_program_info */ nullptr,
2763 CarlaEngineNative::_set_parameter_value,
2764 /* _set_midi_program */ nullptr,
2765 /* _set_custom_data */ nullptr,
2766 #ifndef CARLA_ENGINE_WITHOUT_UI
2767 CarlaEngineNative::_ui_show,
2768 #else
2769 nullptr,
2770 #endif
2771 CarlaEngineNative::_ui_idle,
2772 CarlaEngineNative::_ui_set_parameter_value,
2773 /* _ui_set_midi_program */ nullptr,
2774 /* _ui_set_custom_data */ nullptr,
2775 CarlaEngineNative::_activate,
2776 CarlaEngineNative::_deactivate,
2777 CarlaEngineNative::_process,
2778 CarlaEngineNative::_get_state,
2779 CarlaEngineNative::_set_state,
2780 CarlaEngineNative::_dispatcher,
2781 /* _render_inline_dsplay */ nullptr,
2782 /* cvIns */ 5,
2783 /* cvOuts */ 5,
2784 /* _get_buffer_port_name */ nullptr,
2785 /* _get_buffer_port_range */ nullptr,
2786 /* ui_width */ kUiWidth,
2787 /* ui_height */ kUiHeight
2790 static const NativePluginDescriptor carlaPatchbayCV8Desc = {
2791 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2792 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2793 |NATIVE_PLUGIN_HAS_UI
2794 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2795 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2796 |NATIVE_PLUGIN_USES_STATE
2797 |NATIVE_PLUGIN_USES_TIME
2798 |NATIVE_PLUGIN_USES_UI_SIZE),
2799 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2800 /* audioIns */ 2,
2801 /* audioOuts */ 2,
2802 /* midiIns */ 1,
2803 /* midiOuts */ 1,
2804 /* paramIns */ kNumInParams,
2805 /* paramOuts */ kNumOutParams,
2806 /* name */ "Carla-Patchbay (CV8)",
2807 /* label */ "carlapatchbaycv",
2808 /* maker */ "falkTX",
2809 /* copyright */ "GNU GPL v2+",
2810 CarlaEngineNative::_instantiatePatchbayCV8,
2811 CarlaEngineNative::_cleanup,
2812 CarlaEngineNative::_get_parameter_count,
2813 CarlaEngineNative::_get_parameter_info,
2814 CarlaEngineNative::_get_parameter_value,
2815 /* _get_midi_program_count */ nullptr,
2816 /* _get_midi_program_info */ nullptr,
2817 CarlaEngineNative::_set_parameter_value,
2818 /* _set_midi_program */ nullptr,
2819 /* _set_custom_data */ nullptr,
2820 #ifndef CARLA_ENGINE_WITHOUT_UI
2821 CarlaEngineNative::_ui_show,
2822 #else
2823 nullptr,
2824 #endif
2825 CarlaEngineNative::_ui_idle,
2826 CarlaEngineNative::_ui_set_parameter_value,
2827 /* _ui_set_midi_program */ nullptr,
2828 /* _ui_set_custom_data */ nullptr,
2829 CarlaEngineNative::_activate,
2830 CarlaEngineNative::_deactivate,
2831 CarlaEngineNative::_process,
2832 CarlaEngineNative::_get_state,
2833 CarlaEngineNative::_set_state,
2834 CarlaEngineNative::_dispatcher,
2835 /* _render_inline_dsplay */ nullptr,
2836 /* cvIns */ 8,
2837 /* cvOuts */ 8,
2838 /* _get_buffer_port_name */ nullptr,
2839 /* _get_buffer_port_range */ nullptr,
2840 /* ui_width */ kUiWidth,
2841 /* ui_height */ kUiHeight
2844 static const NativePluginDescriptor carlaPatchbayCV32Desc = {
2845 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2846 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2847 |NATIVE_PLUGIN_HAS_UI
2848 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2849 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2850 |NATIVE_PLUGIN_USES_STATE
2851 |NATIVE_PLUGIN_USES_TIME
2852 |NATIVE_PLUGIN_USES_UI_SIZE),
2853 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2854 /* audioIns */ 64,
2855 /* audioOuts */ 64,
2856 /* midiIns */ 1,
2857 /* midiOuts */ 1,
2858 /* paramIns */ kNumInParams,
2859 /* paramOuts */ kNumOutParams,
2860 /* name */ "Carla-Patchbay (CV32)",
2861 /* label */ "carlapatchbaycv",
2862 /* maker */ "falkTX",
2863 /* copyright */ "GNU GPL v2+",
2864 CarlaEngineNative::_instantiatePatchbayCV32,
2865 CarlaEngineNative::_cleanup,
2866 CarlaEngineNative::_get_parameter_count,
2867 CarlaEngineNative::_get_parameter_info,
2868 CarlaEngineNative::_get_parameter_value,
2869 /* _get_midi_program_count */ nullptr,
2870 /* _get_midi_program_info */ nullptr,
2871 CarlaEngineNative::_set_parameter_value,
2872 /* _set_midi_program */ nullptr,
2873 /* _set_custom_data */ nullptr,
2874 #ifndef CARLA_ENGINE_WITHOUT_UI
2875 CarlaEngineNative::_ui_show,
2876 #else
2877 nullptr,
2878 #endif
2879 CarlaEngineNative::_ui_idle,
2880 CarlaEngineNative::_ui_set_parameter_value,
2881 /* _ui_set_midi_program */ nullptr,
2882 /* _ui_set_custom_data */ nullptr,
2883 CarlaEngineNative::_activate,
2884 CarlaEngineNative::_deactivate,
2885 CarlaEngineNative::_process,
2886 CarlaEngineNative::_get_state,
2887 CarlaEngineNative::_set_state,
2888 CarlaEngineNative::_dispatcher,
2889 /* _render_inline_dsplay */ nullptr,
2890 /* cvIns */ 32,
2891 /* cvOuts */ 32,
2892 /* _get_buffer_port_name */ nullptr,
2893 /* _get_buffer_port_range */ nullptr,
2894 /* ui_width */ kUiWidth,
2895 /* ui_height */ kUiHeight
2898 static const NativePluginDescriptor carlaPatchbayOBS = {
2899 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2900 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2901 |NATIVE_PLUGIN_HAS_UI
2902 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2903 |NATIVE_PLUGIN_USES_STATE
2904 |NATIVE_PLUGIN_USES_TIME
2905 |NATIVE_PLUGIN_USES_UI_SIZE),
2906 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2907 /* audioIns */ 8,
2908 /* audioOuts */ 8,
2909 /* midiIns */ 0,
2910 /* midiOuts */ 0,
2911 /* paramIns */ kNumInParams,
2912 /* paramOuts */ kNumOutParams,
2913 /* name */ "Carla-Patchbay (OBS)",
2914 /* label */ "carlapatchbayOBS",
2915 /* maker */ "falkTX",
2916 /* copyright */ "GNU GPL v2+",
2917 CarlaEngineNative::_instantiatePatchbayOBS,
2918 CarlaEngineNative::_cleanup,
2919 CarlaEngineNative::_get_parameter_count,
2920 CarlaEngineNative::_get_parameter_info,
2921 CarlaEngineNative::_get_parameter_value,
2922 /* _get_midi_program_count */ nullptr,
2923 /* _get_midi_program_info */ nullptr,
2924 CarlaEngineNative::_set_parameter_value,
2925 /* _set_midi_program */ nullptr,
2926 /* _set_custom_data */ nullptr,
2927 #ifndef CARLA_ENGINE_WITHOUT_UI
2928 CarlaEngineNative::_ui_show,
2929 #else
2930 nullptr,
2931 #endif
2932 CarlaEngineNative::_ui_idle,
2933 CarlaEngineNative::_ui_set_parameter_value,
2934 /* _ui_set_midi_program */ nullptr,
2935 /* _ui_set_custom_data */ nullptr,
2936 CarlaEngineNative::_activate,
2937 CarlaEngineNative::_deactivate,
2938 CarlaEngineNative::_process,
2939 CarlaEngineNative::_get_state,
2940 CarlaEngineNative::_set_state,
2941 CarlaEngineNative::_dispatcher,
2942 /* _render_inline_dsplay */ nullptr,
2943 /* cvIns */ 0,
2944 /* cvOuts */ 0,
2945 /* _get_buffer_port_name */ nullptr,
2946 /* _get_buffer_port_range */ nullptr,
2947 /* ui_width */ kUiWidth,
2948 /* ui_height */ kUiHeight
2951 CARLA_BACKEND_END_NAMESPACE
2953 // -----------------------------------------------------------------------
2955 #ifndef STATIC_PLUGIN_TARGET
2957 CARLA_API_EXPORT
2958 void carla_register_native_plugin_carla();
2960 void carla_register_native_plugin_carla()
2962 CARLA_BACKEND_USE_NAMESPACE;
2963 carla_register_native_plugin(&carlaRackDesc);
2964 carla_register_native_plugin(&carlaRackNoMidiOutDesc);
2965 carla_register_native_plugin(&carlaPatchbayDesc);
2966 carla_register_native_plugin(&carlaPatchbay3sDesc);
2967 carla_register_native_plugin(&carlaPatchbay16Desc);
2968 carla_register_native_plugin(&carlaPatchbay32Desc);
2969 carla_register_native_plugin(&carlaPatchbay64Desc);
2970 carla_register_native_plugin(&carlaPatchbayCVDesc);
2973 #endif
2975 // -----------------------------------------------------------------------
2977 const NativePluginDescriptor* carla_get_native_rack_plugin()
2979 CARLA_BACKEND_USE_NAMESPACE;
2980 return &carlaRackDesc;
2983 const NativePluginDescriptor* carla_get_native_patchbay_plugin()
2985 CARLA_BACKEND_USE_NAMESPACE;
2986 return &carlaPatchbayDesc;
2989 const NativePluginDescriptor* carla_get_native_patchbay16_plugin()
2991 CARLA_BACKEND_USE_NAMESPACE;
2992 return &carlaPatchbay16Desc;
2995 const NativePluginDescriptor* carla_get_native_patchbay32_plugin()
2997 CARLA_BACKEND_USE_NAMESPACE;
2998 return &carlaPatchbay32Desc;
3001 const NativePluginDescriptor* carla_get_native_patchbay64_plugin()
3003 CARLA_BACKEND_USE_NAMESPACE;
3004 return &carlaPatchbay64Desc;
3007 const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin()
3009 CARLA_BACKEND_USE_NAMESPACE;
3010 return &carlaPatchbayCVDesc;
3013 const NativePluginDescriptor* carla_get_native_patchbay_cv8_plugin()
3015 CARLA_BACKEND_USE_NAMESPACE;
3016 return &carlaPatchbayCV8Desc;
3019 const NativePluginDescriptor* carla_get_native_patchbay_cv32_plugin()
3021 CARLA_BACKEND_USE_NAMESPACE;
3022 return &carlaPatchbayCV32Desc;
3025 const NativePluginDescriptor* carla_get_native_patchbay_obs_plugin()
3027 CARLA_BACKEND_USE_NAMESPACE;
3028 return &carlaPatchbayOBS;
3031 // -----------------------------------------------------------------------
3032 // Extra stuff for linking purposes
3034 #ifdef CARLA_PLUGIN_BUILD
3036 CARLA_BACKEND_START_NAMESPACE
3038 namespace EngineInit {
3040 #ifdef HAVE_JACK
3041 CarlaEngine* newJack() { return nullptr; }
3042 #endif
3044 #ifdef USING_RTAUDIO
3045 CarlaEngine* newRtAudio(const AudioApi) { return nullptr; }
3046 uint getRtAudioApiCount() { return 0; }
3047 const char* getRtAudioApiName(const uint) { return nullptr; }
3048 const char* const* getRtAudioApiDeviceNames(const uint) { return nullptr; }
3049 const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const uint, const char* const) { return nullptr; }
3050 #endif
3052 #ifdef HAVE_SDL
3053 CarlaEngine* newSDL() { return nullptr; }
3054 const char* const* getSDLDeviceNames() { return nullptr; }
3055 #endif
3059 CARLA_BACKEND_END_NAMESPACE
3061 #define CARLA_PLUGIN_UI_CLASS_PREFIX Plugin
3062 #include "CarlaPluginUI.cpp"
3063 # undef CARLA_PLUGIN_UI_CLASS_PREFIX
3064 #include "CarlaDssiUtils.cpp"
3065 #include "CarlaMacUtils.cpp"
3066 #include "CarlaPatchbayUtils.cpp"
3067 #include "CarlaPipeUtils.cpp"
3068 #include "CarlaProcessUtils.cpp"
3069 #include "CarlaStateUtils.cpp"
3071 #endif /* CARLA_PLUGIN_BUILD */
3073 // -----------------------------------------------------------------------