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