Rename a pipe method, add docs
[carla.git] / source / backend / engine / CarlaEngineNative.cpp
blob2547bb6ee8b013e9c4c2a8776647f5e4367f84eb
1 /*
2 * Carla Plugin Host
3 * Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "CarlaDefines.h"
20 #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
21 # error This file should not be compiled if building alternative-arch bridges
22 #endif
24 #ifdef CARLA_OS_WASM
25 # define CARLA_ENGINE_WITHOUT_UI
26 #endif
28 #include "CarlaEngineInit.hpp"
29 #include "CarlaEngineInternal.hpp"
30 #include "CarlaPlugin.hpp"
32 #include "CarlaBackendUtils.hpp"
33 #include "CarlaBase64Utils.hpp"
34 #include "CarlaBinaryUtils.hpp"
35 #include "CarlaMathUtils.hpp"
36 #include "CarlaStateUtils.hpp"
38 #include "CarlaExternalUI.hpp"
39 #include "CarlaHost.h"
40 #include "CarlaNative.hpp"
41 #include "CarlaNativePlugin.h"
43 #include "water/files/File.h"
44 #include "water/streams/MemoryOutputStream.h"
45 #include "water/xml/XmlDocument.h"
46 #include "water/xml/XmlElement.h"
48 #ifdef CARLA_OS_WIN
49 # include <direct.h>
50 #endif
52 #ifdef USING_JUCE
53 # include "carla_juce/carla_juce.h"
54 #endif
56 using water::File;
57 using water::MemoryOutputStream;
58 using water::String;
59 using water::XmlDocument;
60 using water::XmlElement;
62 CARLA_BACKEND_START_NAMESPACE
64 static const uint32_t kNumInParams = 100;
65 static const uint32_t kNumOutParams = 10;
67 static const uint16_t kUiWidth = 1024;
68 static const uint16_t kUiHeight = 712;
70 // -----------------------------------------------------------------------
72 #ifndef CARLA_ENGINE_WITHOUT_UI
73 class CarlaEngineNative;
75 class CarlaEngineNativeUI : public CarlaExternalUI
77 public:
78 CarlaEngineNativeUI(CarlaEngineNative* const engine)
79 : fEngine(engine)
81 carla_debug("CarlaEngineNativeUI::CarlaEngineNativeUI(%p)", engine);
84 ~CarlaEngineNativeUI() noexcept override
86 carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()");
89 protected:
90 bool msgReceived(const char* const msg) noexcept override;
92 private:
93 CarlaEngineNative* const fEngine;
95 void _updateParamValues(const CarlaPluginPtr& plugin,
96 uint32_t pluginId,
97 bool sendCallback, bool sendPluginHost) const noexcept;
99 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeUI)
101 #endif
103 // -----------------------------------------------------------------------
105 class CarlaEngineNative : public CarlaEngine
107 public:
108 CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay,
109 const bool withMidiIn, const bool withMidiOut,
110 const uint32_t inChan = 2, uint32_t outChan = 2,
111 const uint32_t cvIns = 0, const uint32_t cvOuts = 0)
112 : CarlaEngine(),
113 pHost(host),
114 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
115 // if not running inside Carla, we will have to run event loop ourselves
116 kNeedsJuceEvents(host->dispatcher(pHost->handle,
117 NATIVE_HOST_OPCODE_INTERNAL_PLUGIN, 0, 0, nullptr, 0.0f) == 0),
118 fJuceMsgMgr(),
119 fJuceMsgMutex(),
120 #endif
121 kIsPatchbay(isPatchbay),
122 kHasMidiIn(withMidiIn),
123 kHasMidiOut(withMidiOut),
124 fIsActive(false),
125 fIsRunning(false),
126 fUsesEmbed(false),
127 #ifndef CARLA_ENGINE_WITHOUT_UI
128 fUiServer(this),
129 #endif
130 fLastScaleFactor(1.0f),
131 fLastProjectFolder(),
132 fPluginDeleterMutex(),
133 fOptionsForced(false)
135 carla_debug("CarlaEngineNative::CarlaEngineNative()");
137 carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
139 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
140 if (kNeedsJuceEvents)
141 fJuceMsgMgr.incRef();
142 #endif
144 pData->bufferSize = pHost->get_buffer_size(pHost->handle);
145 pData->sampleRate = pHost->get_sample_rate(pHost->handle);
146 pData->initTime(nullptr);
148 #ifndef BUILD_BRIDGE
149 // Forced OSC setup when running as plugin
150 pData->options.oscEnabled = true;
151 pData->options.oscPortTCP = -1;
152 pData->options.oscPortUDP = 0;
153 #endif
155 if (outChan == 0)
156 outChan = inChan;
158 // set-up engine
159 if (kIsPatchbay)
161 pData->options.processMode = ENGINE_PROCESS_MODE_PATCHBAY;
162 pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
163 pData->options.forceStereo = false;
164 pData->options.preferPluginBridges = false;
165 pData->options.preferUiBridges = false;
166 init("Carla-Patchbay");
167 pData->graph.create(inChan, outChan, cvIns, cvOuts, withMidiIn, withMidiOut);
169 else
171 CARLA_SAFE_ASSERT(inChan == 2);
172 CARLA_SAFE_ASSERT(outChan == 2);
173 pData->options.processMode = ENGINE_PROCESS_MODE_CONTINUOUS_RACK;
174 pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
175 pData->options.forceStereo = true;
176 pData->options.preferPluginBridges = false;
177 pData->options.preferUiBridges = false;
178 init("Carla-Rack");
179 pData->graph.create(0, 0, 0, 0); // FIXME?
182 if (pData->options.resourceDir != nullptr)
183 delete[] pData->options.resourceDir;
184 if (pData->options.binaryDir != nullptr)
185 delete[] pData->options.binaryDir;
187 const water::String binaryDir(File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName());
189 pData->options.resourceDir = carla_strdup(pHost->resourceDir);
190 pData->options.binaryDir = carla_strdup(binaryDir.toRawUTF8());
193 ~CarlaEngineNative() override
195 CARLA_SAFE_ASSERT(! fIsActive);
196 carla_debug("CarlaEngineNative::~CarlaEngineNative() - START");
198 pData->aboutToClose = true;
199 fIsRunning = false;
202 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
203 const ScopedJuceMessageThreadRunner sjmtr(*this, true);
204 #endif
205 removeAllPlugins();
206 //runPendingRtEvents();
207 close();
209 pData->graph.destroy();
212 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
213 if (kNeedsJuceEvents)
214 fJuceMsgMgr.decRef();
215 #endif
217 carla_debug("CarlaEngineNative::~CarlaEngineNative() - END");
220 // -------------------------------------
221 // CarlaEngine virtual calls
223 bool init(const char* const clientName) override
225 carla_debug("CarlaEngineNative::init(\"%s\")", clientName);
227 fIsRunning = true;
229 if (! pData->init(clientName))
231 close();
232 setLastError("Failed to init internal data");
233 return false;
236 pData->bufferSize = pHost->get_buffer_size(pHost->handle);
237 pData->sampleRate = pHost->get_sample_rate(pHost->handle);
239 return true;
242 bool close() override
244 fIsRunning = false;
245 CarlaEngine::close();
246 return true;
249 bool hasIdleOnMainThread() const noexcept override
251 return false;
254 bool isRunning() const noexcept override
256 return fIsRunning;
259 bool isOffline() const noexcept override
261 return pHost->is_offline(pHost->handle);
264 bool usesConstantBufferSize() const noexcept override
266 // TODO LV2 hosts can report this, till then we allow this
267 return true;
270 EngineType getType() const noexcept override
272 return kEngineTypePlugin;
275 const char* getCurrentDriverName() const noexcept override
277 return "Plugin";
280 const char* getCurrentProjectFolder() const noexcept override
282 CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);
284 static char filetype[] = "carla\0";
286 try {
287 return (const char*)(uintptr_t)pHost->dispatcher(pHost->handle,
288 NATIVE_HOST_OPCODE_GET_FILE_PATH,
289 0, 0,
290 (void*)filetype,
291 0.0f);
292 } CARLA_SAFE_EXCEPTION_RETURN("get_file_path", nullptr);
295 void callback(const bool sendHost, const bool sendOsc,
296 const EngineCallbackOpcode action, const uint pluginId,
297 const int value1, const int value2, const int value3,
298 const float valuef, const char* const valueStr) noexcept override
300 CarlaEngine::callback(sendHost, sendOsc, action, pluginId, value1, value2, value3, valuef, valueStr);
302 #ifndef CARLA_ENGINE_WITHOUT_UI
303 if (sendHost)
304 uiServerCallback(action, pluginId, value1, value2, value3, valuef, valueStr);
305 #endif
307 switch (action)
309 case ENGINE_CALLBACK_IDLE:
310 if (! pData->aboutToClose)
311 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_HOST_IDLE, 0, 0, nullptr, 0.0f);
312 break;
314 case ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
315 if (sendHost && value1 >= 0)
317 uint32_t rindex = static_cast<uint32_t>(value1);
318 if (_getRealIndexForPluginParameter(pluginId, rindex))
320 fParameters[rindex] = valuef;
322 if (fUsesEmbed
323 #ifndef CARLA_ENGINE_WITHOUT_UI
324 || fUiServer.isPipeRunning()
325 #endif
328 pHost->ui_parameter_changed(pHost->handle, rindex, valuef);
330 else
332 static uint last_pluginId = pluginId;
333 static int last_value1 = value1;
334 static bool init = true;
336 if (init || last_pluginId != pluginId || last_value1 != value1)
338 init = false;
339 last_pluginId = pluginId;
340 last_value1 = value1;
341 carla_stdout("Plugin with id %d triggered parameter %d update while UI is hidden",
342 pluginId, value1);
347 break;
349 case ENGINE_CALLBACK_UI_STATE_CHANGED:
350 if (sendHost && fUsesEmbed)
351 pHost->ui_closed(pHost->handle);
352 break;
354 default:
355 break;
359 const char* runFileCallback(FileCallbackOpcode action,
360 bool isDir, const char* title, const char* filter) noexcept override
362 switch (action)
364 case FILE_CALLBACK_DEBUG:
365 return nullptr;
367 case FILE_CALLBACK_OPEN:
368 return pHost->ui_open_file(pHost->handle, isDir, title, filter);
370 case FILE_CALLBACK_SAVE:
371 return pHost->ui_save_file(pHost->handle, isDir, title, filter);
374 return nullptr;
377 // -------------------------------------------------------------------
379 void touchPluginParameter(const uint id, const uint32_t parameterId, const bool touch) noexcept override
381 setParameterTouchFromUI(id, parameterId, touch);
384 // -------------------------------------------------------------------
386 void setParameterValueFromUI(const uint32_t pluginId, const uint32_t index, const float value)
388 uint32_t rindex = index;
389 if (_getRealIndexForPluginParameter(pluginId, rindex))
391 fParameters[rindex] = value;
392 pHost->ui_parameter_changed(pHost->handle, rindex, value);
396 void setParameterTouchFromUI(const uint32_t pluginId, const uint32_t index, const bool touch)
398 uint32_t rindex = index;
399 if (_getRealIndexForPluginParameter(pluginId, rindex))
401 pHost->dispatcher(pHost->handle,
402 NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER,
403 static_cast<int32_t>(rindex),
404 touch ? 1 : 0,
405 nullptr, 0.0f);
409 void reloadFromUI()
411 carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
412 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_RELOAD_PARAMETERS, 0, 0, nullptr, 0.0f);
415 protected:
416 // -------------------------------------------------------------------
418 void bufferSizeChanged(const uint32_t newBufferSize)
420 if (pData->bufferSize == newBufferSize)
421 return;
423 #ifndef CARLA_ENGINE_WITHOUT_UI
425 const CarlaMutexLocker cml(fUiServer.getPipeLock());
427 if (fUiServer.writeMessage("buffer-size\n"))
429 char tmpBuf[STR_MAX+1];
430 carla_zeroChars(tmpBuf, STR_MAX+1);
432 std::snprintf(tmpBuf, STR_MAX, "%i\n", newBufferSize);
434 if (fUiServer.writeMessage(tmpBuf))
435 fUiServer.syncMessages();
438 #endif
440 pData->bufferSize = newBufferSize;
441 CarlaEngine::bufferSizeChanged(newBufferSize);
444 void sampleRateChanged(const double newSampleRate)
446 if (carla_isEqual(pData->sampleRate, newSampleRate))
447 return;
449 #ifndef CARLA_ENGINE_WITHOUT_UI
451 const CarlaMutexLocker cml(fUiServer.getPipeLock());
453 if (fUiServer.writeMessage("sample-rate\n"))
455 char tmpBuf[STR_MAX+1];
456 carla_zeroChars(tmpBuf, STR_MAX+1);
459 const CarlaScopedLocale csl;
460 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", newSampleRate);
463 if (fUiServer.writeMessage(tmpBuf))
464 fUiServer.syncMessages();
467 #endif
469 pData->sampleRate = newSampleRate;
470 CarlaEngine::sampleRateChanged(newSampleRate);
473 #ifndef CARLA_ENGINE_WITHOUT_UI
474 // -------------------------------------------------------------------
476 void uiServerSendPluginInfo(const CarlaPluginPtr& plugin)
478 char tmpBuf[STR_MAX+1];
479 carla_zeroChars(tmpBuf, STR_MAX+1);
481 const CarlaMutexLocker cml(fUiServer.getPipeLock());
483 const uint pluginId(plugin->getId());
485 std::snprintf(tmpBuf, STR_MAX, "PLUGIN_INFO_%i\n", pluginId);
486 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
488 std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:" P_INT64 ":%i:%i\n",
489 plugin->getType(), plugin->getCategory(),
490 plugin->getHints(), plugin->getUniqueId(),
491 plugin->getOptionsAvailable(), plugin->getOptionsEnabled());
492 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
494 if (const char* const filename = plugin->getFilename())
496 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(filename),);
498 else
500 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
503 if (const char* const name = plugin->getName())
505 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(name),);
507 else
509 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
512 if (const char* const iconName = plugin->getIconName())
514 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(iconName),);
516 else
518 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
521 if (plugin->getRealName(tmpBuf)) {
522 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
523 } else {
524 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
527 if (plugin->getLabel(tmpBuf)) {
528 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
529 } else {
530 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
533 if (plugin->getMaker(tmpBuf)) {
534 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
535 } else {
536 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
539 if (plugin->getCopyright(tmpBuf)) {
540 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
541 } else {
542 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
545 std::snprintf(tmpBuf, STR_MAX, "AUDIO_COUNT_%i:%i:%i\n",
546 pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount());
547 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
549 std::snprintf(tmpBuf, STR_MAX, "MIDI_COUNT_%i:%i:%i\n",
550 pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount());
551 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
553 fUiServer.syncMessages();
556 void uiServerSendPluginParameters(const CarlaPluginPtr& plugin)
558 char tmpBuf[STR_MAX+1];
559 carla_zeroChars(tmpBuf, STR_MAX+1);
561 const CarlaMutexLocker cml(fUiServer.getPipeLock());
562 const CarlaScopedLocale csl;
564 const uint pluginId(plugin->getId());
566 for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i)
568 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%i\n", pluginId, i);
569 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
571 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getInternalParameterValue(i)));
572 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
574 fUiServer.syncMessages();
577 uint32_t ins, outs, count;
578 plugin->getParameterCountInfo(ins, outs);
579 count = plugin->getParameterCount();
581 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count);
582 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
584 for (uint32_t i=0; i<count; ++i)
586 const ParameterData& paramData(plugin->getParameterData(i));
587 const ParameterRanges& paramRanges(plugin->getParameterRanges(i));
589 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_DATA_%i:%i\n", pluginId, i);
590 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
592 std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:%i\n", paramData.type, paramData.hints,
593 paramData.mappedControlIndex, paramData.midiChannel);
594 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
596 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g\n", static_cast<double>(paramData.mappedMinimum),
597 static_cast<double>(paramData.mappedMaximum));
598 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
600 if (plugin->getParameterName(i, tmpBuf)) {
601 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
602 } else {
603 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
606 if (plugin->getParameterUnit(i, tmpBuf)) {
607 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
608 } else {
609 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
612 if (plugin->getParameterComment(i, tmpBuf)) {
613 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
614 } else {
615 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
618 if (plugin->getParameterGroupName(i, tmpBuf)) {
619 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
620 } else {
621 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
624 std::snprintf(tmpBuf, STR_MAX, "PARAMETER_RANGES_%i:%i\n", pluginId, i);
625 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
627 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g:%.12g:%.12g\n",
628 static_cast<double>(paramRanges.def),
629 static_cast<double>(paramRanges.min),
630 static_cast<double>(paramRanges.max),
631 static_cast<double>(paramRanges.step),
632 static_cast<double>(paramRanges.stepSmall),
633 static_cast<double>(paramRanges.stepLarge));
634 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
636 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", pluginId, i);
637 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
639 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(i)));
640 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
643 fUiServer.syncMessages();
646 void uiServerSendPluginPrograms(const CarlaPluginPtr& plugin)
648 char tmpBuf[STR_MAX+1];
649 carla_zeroChars(tmpBuf, STR_MAX+1);
651 const CarlaMutexLocker cml(fUiServer.getPipeLock());
653 const uint pluginId(plugin->getId());
655 uint32_t count = plugin->getProgramCount();
656 std::snprintf(tmpBuf, STR_MAX, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram());
657 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
659 for (uint32_t i=0; i<count; ++i)
661 std::snprintf(tmpBuf, STR_MAX, "PROGRAM_NAME_%i:%i\n", pluginId, i);
662 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
664 if (plugin->getProgramName(i, tmpBuf)) {
665 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
666 } else {
667 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
671 fUiServer.syncMessages();
673 count = plugin->getMidiProgramCount();
674 std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_COUNT_%i:%i:%i\n",
675 pluginId, count, plugin->getCurrentMidiProgram());
676 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
678 for (uint32_t i=0; i<count; ++i)
680 std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i);
681 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
683 const MidiProgramData& mpData(plugin->getMidiProgramData(i));
685 std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program);
686 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
688 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(mpData.name),);
691 fUiServer.syncMessages();
694 void uiServerSendPluginProperties(const CarlaPluginPtr& plugin)
696 char tmpBuf[STR_MAX+1];
697 carla_zeroChars(tmpBuf, STR_MAX+1);
699 const CarlaMutexLocker cml(fUiServer.getPipeLock());
701 const uint pluginId(plugin->getId());
703 uint32_t count = plugin->getCustomDataCount();
704 std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_COUNT_%i:%i\n", pluginId, count);
705 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
707 for (uint32_t i=0; i<count; ++i)
709 const CustomData& customData(plugin->getCustomData(i));
710 CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
712 if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_PROPERTY) != 0)
713 continue;
715 std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_%i:%i\n", pluginId, i);
716 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
717 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.type),);
718 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.key),);
719 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.value),);
722 fUiServer.syncMessages();
725 void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId,
726 const int value1, const int value2, const int value3,
727 const float valuef, const char* const valueStr)
729 if (! fIsRunning)
730 return;
731 if (! fUiServer.isPipeRunning())
732 return;
734 switch (action)
736 case ENGINE_CALLBACK_UPDATE:
737 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
739 if (plugin->isEnabled())
741 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
742 uiServerSendPluginProperties(plugin);
745 break;
747 case ENGINE_CALLBACK_RELOAD_INFO:
748 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
750 if (plugin->isEnabled())
752 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
753 uiServerSendPluginInfo(plugin);
756 break;
758 case ENGINE_CALLBACK_RELOAD_PARAMETERS:
759 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
761 if (plugin->isEnabled())
763 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
764 uiServerSendPluginParameters(plugin);
767 break;
769 case ENGINE_CALLBACK_RELOAD_PROGRAMS:
770 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
772 if (plugin->isEnabled())
774 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
775 uiServerSendPluginPrograms(plugin);
778 break;
780 case ENGINE_CALLBACK_RELOAD_ALL:
781 case ENGINE_CALLBACK_PLUGIN_ADDED:
782 case ENGINE_CALLBACK_PLUGIN_RENAMED:
783 if (const CarlaPluginPtr plugin = getPlugin(pluginId))
785 if (plugin->isEnabled())
787 CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
788 uiServerSendPluginInfo(plugin);
789 uiServerSendPluginParameters(plugin);
790 uiServerSendPluginPrograms(plugin);
791 uiServerSendPluginProperties(plugin);
794 break;
796 default:
797 break;
800 char tmpBuf[STR_MAX+1];
801 carla_zeroChars(tmpBuf, STR_MAX+1);
803 const CarlaMutexLocker cml(fUiServer.getPipeLock());
805 std::snprintf(tmpBuf, STR_MAX, "ENGINE_CALLBACK_%i\n", int(action));
806 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
808 std::snprintf(tmpBuf, STR_MAX, "%u\n", pluginId);
809 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
811 std::snprintf(tmpBuf, STR_MAX, "%i\n", value1);
812 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
814 std::snprintf(tmpBuf, STR_MAX, "%i\n", value2);
815 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
817 std::snprintf(tmpBuf, STR_MAX, "%i\n", value3);
818 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
821 const CarlaScopedLocale csl;
822 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(valuef));
824 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
826 if (valueStr != nullptr) {
827 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(valueStr),);
828 } else {
829 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
832 fUiServer.syncMessages();
835 void uiServerInfo()
837 CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
838 CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
840 char tmpBuf[STR_MAX+1];
841 carla_zeroChars(tmpBuf, STR_MAX+1);
843 const CarlaMutexLocker cml(fUiServer.getPipeLock());
845 #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
846 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("osc-urls\n"),);
847 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathTCP()),);
848 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathUDP()),);
849 #endif
851 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("max-plugin-number\n"),);
852 std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->maxPluginNumber);
853 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
855 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("buffer-size\n"),);
856 std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->bufferSize);
857 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
859 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("sample-rate\n"),);
861 const CarlaScopedLocale csl;
862 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", pData->sampleRate);
864 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
866 fUiServer.syncMessages();
869 void uiServerOptions()
871 CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
872 CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
874 char tmpBuf[STR_MAX+1];
875 carla_zeroChars(tmpBuf, STR_MAX+1);
877 const EngineOptions& options(pData->options);
878 const CarlaMutexLocker cml(fUiServer.getPipeLock());
880 const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n");
881 const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6);
883 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE);
884 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
885 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
886 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.processMode);
887 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
888 fUiServer.syncMessages();
890 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE);
891 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
892 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
893 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.transportMode);
894 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
895 fUiServer.syncMessages();
897 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO);
898 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
899 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
900 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.forceStereo ? "true\n" : "false\n"),);
901 fUiServer.syncMessages();
903 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES);
904 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
905 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
906 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferPluginBridges ? "true\n" : "false\n"),);
907 fUiServer.syncMessages();
909 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES);
910 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
911 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
912 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferUiBridges ? "true\n" : "false\n"),);
913 fUiServer.syncMessages();
915 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP);
916 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
917 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
918 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.uisAlwaysOnTop ? "true\n" : "false\n"),);
919 fUiServer.syncMessages();
921 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS);
922 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
923 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
924 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.maxParameters);
925 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
926 fUiServer.syncMessages();
928 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT);
929 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
930 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
931 std::snprintf(tmpBuf, STR_MAX, "%i\n", options.uiBridgesTimeout);
932 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
933 fUiServer.syncMessages();
935 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES);
936 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
937 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
938 std::snprintf(tmpBuf, STR_MAX, "%s\n", options.binaryDir);
939 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
940 fUiServer.syncMessages();
942 std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES);
943 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
944 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
945 std::snprintf(tmpBuf, STR_MAX, "%s\n", options.resourceDir);
946 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
947 fUiServer.syncMessages();
949 #endif
951 // -------------------------------------------------------------------
952 // Plugin parameter calls
954 uint32_t getParameterCount() const
956 return kNumInParams + kNumOutParams;
959 const NativeParameter* getParameterInfo(const uint32_t index) const
961 static NativeParameter param;
963 static char strBufName[STR_MAX+1];
964 static char strBufUnit[STR_MAX+1];
965 static char strBufComment[STR_MAX+1];
966 static char strBufGroupName[STR_MAX+1];
967 carla_zeroChars(strBufName, STR_MAX+1);
968 carla_zeroChars(strBufUnit, STR_MAX+1);
969 carla_zeroChars(strBufComment, STR_MAX+1);
970 carla_zeroChars(strBufGroupName, STR_MAX+1);
972 uint32_t rindex = index;
973 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
975 const ParameterData& paramData(plugin->getParameterData(rindex));
976 const ParameterRanges& paramRanges(plugin->getParameterRanges(rindex));
978 if (! plugin->getParameterName(rindex, strBufName))
979 strBufName[0] = '\0';
980 if (! plugin->getParameterUnit(rindex, strBufUnit))
981 strBufUnit[0] = '\0';
982 if (! plugin->getParameterComment(rindex, strBufComment))
983 strBufComment[0] = '\0';
984 if (! plugin->getParameterGroupName(rindex, strBufGroupName))
985 std::snprintf(strBufGroupName, STR_MAX, "%u:%s", plugin->getId(), plugin->getName());
987 uint hints = 0x0;
989 if (paramData.hints & PARAMETER_IS_BOOLEAN)
990 hints |= NATIVE_PARAMETER_IS_BOOLEAN;
991 if (paramData.hints & PARAMETER_IS_INTEGER)
992 hints |= NATIVE_PARAMETER_IS_INTEGER;
993 if (paramData.hints & PARAMETER_IS_LOGARITHMIC)
994 hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
995 if (paramData.hints & PARAMETER_IS_AUTOMATABLE)
996 hints |= NATIVE_PARAMETER_IS_AUTOMATABLE;
997 if (paramData.hints & PARAMETER_USES_SAMPLERATE)
998 hints |= NATIVE_PARAMETER_USES_SAMPLE_RATE;
999 if (paramData.hints & PARAMETER_USES_SCALEPOINTS)
1000 hints |= NATIVE_PARAMETER_USES_SCALEPOINTS;
1002 if (paramData.type == PARAMETER_INPUT || paramData.type == PARAMETER_OUTPUT)
1004 if (paramData.hints & PARAMETER_IS_ENABLED)
1005 hints |= NATIVE_PARAMETER_IS_ENABLED;
1006 if (paramData.type == PARAMETER_OUTPUT)
1007 hints |= NATIVE_PARAMETER_IS_OUTPUT;
1010 param.hints = static_cast<NativeParameterHints>(hints);
1011 param.name = strBufName;
1012 param.unit = strBufUnit;
1013 param.comment = strBufComment;
1014 param.groupName = strBufGroupName;
1015 param.ranges.def = paramRanges.def;
1016 param.ranges.min = paramRanges.min;
1017 param.ranges.max = paramRanges.max;
1018 param.ranges.step = paramRanges.step;
1019 param.ranges.stepSmall = paramRanges.stepSmall;
1020 param.ranges.stepLarge = paramRanges.stepLarge;
1021 param.scalePointCount = 0; // TODO
1022 param.scalePoints = nullptr;
1024 return &param;
1027 param.hints = index < kNumInParams ? static_cast<NativeParameterHints>(0x0) : NATIVE_PARAMETER_IS_OUTPUT;
1028 param.name = "Unused";
1029 param.unit = "";
1030 param.ranges.def = 0.0f;
1031 param.ranges.min = 0.0f;
1032 param.ranges.max = 1.0f;
1033 param.ranges.step = 0.01f;
1034 param.ranges.stepSmall = 0.001f;
1035 param.ranges.stepLarge = 0.1f;
1036 param.scalePointCount = 0;
1037 param.scalePoints = nullptr;
1039 return &param;
1042 float getParameterValue(const uint32_t index) const
1044 uint32_t rindex = index;
1045 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1046 return plugin->getParameterValue(rindex);
1048 return fParameters[index];
1051 // -------------------------------------------------------------------
1052 // Plugin state calls
1054 void setParameterValue(const uint32_t index, const float value)
1056 uint32_t rindex = index;
1057 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1058 plugin->setParameterValueRT(rindex, value, 0, false);
1060 fParameters[index] = value;
1063 // -------------------------------------------------------------------
1064 // Plugin process calls
1066 void activate()
1068 #if 0
1069 for (uint i=0; i < pData->curPluginCount; ++i)
1071 CarlaPluginPtr plugin = pData->plugins[i].plugin;
1073 if (plugin == nullptr || ! plugin->isEnabled())
1074 continue;
1076 plugin->setActive(true, true, false);
1078 #endif
1079 fIsActive = true;
1082 void deactivate()
1084 fIsActive = false;
1085 #if 0
1086 for (uint i=0; i < pData->curPluginCount; ++i)
1088 CarlaPluginPtr plugin = pData->plugins[i].plugin;
1090 if (plugin == nullptr || ! plugin->isEnabled())
1091 continue;
1093 plugin->setActive(false, true, false);
1095 #endif
1097 // just in case
1098 //runPendingRtEvents();
1101 void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames,
1102 const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount)
1104 if (frames > pData->bufferSize)
1106 carla_stderr2("Host is calling process with too high number of frames! %u vs %u",
1107 frames, pData->bufferSize);
1109 deactivate();
1110 bufferSizeChanged(frames);
1111 activate();
1114 const PendingRtEventsRunner prt(this, frames, true);
1116 // ---------------------------------------------------------------
1117 // Time Info
1119 const NativeTimeInfo* const timeInfo(pHost->get_time_info(pHost->handle));
1121 pData->timeInfo.playing = timeInfo->playing;
1122 pData->timeInfo.frame = timeInfo->frame;
1123 pData->timeInfo.usecs = timeInfo->usecs;
1124 pData->timeInfo.bbt.valid = timeInfo->bbt.valid;
1126 if (timeInfo->bbt.valid)
1128 pData->timeInfo.bbt.bar = timeInfo->bbt.bar;
1129 pData->timeInfo.bbt.beat = timeInfo->bbt.beat;
1130 pData->timeInfo.bbt.tick = timeInfo->bbt.tick;
1131 pData->timeInfo.bbt.barStartTick = timeInfo->bbt.barStartTick;
1133 pData->timeInfo.bbt.beatsPerBar = timeInfo->bbt.beatsPerBar;
1134 pData->timeInfo.bbt.beatType = timeInfo->bbt.beatType;
1136 pData->timeInfo.bbt.ticksPerBeat = timeInfo->bbt.ticksPerBeat;
1137 pData->timeInfo.bbt.beatsPerMinute = timeInfo->bbt.beatsPerMinute;
1140 // ---------------------------------------------------------------
1141 // Do nothing if no plugins and rack mode
1143 if (pData->curPluginCount == 0 && ! kIsPatchbay)
1145 if (outBuffer[0] != inBuffer[0])
1146 carla_copyFloats(outBuffer[0], inBuffer[0], frames);
1148 if (outBuffer[1] != inBuffer[1])
1149 carla_copyFloats(outBuffer[1], inBuffer[1], frames);
1151 for (uint32_t i=0; i < midiEventCount; ++i)
1153 if (! pHost->write_midi_event(pHost->handle, &midiEvents[i]))
1154 break;
1156 return;
1159 // ---------------------------------------------------------------
1160 // initialize events
1162 carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
1163 carla_zeroStructs(pData->events.out, kMaxEngineEventInternalCount);
1165 // ---------------------------------------------------------------
1166 // events input (before processing)
1168 if (kHasMidiIn)
1170 uint32_t engineEventIndex = 0;
1172 for (uint32_t i=0; i < midiEventCount && engineEventIndex < kMaxEngineEventInternalCount; ++i)
1174 const NativeMidiEvent& midiEvent(midiEvents[i]);
1175 EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);
1177 engineEvent.time = midiEvent.time;
1178 engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data, 0);
1180 if (engineEventIndex >= kMaxEngineEventInternalCount)
1181 break;
1185 if (kIsPatchbay)
1187 // -----------------------------------------------------------
1188 // process
1190 pData->graph.process(pData, inBuffer, outBuffer, frames);
1192 else
1194 // -----------------------------------------------------------
1195 // create audio buffers
1197 const float* inBuf[2] = { inBuffer[0], inBuffer[1] };
1198 /* */ float* outBuf[2] = { outBuffer[0], outBuffer[1] };
1200 // -----------------------------------------------------------
1201 // process
1203 pData->graph.processRack(pData, inBuf, outBuf, frames);
1206 // ---------------------------------------------------------------
1207 // events output (after processing)
1209 carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
1211 if (kHasMidiOut)
1213 NativeMidiEvent midiEvent;
1215 for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
1217 const EngineEvent& engineEvent(pData->events.out[i]);
1219 if (engineEvent.type == kEngineEventTypeNull)
1220 break;
1222 carla_zeroStruct(midiEvent);
1223 midiEvent.time = engineEvent.time;
1225 /**/ if (engineEvent.type == kEngineEventTypeControl)
1227 midiEvent.port = 0;
1228 midiEvent.size = engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.data);
1230 else if (engineEvent.type == kEngineEventTypeMidi)
1232 if (engineEvent.midi.size > 4)
1233 continue;
1235 midiEvent.port = engineEvent.midi.port;
1236 midiEvent.size = engineEvent.midi.size;
1238 midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
1240 for (uint8_t j=1; j < midiEvent.size; ++j)
1241 midiEvent.data[j] = engineEvent.midi.data[j];
1243 else
1245 continue;
1248 if (midiEvent.size > 0)
1249 pHost->write_midi_event(pHost->handle, &midiEvent);
1254 // -------------------------------------------------------------------
1255 // Plugin UI calls
1257 #ifndef CARLA_ENGINE_WITHOUT_UI
1258 void uiShow(const bool show)
1260 if (show)
1262 if (fUiServer.isPipeRunning())
1264 fUiServer.writeFocusMessage();
1265 return;
1268 CarlaString path(pHost->resourceDir);
1270 if (kIsPatchbay)
1271 path += CARLA_OS_SEP_STR "carla-plugin-patchbay";
1272 else
1273 path += CARLA_OS_SEP_STR "carla-plugin";
1274 #ifdef CARLA_OS_WIN
1275 path += ".exe";
1276 #endif
1277 carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer());
1279 fUiServer.setData(path, pData->sampleRate, pHost->uiName);
1281 #ifdef CARLA_OS_WIN
1282 // Fix conflict with other tools using Carla
1283 char* const oldcwd = _getcwd(nullptr, 0);
1284 chdir(pHost->resourceDir);
1285 #endif
1287 if (! fUiServer.startPipeServer(false))
1289 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
1290 return;
1293 uiServerInfo();
1294 uiServerOptions();
1295 uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED,
1296 pData->curPluginCount,
1297 pData->options.processMode,
1298 pData->options.transportMode,
1299 static_cast<int>(pData->bufferSize),
1300 static_cast<float>(pData->sampleRate),
1301 "Plugin");
1303 fUiServer.writeShowMessage();
1305 for (uint i=0; i < pData->curPluginCount; ++i)
1307 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1308 if (plugin->isEnabled())
1309 uiServerCallback(ENGINE_CALLBACK_PLUGIN_ADDED, i, plugin->getType(),
1310 0, 0, 0.0f,
1311 plugin->getName());
1314 if (kIsPatchbay)
1315 patchbayRefresh(true, false, false);
1317 #ifdef CARLA_OS_WIN
1318 chdir(oldcwd);
1319 std::free(oldcwd);
1320 #endif
1322 else
1324 fUiServer.stopPipeServer(2000);
1326 // hide all custom uis
1327 for (uint i=0; i < pData->curPluginCount; ++i)
1329 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1331 if (plugin->isEnabled())
1333 if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
1335 try {
1336 plugin->showCustomUI(false);
1337 } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin showCustomUI (hide)");
1344 #endif
1346 void uiIdle()
1348 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
1349 const ScopedJuceMessageThreadRunner sjmtr(*this, false);
1351 if (kNeedsJuceEvents && ! sjmtr.wasLocked)
1352 return;
1353 #endif
1355 for (uint i=0; i < pData->curPluginCount; ++i)
1357 if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
1359 if (plugin->isEnabled())
1361 const uint hints = plugin->getHints();
1363 if ((hints & PLUGIN_HAS_CUSTOM_UI) != 0 && (hints & PLUGIN_NEEDS_UI_MAIN_THREAD) != 0)
1365 try {
1366 plugin->uiIdle();
1367 } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin uiIdle");
1373 #ifndef CARLA_ENGINE_WITHOUT_UI
1374 idlePipe();
1376 switch (fUiServer.getAndResetUiState())
1378 case CarlaExternalUI::UiNone:
1379 case CarlaExternalUI::UiShow:
1380 break;
1381 case CarlaExternalUI::UiCrashed:
1382 pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
1383 break;
1384 case CarlaExternalUI::UiHide:
1385 pHost->ui_closed(pHost->handle);
1386 fUiServer.stopPipeServer(1000);
1387 break;
1389 #endif
1391 if (carla_isNotEqual(fLastScaleFactor, pData->options.uiScale))
1393 fLastScaleFactor = pData->options.uiScale;
1394 pHost->dispatcher(pHost->handle,
1395 NATIVE_HOST_OPCODE_UI_RESIZE,
1396 static_cast<int>(kUiWidth * fLastScaleFactor + 0.5f),
1397 static_cast<int>(kUiHeight * fLastScaleFactor + 0.5f),
1398 nullptr, 0.0f);
1402 const CarlaMutexLocker cml(fPluginDeleterMutex);
1403 pData->deletePluginsAsNeeded();
1407 void uiSetParameterValue(const uint32_t index, const float value)
1409 uint32_t rindex = index;
1410 if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
1412 if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
1413 plugin->uiParameterChange(rindex, value);
1415 #ifndef CARLA_ENGINE_WITHOUT_UI
1416 if (index >= kNumInParams || ! fUiServer.isPipeRunning())
1417 return;
1419 uiServerCallback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
1420 plugin->getId(),
1421 static_cast<int>(rindex),
1422 0, 0,
1423 value,
1424 nullptr);
1425 #endif
1429 #ifndef CARLA_ENGINE_WITHOUT_UI
1430 void idlePipe()
1432 if (! fUiServer.isPipeRunning())
1433 return;
1435 fUiServer.idlePipe();
1437 if (! fUiServer.isPipeRunning())
1438 return;
1440 char tmpBuf[STR_MAX+1];
1441 carla_zeroChars(tmpBuf, STR_MAX+1);
1443 const CarlaMutexLocker cml(fUiServer.getPipeLock());
1444 const CarlaScopedLocale csl;
1445 const EngineTimeInfo& timeInfo(pData->timeInfo);
1447 // ------------------------------------------------------------------------------------------------------------
1448 // send engine info
1450 std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad()));
1451 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("runtime-info\n"),);
1452 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1454 fUiServer.syncMessages();
1456 if (const char* const projFolder = getCurrentProjectFolder())
1458 if (fLastProjectFolder != projFolder)
1460 carla_stdout("Project folder changed to %s", projFolder);
1461 fLastProjectFolder = projFolder;
1462 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("project-folder\n"),);
1463 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(projFolder),);
1464 fUiServer.syncMessages();
1468 // ------------------------------------------------------------------------------------------------------------
1469 // send transport
1471 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("transport\n"),);
1472 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),);
1474 if (timeInfo.bbt.valid)
1476 std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":%i:%i:%i\n", timeInfo.frame,
1477 timeInfo.bbt.bar,
1478 timeInfo.bbt.beat,
1479 static_cast<int>(timeInfo.bbt.tick + 0.5));
1480 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1481 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", timeInfo.bbt.beatsPerMinute);
1482 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1484 else
1486 std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":0:0:0\n", timeInfo.frame);
1487 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1488 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("0.0\n"),);
1491 fUiServer.syncMessages();
1493 // ------------------------------------------------------------------------------------------------------------
1494 // send peaks and param outputs for all plugins
1496 for (uint i=0; i < pData->curPluginCount; ++i)
1498 const EnginePluginData& plugData(pData->plugins[i]);
1499 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1501 std::snprintf(tmpBuf, STR_MAX, "PEAKS_%i\n", i);
1502 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1503 std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g\n",
1504 static_cast<double>(plugData.peaks[0]),
1505 static_cast<double>(plugData.peaks[1]),
1506 static_cast<double>(plugData.peaks[2]),
1507 static_cast<double>(plugData.peaks[3]));
1508 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1510 fUiServer.syncMessages();
1512 for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j)
1514 if (! plugin->isParameterOutput(j))
1515 continue;
1517 std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", i, j);
1518 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1519 std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(j)));
1520 CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
1522 fUiServer.syncMessages();
1526 #endif
1528 // -------------------------------------------------------------------
1529 // Plugin state calls
1531 char* getState() const
1533 MemoryOutputStream out;
1534 saveProjectInternal(out);
1535 return strdup(out.toString().toRawUTF8());
1538 void setState(const char* const data)
1540 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
1541 const ScopedJuceMessageThreadRunner sjmtr(*this, true);
1542 #endif
1544 // remove all plugins from UI side
1545 for (uint i=0, count=pData->curPluginCount; i < count; ++i)
1546 CarlaEngine::callback(true, true, ENGINE_CALLBACK_PLUGIN_REMOVED, count-i-1, 0, 0, 0, 0.0f, nullptr);
1548 // remove all plugins from backend, no lock
1549 fIsRunning = false;
1550 removeAllPlugins();
1551 fIsRunning = true;
1554 const CarlaMutexLocker cml(fPluginDeleterMutex);
1555 pData->deletePluginsAsNeeded();
1558 // stopped during removeAllPlugins()
1559 if (! pData->runner.isRunnerActive())
1560 pData->runner.start();
1562 fOptionsForced = true;
1563 const String state(data);
1564 XmlDocument xml(state);
1565 loadProjectInternal(xml, true);
1567 reloadFromUI();
1570 // -------------------------------------------------------------------
1572 public:
1573 #define handlePtr ((CarlaEngineNative*)handle)
1575 static NativePluginHandle _instantiateRack(const NativeHostDescriptor* host)
1577 return new CarlaEngineNative(host, false, true, true);
1580 static NativePluginHandle _instantiateRackNoMidiOut(const NativeHostDescriptor* host)
1582 return new CarlaEngineNative(host, false, true, false);
1585 static NativePluginHandle _instantiatePatchbay(const NativeHostDescriptor* host)
1587 return new CarlaEngineNative(host, true, true, true);
1590 static NativePluginHandle _instantiatePatchbay3s(const NativeHostDescriptor* host)
1592 return new CarlaEngineNative(host, true, true, true, 3, 2);
1595 static NativePluginHandle _instantiatePatchbay16(const NativeHostDescriptor* host)
1597 return new CarlaEngineNative(host, true, true, true, 16, 16);
1600 static NativePluginHandle _instantiatePatchbay32(const NativeHostDescriptor* host)
1602 return new CarlaEngineNative(host, true, true, true, 32, 32);
1605 static NativePluginHandle _instantiatePatchbay64(const NativeHostDescriptor* host)
1607 return new CarlaEngineNative(host, true, true, true, 64, 64);
1610 static NativePluginHandle _instantiatePatchbayCV(const NativeHostDescriptor* host)
1612 return new CarlaEngineNative(host, true, true, true, 2, 2, 5, 5);
1615 static NativePluginHandle _instantiatePatchbayCV8(const NativeHostDescriptor* host)
1617 return new CarlaEngineNative(host, true, true, true, 2, 2, 8, 8);
1620 static NativePluginHandle _instantiatePatchbayCV32(const NativeHostDescriptor* host)
1622 return new CarlaEngineNative(host, true, true, true, 64, 64, 32, 32);
1625 static NativePluginHandle _instantiatePatchbayOBS(const NativeHostDescriptor* host)
1627 return new CarlaEngineNative(host, true, false, false, 8, 8);
1630 static void _cleanup(NativePluginHandle handle)
1632 delete handlePtr;
1635 static uint32_t _get_parameter_count(NativePluginHandle handle)
1637 return handlePtr->getParameterCount();
1640 static const NativeParameter* _get_parameter_info(NativePluginHandle handle, uint32_t index)
1642 return handlePtr->getParameterInfo(index);
1645 static float _get_parameter_value(NativePluginHandle handle, uint32_t index)
1647 return handlePtr->getParameterValue(index);
1650 static void _set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
1652 handlePtr->setParameterValue(index, value);
1655 #ifndef CARLA_ENGINE_WITHOUT_UI
1656 static void _ui_show(NativePluginHandle handle, bool show)
1658 handlePtr->uiShow(show);
1660 #endif
1662 static void _ui_idle(NativePluginHandle handle)
1664 handlePtr->uiIdle();
1667 static void _ui_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
1669 handlePtr->uiSetParameterValue(index, value);
1672 static void _activate(NativePluginHandle handle)
1674 handlePtr->activate();
1677 static void _deactivate(NativePluginHandle handle)
1679 handlePtr->deactivate();
1682 // FIXME for v3.0, use const for the input buffer
1683 static void _process(NativePluginHandle handle,
1684 float** inBuffer, float** outBuffer, const uint32_t frames,
1685 const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
1687 handlePtr->process(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
1690 static char* _get_state(NativePluginHandle handle)
1692 return handlePtr->getState();
1695 static void _set_state(NativePluginHandle handle, const char* data)
1697 handlePtr->setState(data);
1700 static intptr_t _dispatcher(NativePluginHandle handle,
1701 NativePluginDispatcherOpcode opcode,
1702 int32_t index, intptr_t value, void* ptr, float opt)
1704 switch(opcode)
1706 case NATIVE_PLUGIN_OPCODE_NULL:
1707 return 0;
1708 case NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
1709 CARLA_SAFE_ASSERT_RETURN(value > 0, 0);
1710 handlePtr->bufferSizeChanged(static_cast<uint32_t>(value));
1711 return 0;
1712 case NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
1713 CARLA_SAFE_ASSERT_RETURN(opt > 0.0f, 0);
1714 handlePtr->sampleRateChanged(static_cast<double>(opt));
1715 return 0;
1716 case NATIVE_PLUGIN_OPCODE_OFFLINE_CHANGED:
1717 handlePtr->offlineModeChanged(value != 0);
1718 return 0;
1719 case NATIVE_PLUGIN_OPCODE_UI_NAME_CHANGED:
1720 //handlePtr->uiNameChanged(static_cast<const char*>(ptr));
1721 return 0;
1722 case NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE: {
1723 CarlaEngineNative* const engine = handlePtr;
1724 return (intptr_t)(CarlaEngine*)engine;
1726 case NATIVE_PLUGIN_OPCODE_IDLE:
1727 //handlePtr->idle();
1728 return 0;
1729 case NATIVE_PLUGIN_OPCODE_UI_MIDI_EVENT:
1730 return 0;
1731 case NATIVE_PLUGIN_OPCODE_HOST_USES_EMBED:
1732 handlePtr->fUsesEmbed = true;
1733 return 0;
1734 case NATIVE_PLUGIN_OPCODE_HOST_OPTION:
1735 handlePtr->setOption(static_cast<EngineOption>(index), value, static_cast<const char*>(ptr));
1736 return 0;
1739 return 0;
1741 // unused
1742 (void)index;
1743 (void)ptr;
1746 // -------------------------------------------------------------------
1748 #undef handlePtr
1750 private:
1751 const NativeHostDescriptor* const pHost;
1753 #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
1754 const bool kNeedsJuceEvents;
1755 const CarlaJUCE::ReferenceCountedJuceMessageMessager fJuceMsgMgr;
1756 CarlaMutex fJuceMsgMutex;
1758 struct ScopedJuceMessageThreadRunner {
1759 const CarlaMutexTryLocker cmtl;
1760 const bool wasLocked;
1762 ScopedJuceMessageThreadRunner(CarlaEngineNative& self, const bool forceLock) noexcept
1763 : cmtl(self.fJuceMsgMutex, forceLock),
1764 wasLocked(cmtl.wasLocked())
1766 if (! self.kNeedsJuceEvents)
1767 return;
1768 if (! wasLocked)
1769 return;
1771 CarlaJUCE::setMessageManagerForThisThread();
1774 ~ScopedJuceMessageThreadRunner()
1776 CarlaJUCE::dispatchMessageManagerMessages();
1779 CARLA_DECLARE_NON_COPYABLE(ScopedJuceMessageThreadRunner)
1781 #endif
1783 const bool kIsPatchbay; // rack if false
1784 const bool kHasMidiIn;
1785 const bool kHasMidiOut;
1786 bool fIsActive, fIsRunning, fUsesEmbed;
1787 #ifndef CARLA_ENGINE_WITHOUT_UI
1788 CarlaEngineNativeUI fUiServer;
1789 #endif
1790 float fLastScaleFactor;
1792 float fParameters[kNumInParams+kNumOutParams];
1793 CarlaString fLastProjectFolder;
1794 CarlaMutex fPluginDeleterMutex;
1796 bool fOptionsForced;
1798 CarlaPluginPtr _getPluginForParameterIndex(uint32_t& index) const noexcept
1800 if (pData->curPluginCount == 0 || pData->plugins == nullptr)
1801 return nullptr;
1803 for (uint32_t i=0; i<pData->curPluginCount; ++i)
1805 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1807 if (plugin.get() == nullptr || ! plugin->isEnabled())
1808 break;
1810 if (const uint32_t paramCount = plugin->getParameterCount())
1812 if (index >= paramCount)
1814 index -= paramCount;
1815 continue;
1818 return plugin;
1822 return nullptr;
1825 bool _getRealIndexForPluginParameter(const uint32_t pluginId, uint32_t& rindex) const noexcept
1827 if (pData->curPluginCount == 0 || pluginId >= pData->curPluginCount || pData->plugins == nullptr)
1828 return false;
1830 for (uint32_t i=0; i<pluginId; ++i)
1832 const CarlaPluginPtr plugin = pData->plugins[i].plugin;
1834 if (plugin.get() == nullptr || ! plugin->isEnabled())
1835 return false;
1837 rindex += plugin->getParameterCount();
1840 if (rindex >= kNumInParams)
1841 return false;
1843 return true;
1846 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNative)
1849 // -----------------------------------------------------------------------
1851 #ifndef CARLA_ENGINE_WITHOUT_UI
1852 bool CarlaEngineNativeUI::msgReceived(const char* const msg) noexcept
1854 if (CarlaExternalUI::msgReceived(msg))
1855 return true;
1857 bool ok = true;
1859 if (std::strcmp(msg, "set_engine_option") == 0)
1861 uint32_t option;
1862 int32_t value;
1863 const char* valueStr = nullptr;
1865 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
1866 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(value), true);
1867 readNextLineAsString(valueStr, false); // can be null
1869 try {
1870 fEngine->setOption(static_cast<EngineOption>(option), value, valueStr);
1871 } CARLA_SAFE_EXCEPTION("setOption");
1873 else if (std::strcmp(msg, "clear_engine_xruns") == 0)
1875 fEngine->clearXruns();
1877 else if (std::strcmp(msg, "cancel_engine_action") == 0)
1879 fEngine->setActionCanceled(true);
1881 else if (std::strcmp(msg, "load_file") == 0)
1883 const char* filename;
1885 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1887 try {
1888 ok = fEngine->loadFile(filename);
1889 } CARLA_SAFE_EXCEPTION("loadFile");
1891 fEngine->reloadFromUI();
1893 else if (std::strcmp(msg, "load_project") == 0)
1895 const char* filename;
1897 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1899 try {
1900 ok = fEngine->loadProject(filename, true);
1901 } CARLA_SAFE_EXCEPTION("loadProject");
1903 fEngine->reloadFromUI();
1905 else if (std::strcmp(msg, "save_project") == 0)
1907 const char* filename;
1909 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
1911 try {
1912 ok = fEngine->saveProject(filename, true);
1913 } CARLA_SAFE_EXCEPTION("saveProject");
1915 else if (std::strcmp(msg, "clear_project_filename") == 0)
1917 fEngine->clearCurrentProjectFilename();
1919 else if (std::strcmp(msg, "patchbay_connect") == 0)
1921 bool external;
1922 uint32_t groupA, portA, groupB, portB;
1924 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1925 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupA), true);
1926 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portA), true);
1927 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupB), true);
1928 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portB), true);
1930 try {
1931 ok = fEngine->patchbayConnect(external, groupA, portA, groupB, portB);
1932 } CARLA_SAFE_EXCEPTION("patchbayConnect");
1934 else if (std::strcmp(msg, "patchbay_disconnect") == 0)
1936 bool external;
1937 uint32_t connectionId;
1939 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1940 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(connectionId), true);
1942 try {
1943 ok = fEngine->patchbayDisconnect(external, connectionId);
1944 } CARLA_SAFE_EXCEPTION("patchbayDisconnect");
1946 else if (std::strcmp(msg, "patchbay_set_group_pos") == 0)
1948 bool external;
1949 uint32_t groupId;
1950 int x1, y1, x2, y2;
1951 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1952 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupId), true);
1953 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x1), true);
1954 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y1), true);
1955 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x2), true);
1956 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y2), true);
1958 try {
1959 ok = fEngine->patchbaySetGroupPos(false, true, external, groupId, x1, y1, x2, y2);
1960 } CARLA_SAFE_EXCEPTION("patchbaySetGroupPos");
1962 else if (std::strcmp(msg, "patchbay_refresh") == 0)
1964 bool external;
1965 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
1967 try {
1968 ok = fEngine->patchbayRefresh(true, false, external);
1969 } CARLA_SAFE_EXCEPTION("patchbayRefresh");
1971 else if (std::strcmp(msg, "transport_play") == 0)
1973 fEngine->transportPlay();
1975 else if (std::strcmp(msg, "transport_pause") == 0)
1977 fEngine->transportPause();
1979 else if (std::strcmp(msg, "transport_bpm") == 0)
1981 double bpm;
1983 CARLA_SAFE_ASSERT_RETURN(readNextLineAsDouble(bpm), true);
1985 fEngine->transportBPM(bpm);
1987 else if (std::strcmp(msg, "transport_relocate") == 0)
1989 uint64_t frame;
1991 CARLA_SAFE_ASSERT_RETURN(readNextLineAsULong(frame), true);
1993 fEngine->transportRelocate(frame);
1995 else if (std::strcmp(msg, "add_plugin") == 0)
1997 uint32_t btype, ptype;
1998 const char* filename = nullptr;
1999 const char* name;
2000 const char* label;
2001 int64_t uniqueId;
2002 uint options;
2004 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(btype), true);
2005 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(ptype), true);
2006 readNextLineAsString(filename, true); // can be null
2007 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(name, true), true);
2008 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(label, true), true);
2009 CARLA_SAFE_ASSERT_RETURN(readNextLineAsLong(uniqueId), true);
2010 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(options), true);
2012 if (filename != nullptr && std::strcmp(filename, "(null)") == 0)
2014 std::free(const_cast<char*>(filename));
2015 filename = nullptr;
2018 if (std::strcmp(name, "(null)") == 0)
2020 std::free(const_cast<char*>(name));
2021 name = nullptr;
2024 ok = fEngine->addPlugin(static_cast<BinaryType>(btype), static_cast<PluginType>(ptype),
2025 filename, name, label, uniqueId, nullptr, options);
2027 if (filename != nullptr)
2028 std::free(const_cast<char*>(filename));
2029 if (name != nullptr)
2030 std::free(const_cast<char*>(name));
2031 std::free(const_cast<char*>(label));
2033 fEngine->reloadFromUI();
2035 else if (std::strcmp(msg, "remove_plugin") == 0)
2037 uint32_t pluginId;
2039 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2041 ok = fEngine->removePlugin(pluginId);
2042 fEngine->reloadFromUI();
2044 else if (std::strcmp(msg, "remove_all_plugins") == 0)
2046 ok = fEngine->removeAllPlugins();
2047 fEngine->reloadFromUI();
2049 else if (std::strcmp(msg, "rename_plugin") == 0)
2051 uint32_t pluginId;
2052 const char* newName;
2054 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2055 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName, false), true);
2057 ok = fEngine->renamePlugin(pluginId, newName);
2059 else if (std::strcmp(msg, "clone_plugin") == 0)
2061 uint32_t pluginId;
2063 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2065 ok = fEngine->clonePlugin(pluginId);
2066 fEngine->reloadFromUI();
2068 else if (std::strcmp(msg, "replace_plugin") == 0)
2070 uint32_t pluginId;
2072 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2074 ok = fEngine->replacePlugin(pluginId);
2076 else if (std::strcmp(msg, "switch_plugins") == 0)
2078 uint32_t pluginIdA, pluginIdB;
2080 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdA), true);
2081 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdB), true);
2083 ok = fEngine->switchPlugins(pluginIdA, pluginIdB);
2084 fEngine->reloadFromUI();
2086 else if (std::strcmp(msg, "load_plugin_state") == 0)
2088 uint32_t pluginId;
2089 const char* filename;
2091 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2092 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
2094 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2096 plugin->loadStateFromFile(filename);
2097 _updateParamValues(plugin, pluginId, false, true);
2100 else if (std::strcmp(msg, "save_plugin_state") == 0)
2102 uint32_t pluginId;
2103 const char* filename;
2105 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2106 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
2108 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2109 plugin->saveStateToFile(filename);
2111 else if (std::strcmp(msg, "set_option") == 0)
2113 uint32_t pluginId, option;
2114 bool yesNo;
2116 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2117 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
2118 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
2120 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2121 plugin->setOption(option, yesNo, false);
2123 else if (std::strcmp(msg, "set_active") == 0)
2125 uint32_t pluginId;
2126 bool onOff;
2128 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2129 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(onOff), true);
2131 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2132 plugin->setActive(onOff, true, false);
2134 else if (std::strcmp(msg, "set_drywet") == 0)
2136 uint32_t pluginId;
2137 float value;
2139 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2140 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2142 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2143 plugin->setDryWet(value, true, false);
2145 else if (std::strcmp(msg, "set_volume") == 0)
2147 uint32_t pluginId;
2148 float value;
2150 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2151 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2153 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2154 plugin->setVolume(value, true, false);
2156 else if (std::strcmp(msg, "set_balance_left") == 0)
2158 uint32_t pluginId;
2159 float value;
2161 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2162 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2164 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2165 plugin->setBalanceLeft(value, true, false);
2167 else if (std::strcmp(msg, "set_balance_right") == 0)
2169 uint32_t pluginId;
2170 float value;
2172 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2173 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2175 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2176 plugin->setBalanceRight(value, true, false);
2178 else if (std::strcmp(msg, "set_panning") == 0)
2180 uint32_t pluginId;
2181 float value;
2183 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2184 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2186 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2187 plugin->setPanning(value, true, false);
2189 else if (std::strcmp(msg, "set_ctrl_channel") == 0)
2191 uint32_t pluginId;
2192 int32_t channel;
2194 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2195 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel), true);
2196 CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS, true);
2198 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2199 plugin->setCtrlChannel(int8_t(channel), true, false);
2201 else if (std::strcmp(msg, "set_parameter_value") == 0)
2203 uint32_t pluginId, parameterId;
2204 float value;
2206 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2207 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2208 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
2210 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2212 plugin->setParameterValue(parameterId, value, true, true, false);
2213 fEngine->setParameterValueFromUI(pluginId, parameterId, value);
2216 else if (std::strcmp(msg, "set_parameter_midi_channel") == 0)
2218 uint32_t pluginId, parameterId, channel;
2220 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2221 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2222 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
2223 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
2225 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2226 plugin->setParameterMidiChannel(parameterId, static_cast<uint8_t>(channel), true, false);
2228 else if (std::strcmp(msg, "set_parameter_mapped_control_index") == 0)
2230 uint32_t pluginId, parameterId;
2231 int32_t ctrl;
2233 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2234 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2235 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(ctrl), true);
2236 CARLA_SAFE_ASSERT_RETURN(ctrl >= CONTROL_INDEX_NONE && ctrl <= CONTROL_INDEX_MAX_ALLOWED, true);
2238 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2239 plugin->setParameterMappedControlIndex(parameterId, static_cast<int16_t>(ctrl), true, false, true);
2241 else if (std::strcmp(msg, "set_parameter_mapped_range") == 0)
2243 uint32_t pluginId, parameterId;
2244 float minimum, maximum;
2246 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2247 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2248 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(minimum), true);
2249 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(maximum), true);
2251 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2252 plugin->setParameterMappedRange(parameterId, minimum, maximum, true, false);
2254 else if (std::strcmp(msg, "set_parameter_touch") == 0)
2256 uint32_t pluginId, parameterId;
2257 bool touching;
2259 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2260 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
2261 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(touching), true);
2263 if (fEngine->getPlugin(pluginId))
2264 fEngine->setParameterTouchFromUI(pluginId, parameterId, touching);
2266 else if (std::strcmp(msg, "set_program") == 0)
2268 uint32_t pluginId;
2269 int32_t index;
2271 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2272 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
2274 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2276 plugin->setProgram(index, true, true, false);
2277 _updateParamValues(plugin, pluginId, true, true);
2280 else if (std::strcmp(msg, "set_midi_program") == 0)
2282 uint32_t pluginId;
2283 int32_t index;
2285 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2286 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
2288 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2290 plugin->setMidiProgram(index, true, true, false);
2291 _updateParamValues(plugin, pluginId, true, true);
2294 else if (std::strcmp(msg, "set_custom_data") == 0)
2296 uint32_t pluginId;
2297 const char* type;
2298 const char* key;
2299 const char* value;
2301 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2302 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(type, true), true);
2303 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key, true), true);
2304 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value, false), true);
2306 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2307 plugin->setCustomData(type, key, value, true);
2309 std::free(const_cast<char*>(type));
2310 std::free(const_cast<char*>(key));
2312 else if (std::strcmp(msg, "set_chunk_data") == 0)
2314 uint32_t pluginId;
2315 const char* cdata;
2317 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2318 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(cdata, false), true);
2320 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2322 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(cdata));
2323 #ifdef CARLA_PROPER_CPP11_SUPPORT
2324 plugin->setChunkData(chunk.data(), chunk.size());
2325 #else
2326 plugin->setChunkData(&chunk.front(), chunk.size());
2327 #endif
2328 _updateParamValues(plugin, pluginId, false, true);
2331 else if (std::strcmp(msg, "prepare_for_save") == 0)
2333 uint32_t pluginId;
2335 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2337 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2338 plugin->prepareForSave(false);
2340 else if (std::strcmp(msg, "reset_parameters") == 0)
2342 uint32_t pluginId;
2344 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2346 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2348 plugin->resetParameters();
2349 _updateParamValues(plugin, pluginId, false, true);
2352 else if (std::strcmp(msg, "randomize_parameters") == 0)
2354 uint32_t pluginId;
2356 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2358 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2360 plugin->randomizeParameters();
2361 _updateParamValues(plugin, pluginId, false, true);
2364 else if (std::strcmp(msg, "send_midi_note") == 0)
2366 uint32_t pluginId, channel, note, velocity;
2368 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2369 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
2370 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(note), true);
2371 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(velocity), true);
2372 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
2373 CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_VALUE, true);
2374 CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE, true);
2376 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2377 plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(velocity), true, true, false);
2379 else if (std::strcmp(msg, "show_custom_ui") == 0)
2381 uint32_t pluginId;
2382 bool yesNo;
2384 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
2385 CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
2387 if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
2388 plugin->showCustomUI(yesNo);
2390 else
2392 carla_stderr("CarlaEngineNativeUI::msgReceived : %s", msg);
2393 return false;
2396 if (! ok)
2398 const CarlaMutexLocker cml(getPipeLock());
2400 if (writeMessage("error\n", 6) && writeAndFixMessage(fEngine->getLastError()))
2401 syncMessages();
2404 return true;
2407 void CarlaEngineNativeUI::_updateParamValues(const CarlaPluginPtr& plugin,
2408 const uint32_t pluginId,
2409 const bool sendCallback, const bool sendPluginHost) const noexcept
2411 float value;
2413 for (uint32_t i=0, count=plugin->getParameterCount(); i<count; ++i) {
2414 value = plugin->getParameterValue(i);
2416 if (sendCallback) {
2417 fEngine->callback(true, true,
2418 ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
2419 pluginId,
2420 static_cast<int>(i),
2421 0, 0,
2422 value,
2423 nullptr);
2426 if (sendPluginHost) {
2427 carla_stdout("_updateParamValues");
2428 fEngine->setParameterValueFromUI(pluginId, i, value);
2432 #endif
2434 // -----------------------------------------------------------------------
2436 static const NativePluginDescriptor carlaRackDesc = {
2437 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2438 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2439 |NATIVE_PLUGIN_HAS_UI
2440 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2441 |NATIVE_PLUGIN_USES_STATE
2442 |NATIVE_PLUGIN_USES_TIME
2443 |NATIVE_PLUGIN_USES_UI_SIZE),
2444 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2445 /* audioIns */ 2,
2446 /* audioOuts */ 2,
2447 /* midiIns */ 1,
2448 /* midiOuts */ 1,
2449 /* paramIns */ kNumInParams,
2450 /* paramOuts */ kNumOutParams,
2451 /* name */ "Carla-Rack",
2452 /* label */ "carlarack",
2453 /* maker */ "falkTX",
2454 /* copyright */ "GNU GPL v2+",
2455 CarlaEngineNative::_instantiateRack,
2456 CarlaEngineNative::_cleanup,
2457 CarlaEngineNative::_get_parameter_count,
2458 CarlaEngineNative::_get_parameter_info,
2459 CarlaEngineNative::_get_parameter_value,
2460 /* _get_midi_program_count */ nullptr,
2461 /* _get_midi_program_info */ nullptr,
2462 CarlaEngineNative::_set_parameter_value,
2463 /* _set_midi_program */ nullptr,
2464 /* _set_custom_data */ nullptr,
2465 #ifndef CARLA_ENGINE_WITHOUT_UI
2466 CarlaEngineNative::_ui_show,
2467 #else
2468 nullptr,
2469 #endif
2470 CarlaEngineNative::_ui_idle,
2471 CarlaEngineNative::_ui_set_parameter_value,
2472 /* _ui_set_midi_program */ nullptr,
2473 /* _ui_set_custom_data */ nullptr,
2474 CarlaEngineNative::_activate,
2475 CarlaEngineNative::_deactivate,
2476 CarlaEngineNative::_process,
2477 CarlaEngineNative::_get_state,
2478 CarlaEngineNative::_set_state,
2479 CarlaEngineNative::_dispatcher,
2480 /* _render_inline_dsplay */ nullptr,
2481 /* cvIns */ 0,
2482 /* cvOuts */ 0,
2483 /* _get_buffer_port_name */ nullptr,
2484 /* _get_buffer_port_range */ nullptr,
2485 /* ui_width */ kUiWidth,
2486 /* ui_height */ kUiHeight
2489 static const NativePluginDescriptor carlaRackNoMidiOutDesc = {
2490 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2491 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2492 |NATIVE_PLUGIN_HAS_UI
2493 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2494 |NATIVE_PLUGIN_USES_STATE
2495 |NATIVE_PLUGIN_USES_TIME
2496 |NATIVE_PLUGIN_USES_UI_SIZE),
2497 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2498 /* audioIns */ 2,
2499 /* audioOuts */ 2,
2500 /* midiIns */ 1,
2501 /* midiOuts */ 0,
2502 /* paramIns */ kNumInParams,
2503 /* paramOuts */ kNumOutParams,
2504 /* name */ "Carla-Rack (no midi out)",
2505 /* label */ "carlarack-nomidiout",
2506 /* maker */ "falkTX",
2507 /* copyright */ "GNU GPL v2+",
2508 CarlaEngineNative::_instantiateRackNoMidiOut,
2509 CarlaEngineNative::_cleanup,
2510 CarlaEngineNative::_get_parameter_count,
2511 CarlaEngineNative::_get_parameter_info,
2512 CarlaEngineNative::_get_parameter_value,
2513 /* _get_midi_program_count */ nullptr,
2514 /* _get_midi_program_info */ nullptr,
2515 CarlaEngineNative::_set_parameter_value,
2516 /* _set_midi_program */ nullptr,
2517 /* _set_custom_data */ nullptr,
2518 #ifndef CARLA_ENGINE_WITHOUT_UI
2519 CarlaEngineNative::_ui_show,
2520 #else
2521 nullptr,
2522 #endif
2523 CarlaEngineNative::_ui_idle,
2524 CarlaEngineNative::_ui_set_parameter_value,
2525 /* _ui_set_midi_program */ nullptr,
2526 /* _ui_set_custom_data */ nullptr,
2527 CarlaEngineNative::_activate,
2528 CarlaEngineNative::_deactivate,
2529 CarlaEngineNative::_process,
2530 CarlaEngineNative::_get_state,
2531 CarlaEngineNative::_set_state,
2532 CarlaEngineNative::_dispatcher,
2533 /* _render_inline_dsplay */ nullptr,
2534 /* cvIns */ 0,
2535 /* cvOuts */ 0,
2536 /* _get_buffer_port_name */ nullptr,
2537 /* _get_buffer_port_range */ nullptr,
2538 /* ui_width */ kUiWidth,
2539 /* ui_height */ kUiHeight
2542 static const NativePluginDescriptor carlaPatchbayDesc = {
2543 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2544 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2545 |NATIVE_PLUGIN_HAS_UI
2546 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2547 |NATIVE_PLUGIN_USES_STATE
2548 |NATIVE_PLUGIN_USES_TIME
2549 |NATIVE_PLUGIN_USES_UI_SIZE),
2550 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2551 /* audioIns */ 2,
2552 /* audioOuts */ 2,
2553 /* midiIns */ 1,
2554 /* midiOuts */ 1,
2555 /* paramIns */ kNumInParams,
2556 /* paramOuts */ kNumOutParams,
2557 /* name */ "Carla-Patchbay",
2558 /* label */ "carlapatchbay",
2559 /* maker */ "falkTX",
2560 /* copyright */ "GNU GPL v2+",
2561 CarlaEngineNative::_instantiatePatchbay,
2562 CarlaEngineNative::_cleanup,
2563 CarlaEngineNative::_get_parameter_count,
2564 CarlaEngineNative::_get_parameter_info,
2565 CarlaEngineNative::_get_parameter_value,
2566 /* _get_midi_program_count */ nullptr,
2567 /* _get_midi_program_info */ nullptr,
2568 CarlaEngineNative::_set_parameter_value,
2569 /* _set_midi_program */ nullptr,
2570 /* _set_custom_data */ nullptr,
2571 #ifndef CARLA_ENGINE_WITHOUT_UI
2572 CarlaEngineNative::_ui_show,
2573 #else
2574 nullptr,
2575 #endif
2576 CarlaEngineNative::_ui_idle,
2577 CarlaEngineNative::_ui_set_parameter_value,
2578 /* _ui_set_midi_program */ nullptr,
2579 /* _ui_set_custom_data */ nullptr,
2580 CarlaEngineNative::_activate,
2581 CarlaEngineNative::_deactivate,
2582 CarlaEngineNative::_process,
2583 CarlaEngineNative::_get_state,
2584 CarlaEngineNative::_set_state,
2585 CarlaEngineNative::_dispatcher,
2586 /* _render_inline_dsplay */ nullptr,
2587 /* cvIns */ 0,
2588 /* cvOuts */ 0,
2589 /* _get_buffer_port_name */ nullptr,
2590 /* _get_buffer_port_range */ nullptr,
2591 /* ui_width */ kUiWidth,
2592 /* ui_height */ kUiHeight
2595 static const NativePluginDescriptor carlaPatchbay3sDesc = {
2596 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2597 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2598 |NATIVE_PLUGIN_HAS_UI
2599 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2600 |NATIVE_PLUGIN_USES_STATE
2601 |NATIVE_PLUGIN_USES_TIME
2602 |NATIVE_PLUGIN_USES_UI_SIZE),
2603 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2604 /* audioIns */ 3,
2605 /* audioOuts */ 2,
2606 /* midiIns */ 1,
2607 /* midiOuts */ 1,
2608 /* paramIns */ kNumInParams,
2609 /* paramOuts */ kNumOutParams,
2610 /* name */ "Carla-Patchbay (sidechain)",
2611 /* label */ "carlapatchbay3s",
2612 /* maker */ "falkTX",
2613 /* copyright */ "GNU GPL v2+",
2614 CarlaEngineNative::_instantiatePatchbay3s,
2615 CarlaEngineNative::_cleanup,
2616 CarlaEngineNative::_get_parameter_count,
2617 CarlaEngineNative::_get_parameter_info,
2618 CarlaEngineNative::_get_parameter_value,
2619 /* _get_midi_program_count */ nullptr,
2620 /* _get_midi_program_info */ nullptr,
2621 CarlaEngineNative::_set_parameter_value,
2622 /* _set_midi_program */ nullptr,
2623 /* _set_custom_data */ nullptr,
2624 #ifndef CARLA_ENGINE_WITHOUT_UI
2625 CarlaEngineNative::_ui_show,
2626 #else
2627 nullptr,
2628 #endif
2629 CarlaEngineNative::_ui_idle,
2630 CarlaEngineNative::_ui_set_parameter_value,
2631 /* _ui_set_midi_program */ nullptr,
2632 /* _ui_set_custom_data */ nullptr,
2633 CarlaEngineNative::_activate,
2634 CarlaEngineNative::_deactivate,
2635 CarlaEngineNative::_process,
2636 CarlaEngineNative::_get_state,
2637 CarlaEngineNative::_set_state,
2638 CarlaEngineNative::_dispatcher,
2639 /* _render_inline_dsplay */ nullptr,
2640 /* cvIns */ 0,
2641 /* cvOuts */ 0,
2642 /* _get_buffer_port_name */ nullptr,
2643 /* _get_buffer_port_range */ nullptr,
2644 /* ui_width */ kUiWidth,
2645 /* ui_height */ kUiHeight
2648 static const NativePluginDescriptor carlaPatchbay16Desc = {
2649 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2650 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2651 |NATIVE_PLUGIN_HAS_UI
2652 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2653 |NATIVE_PLUGIN_USES_STATE
2654 |NATIVE_PLUGIN_USES_TIME
2655 |NATIVE_PLUGIN_USES_UI_SIZE),
2656 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2657 /* audioIns */ 16,
2658 /* audioOuts */ 16,
2659 /* midiIns */ 1,
2660 /* midiOuts */ 1,
2661 /* paramIns */ kNumInParams,
2662 /* paramOuts */ kNumOutParams,
2663 /* name */ "Carla-Patchbay (16chan)",
2664 /* label */ "carlapatchbay16",
2665 /* maker */ "falkTX",
2666 /* copyright */ "GNU GPL v2+",
2667 CarlaEngineNative::_instantiatePatchbay16,
2668 CarlaEngineNative::_cleanup,
2669 CarlaEngineNative::_get_parameter_count,
2670 CarlaEngineNative::_get_parameter_info,
2671 CarlaEngineNative::_get_parameter_value,
2672 /* _get_midi_program_count */ nullptr,
2673 /* _get_midi_program_info */ nullptr,
2674 CarlaEngineNative::_set_parameter_value,
2675 /* _set_midi_program */ nullptr,
2676 /* _set_custom_data */ nullptr,
2677 #ifndef CARLA_ENGINE_WITHOUT_UI
2678 CarlaEngineNative::_ui_show,
2679 #else
2680 nullptr,
2681 #endif
2682 CarlaEngineNative::_ui_idle,
2683 CarlaEngineNative::_ui_set_parameter_value,
2684 /* _ui_set_midi_program */ nullptr,
2685 /* _ui_set_custom_data */ nullptr,
2686 CarlaEngineNative::_activate,
2687 CarlaEngineNative::_deactivate,
2688 CarlaEngineNative::_process,
2689 CarlaEngineNative::_get_state,
2690 CarlaEngineNative::_set_state,
2691 CarlaEngineNative::_dispatcher,
2692 /* _render_inline_dsplay */ nullptr,
2693 /* cvIns */ 0,
2694 /* cvOuts */ 0,
2695 /* _get_buffer_port_name */ nullptr,
2696 /* _get_buffer_port_range */ nullptr,
2697 /* ui_width */ kUiWidth,
2698 /* ui_height */ kUiHeight
2701 static const NativePluginDescriptor carlaPatchbay32Desc = {
2702 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2703 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2704 |NATIVE_PLUGIN_HAS_UI
2705 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2706 |NATIVE_PLUGIN_USES_STATE
2707 |NATIVE_PLUGIN_USES_TIME
2708 |NATIVE_PLUGIN_USES_UI_SIZE),
2709 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2710 /* audioIns */ 32,
2711 /* audioOuts */ 32,
2712 /* midiIns */ 1,
2713 /* midiOuts */ 1,
2714 /* paramIns */ kNumInParams,
2715 /* paramOuts */ kNumOutParams,
2716 /* name */ "Carla-Patchbay (32chan)",
2717 /* label */ "carlapatchbay32",
2718 /* maker */ "falkTX",
2719 /* copyright */ "GNU GPL v2+",
2720 CarlaEngineNative::_instantiatePatchbay32,
2721 CarlaEngineNative::_cleanup,
2722 CarlaEngineNative::_get_parameter_count,
2723 CarlaEngineNative::_get_parameter_info,
2724 CarlaEngineNative::_get_parameter_value,
2725 /* _get_midi_program_count */ nullptr,
2726 /* _get_midi_program_info */ nullptr,
2727 CarlaEngineNative::_set_parameter_value,
2728 /* _set_midi_program */ nullptr,
2729 /* _set_custom_data */ nullptr,
2730 #ifndef CARLA_ENGINE_WITHOUT_UI
2731 CarlaEngineNative::_ui_show,
2732 #else
2733 nullptr,
2734 #endif
2735 CarlaEngineNative::_ui_idle,
2736 CarlaEngineNative::_ui_set_parameter_value,
2737 /* _ui_set_midi_program */ nullptr,
2738 /* _ui_set_custom_data */ nullptr,
2739 CarlaEngineNative::_activate,
2740 CarlaEngineNative::_deactivate,
2741 CarlaEngineNative::_process,
2742 CarlaEngineNative::_get_state,
2743 CarlaEngineNative::_set_state,
2744 CarlaEngineNative::_dispatcher,
2745 /* _render_inline_dsplay */ nullptr,
2746 /* cvIns */ 0,
2747 /* cvOuts */ 0,
2748 /* _get_buffer_port_name */ nullptr,
2749 /* _get_buffer_port_range */ nullptr,
2750 /* ui_width */ kUiWidth,
2751 /* ui_height */ kUiHeight
2754 static const NativePluginDescriptor carlaPatchbay64Desc = {
2755 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2756 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2757 |NATIVE_PLUGIN_HAS_UI
2758 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2759 |NATIVE_PLUGIN_USES_STATE
2760 |NATIVE_PLUGIN_USES_TIME
2761 |NATIVE_PLUGIN_USES_UI_SIZE),
2762 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2763 /* audioIns */ 64,
2764 /* audioOuts */ 64,
2765 /* midiIns */ 1,
2766 /* midiOuts */ 1,
2767 /* paramIns */ kNumInParams,
2768 /* paramOuts */ kNumOutParams,
2769 /* name */ "Carla-Patchbay (64chan)",
2770 /* label */ "carlapatchbay64",
2771 /* maker */ "falkTX",
2772 /* copyright */ "GNU GPL v2+",
2773 CarlaEngineNative::_instantiatePatchbay64,
2774 CarlaEngineNative::_cleanup,
2775 CarlaEngineNative::_get_parameter_count,
2776 CarlaEngineNative::_get_parameter_info,
2777 CarlaEngineNative::_get_parameter_value,
2778 /* _get_midi_program_count */ nullptr,
2779 /* _get_midi_program_info */ nullptr,
2780 CarlaEngineNative::_set_parameter_value,
2781 /* _set_midi_program */ nullptr,
2782 /* _set_custom_data */ nullptr,
2783 #ifndef CARLA_ENGINE_WITHOUT_UI
2784 CarlaEngineNative::_ui_show,
2785 #else
2786 nullptr,
2787 #endif
2788 CarlaEngineNative::_ui_idle,
2789 CarlaEngineNative::_ui_set_parameter_value,
2790 /* _ui_set_midi_program */ nullptr,
2791 /* _ui_set_custom_data */ nullptr,
2792 CarlaEngineNative::_activate,
2793 CarlaEngineNative::_deactivate,
2794 CarlaEngineNative::_process,
2795 CarlaEngineNative::_get_state,
2796 CarlaEngineNative::_set_state,
2797 CarlaEngineNative::_dispatcher,
2798 /* _render_inline_dsplay */ nullptr,
2799 /* cvIns */ 0,
2800 /* cvOuts */ 0,
2801 /* _get_buffer_port_name */ nullptr,
2802 /* _get_buffer_port_range */ nullptr,
2803 /* ui_width */ kUiWidth,
2804 /* ui_height */ kUiHeight
2807 static const NativePluginDescriptor carlaPatchbayCVDesc = {
2808 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2809 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2810 |NATIVE_PLUGIN_HAS_UI
2811 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2812 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2813 |NATIVE_PLUGIN_USES_STATE
2814 |NATIVE_PLUGIN_USES_TIME
2815 |NATIVE_PLUGIN_USES_UI_SIZE),
2816 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2817 /* audioIns */ 2,
2818 /* audioOuts */ 2,
2819 /* midiIns */ 1,
2820 /* midiOuts */ 1,
2821 /* paramIns */ kNumInParams,
2822 /* paramOuts */ kNumOutParams,
2823 /* name */ "Carla-Patchbay (CV)",
2824 /* label */ "carlapatchbaycv",
2825 /* maker */ "falkTX",
2826 /* copyright */ "GNU GPL v2+",
2827 CarlaEngineNative::_instantiatePatchbayCV,
2828 CarlaEngineNative::_cleanup,
2829 CarlaEngineNative::_get_parameter_count,
2830 CarlaEngineNative::_get_parameter_info,
2831 CarlaEngineNative::_get_parameter_value,
2832 /* _get_midi_program_count */ nullptr,
2833 /* _get_midi_program_info */ nullptr,
2834 CarlaEngineNative::_set_parameter_value,
2835 /* _set_midi_program */ nullptr,
2836 /* _set_custom_data */ nullptr,
2837 #ifndef CARLA_ENGINE_WITHOUT_UI
2838 CarlaEngineNative::_ui_show,
2839 #else
2840 nullptr,
2841 #endif
2842 CarlaEngineNative::_ui_idle,
2843 CarlaEngineNative::_ui_set_parameter_value,
2844 /* _ui_set_midi_program */ nullptr,
2845 /* _ui_set_custom_data */ nullptr,
2846 CarlaEngineNative::_activate,
2847 CarlaEngineNative::_deactivate,
2848 CarlaEngineNative::_process,
2849 CarlaEngineNative::_get_state,
2850 CarlaEngineNative::_set_state,
2851 CarlaEngineNative::_dispatcher,
2852 /* _render_inline_dsplay */ nullptr,
2853 /* cvIns */ 5,
2854 /* cvOuts */ 5,
2855 /* _get_buffer_port_name */ nullptr,
2856 /* _get_buffer_port_range */ nullptr,
2857 /* ui_width */ kUiWidth,
2858 /* ui_height */ kUiHeight
2861 static const NativePluginDescriptor carlaPatchbayCV8Desc = {
2862 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2863 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2864 |NATIVE_PLUGIN_HAS_UI
2865 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2866 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2867 |NATIVE_PLUGIN_USES_STATE
2868 |NATIVE_PLUGIN_USES_TIME
2869 |NATIVE_PLUGIN_USES_UI_SIZE),
2870 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2871 /* audioIns */ 2,
2872 /* audioOuts */ 2,
2873 /* midiIns */ 1,
2874 /* midiOuts */ 1,
2875 /* paramIns */ kNumInParams,
2876 /* paramOuts */ kNumOutParams,
2877 /* name */ "Carla-Patchbay (CV8)",
2878 /* label */ "carlapatchbaycv",
2879 /* maker */ "falkTX",
2880 /* copyright */ "GNU GPL v2+",
2881 CarlaEngineNative::_instantiatePatchbayCV8,
2882 CarlaEngineNative::_cleanup,
2883 CarlaEngineNative::_get_parameter_count,
2884 CarlaEngineNative::_get_parameter_info,
2885 CarlaEngineNative::_get_parameter_value,
2886 /* _get_midi_program_count */ nullptr,
2887 /* _get_midi_program_info */ nullptr,
2888 CarlaEngineNative::_set_parameter_value,
2889 /* _set_midi_program */ nullptr,
2890 /* _set_custom_data */ nullptr,
2891 #ifndef CARLA_ENGINE_WITHOUT_UI
2892 CarlaEngineNative::_ui_show,
2893 #else
2894 nullptr,
2895 #endif
2896 CarlaEngineNative::_ui_idle,
2897 CarlaEngineNative::_ui_set_parameter_value,
2898 /* _ui_set_midi_program */ nullptr,
2899 /* _ui_set_custom_data */ nullptr,
2900 CarlaEngineNative::_activate,
2901 CarlaEngineNative::_deactivate,
2902 CarlaEngineNative::_process,
2903 CarlaEngineNative::_get_state,
2904 CarlaEngineNative::_set_state,
2905 CarlaEngineNative::_dispatcher,
2906 /* _render_inline_dsplay */ nullptr,
2907 /* cvIns */ 8,
2908 /* cvOuts */ 8,
2909 /* _get_buffer_port_name */ nullptr,
2910 /* _get_buffer_port_range */ nullptr,
2911 /* ui_width */ kUiWidth,
2912 /* ui_height */ kUiHeight
2915 static const NativePluginDescriptor carlaPatchbayCV32Desc = {
2916 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2917 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2918 |NATIVE_PLUGIN_HAS_UI
2919 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2920 |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
2921 |NATIVE_PLUGIN_USES_STATE
2922 |NATIVE_PLUGIN_USES_TIME
2923 |NATIVE_PLUGIN_USES_UI_SIZE),
2924 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2925 /* audioIns */ 64,
2926 /* audioOuts */ 64,
2927 /* midiIns */ 1,
2928 /* midiOuts */ 1,
2929 /* paramIns */ kNumInParams,
2930 /* paramOuts */ kNumOutParams,
2931 /* name */ "Carla-Patchbay (CV32)",
2932 /* label */ "carlapatchbaycv",
2933 /* maker */ "falkTX",
2934 /* copyright */ "GNU GPL v2+",
2935 CarlaEngineNative::_instantiatePatchbayCV32,
2936 CarlaEngineNative::_cleanup,
2937 CarlaEngineNative::_get_parameter_count,
2938 CarlaEngineNative::_get_parameter_info,
2939 CarlaEngineNative::_get_parameter_value,
2940 /* _get_midi_program_count */ nullptr,
2941 /* _get_midi_program_info */ nullptr,
2942 CarlaEngineNative::_set_parameter_value,
2943 /* _set_midi_program */ nullptr,
2944 /* _set_custom_data */ nullptr,
2945 #ifndef CARLA_ENGINE_WITHOUT_UI
2946 CarlaEngineNative::_ui_show,
2947 #else
2948 nullptr,
2949 #endif
2950 CarlaEngineNative::_ui_idle,
2951 CarlaEngineNative::_ui_set_parameter_value,
2952 /* _ui_set_midi_program */ nullptr,
2953 /* _ui_set_custom_data */ nullptr,
2954 CarlaEngineNative::_activate,
2955 CarlaEngineNative::_deactivate,
2956 CarlaEngineNative::_process,
2957 CarlaEngineNative::_get_state,
2958 CarlaEngineNative::_set_state,
2959 CarlaEngineNative::_dispatcher,
2960 /* _render_inline_dsplay */ nullptr,
2961 /* cvIns */ 32,
2962 /* cvOuts */ 32,
2963 /* _get_buffer_port_name */ nullptr,
2964 /* _get_buffer_port_range */ nullptr,
2965 /* ui_width */ kUiWidth,
2966 /* ui_height */ kUiHeight
2969 static const NativePluginDescriptor carlaPatchbayOBS = {
2970 /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
2971 /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
2972 |NATIVE_PLUGIN_HAS_UI
2973 |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
2974 |NATIVE_PLUGIN_USES_STATE
2975 |NATIVE_PLUGIN_USES_TIME
2976 |NATIVE_PLUGIN_USES_UI_SIZE),
2977 /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
2978 /* audioIns */ 8,
2979 /* audioOuts */ 8,
2980 /* midiIns */ 0,
2981 /* midiOuts */ 0,
2982 /* paramIns */ kNumInParams,
2983 /* paramOuts */ kNumOutParams,
2984 /* name */ "Carla-Patchbay (OBS)",
2985 /* label */ "carlapatchbayOBS",
2986 /* maker */ "falkTX",
2987 /* copyright */ "GNU GPL v2+",
2988 CarlaEngineNative::_instantiatePatchbayOBS,
2989 CarlaEngineNative::_cleanup,
2990 CarlaEngineNative::_get_parameter_count,
2991 CarlaEngineNative::_get_parameter_info,
2992 CarlaEngineNative::_get_parameter_value,
2993 /* _get_midi_program_count */ nullptr,
2994 /* _get_midi_program_info */ nullptr,
2995 CarlaEngineNative::_set_parameter_value,
2996 /* _set_midi_program */ nullptr,
2997 /* _set_custom_data */ nullptr,
2998 #ifndef CARLA_ENGINE_WITHOUT_UI
2999 CarlaEngineNative::_ui_show,
3000 #else
3001 nullptr,
3002 #endif
3003 CarlaEngineNative::_ui_idle,
3004 CarlaEngineNative::_ui_set_parameter_value,
3005 /* _ui_set_midi_program */ nullptr,
3006 /* _ui_set_custom_data */ nullptr,
3007 CarlaEngineNative::_activate,
3008 CarlaEngineNative::_deactivate,
3009 CarlaEngineNative::_process,
3010 CarlaEngineNative::_get_state,
3011 CarlaEngineNative::_set_state,
3012 CarlaEngineNative::_dispatcher,
3013 /* _render_inline_dsplay */ nullptr,
3014 /* cvIns */ 0,
3015 /* cvOuts */ 0,
3016 /* _get_buffer_port_name */ nullptr,
3017 /* _get_buffer_port_range */ nullptr,
3018 /* ui_width */ kUiWidth,
3019 /* ui_height */ kUiHeight
3022 CARLA_BACKEND_END_NAMESPACE
3024 // -----------------------------------------------------------------------
3026 #ifndef STATIC_PLUGIN_TARGET
3028 CARLA_API_EXPORT
3029 void carla_register_native_plugin_carla();
3031 void carla_register_native_plugin_carla()
3033 CARLA_BACKEND_USE_NAMESPACE;
3034 carla_register_native_plugin(&carlaRackDesc);
3035 carla_register_native_plugin(&carlaRackNoMidiOutDesc);
3036 carla_register_native_plugin(&carlaPatchbayDesc);
3037 carla_register_native_plugin(&carlaPatchbay3sDesc);
3038 carla_register_native_plugin(&carlaPatchbay16Desc);
3039 carla_register_native_plugin(&carlaPatchbay32Desc);
3040 carla_register_native_plugin(&carlaPatchbay64Desc);
3041 carla_register_native_plugin(&carlaPatchbayCVDesc);
3044 #endif
3046 // -----------------------------------------------------------------------
3048 const NativePluginDescriptor* carla_get_native_rack_plugin()
3050 CARLA_BACKEND_USE_NAMESPACE;
3051 return &carlaRackDesc;
3054 const NativePluginDescriptor* carla_get_native_patchbay_plugin()
3056 CARLA_BACKEND_USE_NAMESPACE;
3057 return &carlaPatchbayDesc;
3060 const NativePluginDescriptor* carla_get_native_patchbay16_plugin()
3062 CARLA_BACKEND_USE_NAMESPACE;
3063 return &carlaPatchbay16Desc;
3066 const NativePluginDescriptor* carla_get_native_patchbay32_plugin()
3068 CARLA_BACKEND_USE_NAMESPACE;
3069 return &carlaPatchbay32Desc;
3072 const NativePluginDescriptor* carla_get_native_patchbay64_plugin()
3074 CARLA_BACKEND_USE_NAMESPACE;
3075 return &carlaPatchbay64Desc;
3078 const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin()
3080 CARLA_BACKEND_USE_NAMESPACE;
3081 return &carlaPatchbayCVDesc;
3084 const NativePluginDescriptor* carla_get_native_patchbay_cv8_plugin()
3086 CARLA_BACKEND_USE_NAMESPACE;
3087 return &carlaPatchbayCV8Desc;
3090 const NativePluginDescriptor* carla_get_native_patchbay_cv32_plugin()
3092 CARLA_BACKEND_USE_NAMESPACE;
3093 return &carlaPatchbayCV32Desc;
3096 const NativePluginDescriptor* carla_get_native_patchbay_obs_plugin()
3098 CARLA_BACKEND_USE_NAMESPACE;
3099 return &carlaPatchbayOBS;
3102 // -----------------------------------------------------------------------
3103 // Extra stuff for linking purposes
3105 #ifdef CARLA_PLUGIN_BUILD
3107 CARLA_BACKEND_START_NAMESPACE
3109 namespace EngineInit {
3111 #ifdef HAVE_JACK
3112 CarlaEngine* newJack() { return nullptr; }
3113 #endif
3115 #ifdef USING_JUCE_AUDIO_DEVICES
3116 CarlaEngine* newJuce(const AudioApi) { return nullptr; }
3117 uint getJuceApiCount() { return 0; }
3118 const char* getJuceApiName(const uint) { return nullptr; }
3119 const char* const* getJuceApiDeviceNames(const uint) { return nullptr; }
3120 const EngineDriverDeviceInfo* getJuceDeviceInfo(const uint, const char* const) { return nullptr; }
3121 bool showJuceDeviceControlPanel(const uint, const char* const) { return false; }
3122 #endif
3124 #ifdef USING_RTAUDIO
3125 CarlaEngine* newRtAudio(const AudioApi) { return nullptr; }
3126 uint getRtAudioApiCount() { return 0; }
3127 const char* getRtAudioApiName(const uint) { return nullptr; }
3128 const char* const* getRtAudioApiDeviceNames(const uint) { return nullptr; }
3129 const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const uint, const char* const) { return nullptr; }
3130 #endif
3132 #ifdef HAVE_SDL
3133 CarlaEngine* newSDL() { return nullptr; }
3134 const char* const* getSDLDeviceNames() { return nullptr; }
3135 #endif
3139 CARLA_BACKEND_END_NAMESPACE
3141 #define CARLA_PLUGIN_UI_CLASS_PREFIX Plugin
3142 #include "CarlaPluginUI.cpp"
3143 # undef CARLA_PLUGIN_UI_CLASS_PREFIX
3144 #include "CarlaDssiUtils.cpp"
3145 #include "CarlaMacUtils.cpp"
3146 #include "CarlaPatchbayUtils.cpp"
3147 #include "CarlaPipeUtils.cpp"
3148 #include "CarlaProcessUtils.cpp"
3149 #include "CarlaStateUtils.cpp"
3151 #endif /* CARLA_PLUGIN_BUILD */
3153 // -----------------------------------------------------------------------