Implement LV2 ControlInputPort change request feature
[carla.git] / source / backend / plugin / CarlaPluginLV2.cpp
blob5c56ca516cd58cf0961f36b59806229ec7f957ed
1 /*
2 * Carla LV2 Plugin
3 * Copyright (C) 2011-2022 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 // testing macros
19 // #define LV2_UIS_ONLY_BRIDGES
20 // #define LV2_UIS_ONLY_INPROCESS
22 #include "CarlaPluginInternal.hpp"
23 #include "CarlaEngine.hpp"
25 #include "CarlaLv2Utils.hpp"
27 #include "CarlaBackendUtils.hpp"
28 #include "CarlaBase64Utils.hpp"
29 #include "CarlaEngineUtils.hpp"
30 #include "CarlaPipeUtils.hpp"
31 #include "CarlaPluginUI.hpp"
32 #include "CarlaScopeUtils.hpp"
33 #include "Lv2AtomRingBuffer.hpp"
35 #include "../modules/lilv/config/lilv_config.h"
37 extern "C" {
38 #include "rtmempool/rtmempool-lv2.h"
41 #include "water/files/File.h"
42 #include "water/misc/Time.h"
44 #ifdef CARLA_OS_MAC
45 # include "CarlaMacUtils.hpp"
46 # if defined(CARLA_OS_64BIT) && defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
47 # define ADAPT_FOR_APPLE_SILLICON
48 # include "CarlaBinaryUtils.hpp"
49 # endif
50 #endif
52 #ifdef CARLA_OS_WASM
53 # define LV2_UIS_ONLY_INPROCESS
54 #endif
56 #include <string>
57 #include <vector>
59 using water::File;
61 #define URI_CARLA_ATOM_WORKER_IN "http://kxstudio.sf.net/ns/carla/atomWorkerIn"
62 #define URI_CARLA_ATOM_WORKER_RESP "http://kxstudio.sf.net/ns/carla/atomWorkerResp"
63 #define URI_CARLA_PARAMETER_CHANGE "http://kxstudio.sf.net/ns/carla/parameterChange"
65 CARLA_BACKEND_START_NAMESPACE
67 // -------------------------------------------------------------------------------------------------------------------
68 // Fallback data
70 static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };
71 static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
72 static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
73 static const char* const kUnmapFallback = "urn:null";
75 // -------------------------------------------------------------------------------------------------------------------
77 // Maximum default buffer size
78 const uint MAX_DEFAULT_BUFFER_SIZE = 8192; // 0x2000
80 // Extra Plugin Hints
81 const uint PLUGIN_HAS_EXTENSION_OPTIONS = 0x01000;
82 const uint PLUGIN_HAS_EXTENSION_PROGRAMS = 0x02000;
83 const uint PLUGIN_HAS_EXTENSION_STATE = 0x04000;
84 const uint PLUGIN_HAS_EXTENSION_WORKER = 0x08000;
85 const uint PLUGIN_HAS_EXTENSION_INLINE_DISPLAY = 0x10000;
86 const uint PLUGIN_HAS_EXTENSION_MIDNAM = 0x20000;
88 // LV2 Event Data/Types
89 const uint CARLA_EVENT_DATA_ATOM = 0x01;
90 const uint CARLA_EVENT_DATA_EVENT = 0x02;
91 const uint CARLA_EVENT_DATA_MIDI_LL = 0x04;
92 const uint CARLA_EVENT_TYPE_MESSAGE = 0x10; // unused
93 const uint CARLA_EVENT_TYPE_MIDI = 0x20;
94 const uint CARLA_EVENT_TYPE_TIME = 0x40;
96 // LV2 URI Map Ids
97 enum CarlaLv2URIDs {
98 kUridNull = 0,
99 kUridAtomBlank,
100 kUridAtomBool,
101 kUridAtomChunk,
102 kUridAtomDouble,
103 kUridAtomEvent,
104 kUridAtomFloat,
105 kUridAtomInt,
106 kUridAtomLiteral,
107 kUridAtomLong,
108 kUridAtomNumber,
109 kUridAtomObject,
110 kUridAtomPath,
111 kUridAtomProperty,
112 kUridAtomResource,
113 kUridAtomSequence,
114 kUridAtomSound,
115 kUridAtomString,
116 kUridAtomTuple,
117 kUridAtomURI,
118 kUridAtomURID,
119 kUridAtomVector,
120 kUridAtomTransferAtom,
121 kUridAtomTransferEvent,
122 kUridBufMaxLength,
123 kUridBufMinLength,
124 kUridBufNominalLength,
125 kUridBufSequenceSize,
126 kUridLogError,
127 kUridLogNote,
128 kUridLogTrace,
129 kUridLogWarning,
130 kUridPatchSet,
131 kUridPatchProperty,
132 kUridPatchSubject,
133 kUridPatchValue,
134 // time base type
135 kUridTimePosition,
136 // time values
137 kUridTimeBar,
138 kUridTimeBarBeat,
139 kUridTimeBeat,
140 kUridTimeBeatUnit,
141 kUridTimeBeatsPerBar,
142 kUridTimeBeatsPerMinute,
143 kUridTimeFrame,
144 kUridTimeFramesPerSecond,
145 kUridTimeSpeed,
146 kUridTimeTicksPerBeat,
147 kUridMidiEvent,
148 kUridParamSampleRate,
149 // ui stuff
150 kUridBackgroundColor,
151 kUridForegroundColor,
152 #ifndef CARLA_OS_MAC
153 kUridScaleFactor,
154 #endif
155 kUridWindowTitle,
156 // custom carla props
157 kUridCarlaAtomWorkerIn,
158 kUridCarlaAtomWorkerResp,
159 kUridCarlaParameterChange,
160 kUridCarlaTransientWindowId,
161 // count
162 kUridCount
165 // LV2 Feature Ids
166 enum CarlaLv2Features {
167 // DSP features
168 kFeatureIdBufSizeBounded = 0,
169 kFeatureIdBufSizeFixed,
170 kFeatureIdBufSizePowerOf2,
171 kFeatureIdEvent,
172 kFeatureIdHardRtCapable,
173 kFeatureIdInPlaceBroken,
174 kFeatureIdIsLive,
175 kFeatureIdLogs,
176 kFeatureIdOptions,
177 kFeatureIdPrograms,
178 kFeatureIdResizePort,
179 kFeatureIdRtMemPool,
180 kFeatureIdRtMemPoolOld,
181 kFeatureIdStateFreePath,
182 kFeatureIdStateMakePath,
183 kFeatureIdStateMapPath,
184 kFeatureIdStrictBounds,
185 kFeatureIdUriMap,
186 kFeatureIdUridMap,
187 kFeatureIdUridUnmap,
188 kFeatureIdWorker,
189 kFeatureIdInlineDisplay,
190 kFeatureIdMidnam,
191 kFeatureIdCtrlInPortChangeReq,
192 kFeatureCountPlugin,
193 // UI features
194 kFeatureIdUiDataAccess = kFeatureCountPlugin,
195 kFeatureIdUiInstanceAccess,
196 kFeatureIdUiIdleInterface,
197 kFeatureIdUiFixedSize,
198 kFeatureIdUiMakeResident,
199 kFeatureIdUiMakeResident2,
200 kFeatureIdUiNoUserResize,
201 kFeatureIdUiParent,
202 kFeatureIdUiPortMap,
203 kFeatureIdUiPortSubscribe,
204 kFeatureIdUiResize,
205 kFeatureIdUiRequestValue,
206 kFeatureIdUiTouch,
207 kFeatureIdExternalUi,
208 kFeatureIdExternalUiOld,
209 kFeatureCountAll
212 // LV2 Feature Ids (special state handlers)
213 enum CarlaLv2StateFeatures {
214 kStateFeatureIdFreePath,
215 kStateFeatureIdMakePath,
216 kStateFeatureIdMapPath,
217 kStateFeatureIdWorker,
218 kStateFeatureCountAll
221 // -------------------------------------------------------------------------------------------------------------------
223 struct Lv2EventData {
224 uint32_t type;
225 uint32_t rindex;
226 CarlaEngineEventPort* port;
228 union {
229 LV2_Atom_Buffer* atom;
230 LV2_Event_Buffer* event;
231 LV2_MIDI midi;
234 Lv2EventData() noexcept
235 : type(0x0),
236 rindex(0),
237 port(nullptr) {}
239 ~Lv2EventData() noexcept
241 if (port != nullptr)
243 delete port;
244 port = nullptr;
247 const uint32_t rtype = type;
248 type = 0x0;
250 if (rtype & CARLA_EVENT_DATA_ATOM)
252 CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
254 std::free(atom);
255 atom = nullptr;
257 else if (rtype & CARLA_EVENT_DATA_EVENT)
259 CARLA_SAFE_ASSERT_RETURN(event != nullptr,);
261 std::free(event);
262 event = nullptr;
264 else if (rtype & CARLA_EVENT_DATA_MIDI_LL)
266 CARLA_SAFE_ASSERT_RETURN(midi.data != nullptr,);
268 delete[] midi.data;
269 midi.data = nullptr;
273 CARLA_DECLARE_NON_COPYABLE(Lv2EventData)
276 union LV2EventIters {
277 LV2_Atom_Buffer_Iterator atom;
278 LV2_Event_Iterator event;
279 LV2_MIDIState midiState;
282 struct CarlaPluginLV2EventData {
283 uint32_t count;
284 Lv2EventData* data;
285 LV2EventIters* iters;
286 Lv2EventData* ctrl; // default port, either this->data[x] or pData->portIn/Out
287 uint32_t ctrlIndex;
289 CarlaPluginLV2EventData() noexcept
290 : count(0),
291 data(nullptr),
292 iters(nullptr),
293 ctrl(nullptr),
294 ctrlIndex(0) {}
296 ~CarlaPluginLV2EventData() noexcept
298 CARLA_SAFE_ASSERT_INT(count == 0, count);
299 CARLA_SAFE_ASSERT(data == nullptr);
300 CARLA_SAFE_ASSERT(iters == nullptr);
301 CARLA_SAFE_ASSERT(ctrl == nullptr);
302 CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
305 void createNew(const uint32_t newCount)
307 CARLA_SAFE_ASSERT_INT(count == 0, count);
308 CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
309 CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
310 CARLA_SAFE_ASSERT_RETURN(iters == nullptr,);
311 CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,);
312 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
314 data = new Lv2EventData[newCount];
315 iters = new LV2EventIters[newCount];
316 count = newCount;
318 ctrl = nullptr;
319 ctrlIndex = 0;
322 void clear(CarlaEngineEventPort* const portToIgnore) noexcept
324 if (data != nullptr)
326 for (uint32_t i=0; i < count; ++i)
328 if (data[i].port != nullptr)
330 if (data[i].port != portToIgnore)
331 delete data[i].port;
332 data[i].port = nullptr;
336 delete[] data;
337 data = nullptr;
340 if (iters != nullptr)
342 delete[] iters;
343 iters = nullptr;
346 count = 0;
348 ctrl = nullptr;
349 ctrlIndex = 0;
352 void initBuffers() const noexcept
354 for (uint32_t i=0; i < count; ++i)
356 if (data[i].port != nullptr && (ctrl == nullptr || data[i].port != ctrl->port))
357 data[i].port->initBuffer();
361 CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2EventData)
364 // -------------------------------------------------------------------------------------------------------------------
366 struct CarlaPluginLV2Options {
367 enum OptIndex {
368 MaxBlockLenth = 0,
369 MinBlockLenth,
370 NominalBlockLenth,
371 SequenceSize,
372 SampleRate,
373 TransientWinId,
374 BackgroundColor,
375 ForegroundColor,
376 #ifndef CARLA_OS_MAC
377 ScaleFactor,
378 #endif
379 WindowTitle,
380 Null,
381 Count
384 int maxBufferSize;
385 int minBufferSize;
386 int nominalBufferSize;
387 int sequenceSize;
388 float sampleRate;
389 int64_t transientWinId;
390 uint32_t bgColor;
391 uint32_t fgColor;
392 float uiScale;
393 const char* windowTitle;
394 LV2_Options_Option opts[Count];
396 CarlaPluginLV2Options() noexcept
397 : maxBufferSize(0),
398 minBufferSize(0),
399 nominalBufferSize(0),
400 sequenceSize(MAX_DEFAULT_BUFFER_SIZE),
401 sampleRate(0.0),
402 transientWinId(0),
403 bgColor(0x000000ff),
404 fgColor(0xffffffff),
405 uiScale(1.0f),
406 windowTitle(nullptr)
408 LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]);
409 optMaxBlockLenth.context = LV2_OPTIONS_INSTANCE;
410 optMaxBlockLenth.subject = 0;
411 optMaxBlockLenth.key = kUridBufMaxLength;
412 optMaxBlockLenth.size = sizeof(int);
413 optMaxBlockLenth.type = kUridAtomInt;
414 optMaxBlockLenth.value = &maxBufferSize;
416 LV2_Options_Option& optMinBlockLenth(opts[MinBlockLenth]);
417 optMinBlockLenth.context = LV2_OPTIONS_INSTANCE;
418 optMinBlockLenth.subject = 0;
419 optMinBlockLenth.key = kUridBufMinLength;
420 optMinBlockLenth.size = sizeof(int);
421 optMinBlockLenth.type = kUridAtomInt;
422 optMinBlockLenth.value = &minBufferSize;
424 LV2_Options_Option& optNominalBlockLenth(opts[NominalBlockLenth]);
425 optNominalBlockLenth.context = LV2_OPTIONS_INSTANCE;
426 optNominalBlockLenth.subject = 0;
427 optNominalBlockLenth.key = kUridBufNominalLength;
428 optNominalBlockLenth.size = sizeof(int);
429 optNominalBlockLenth.type = kUridAtomInt;
430 optNominalBlockLenth.value = &nominalBufferSize;
432 LV2_Options_Option& optSequenceSize(opts[SequenceSize]);
433 optSequenceSize.context = LV2_OPTIONS_INSTANCE;
434 optSequenceSize.subject = 0;
435 optSequenceSize.key = kUridBufSequenceSize;
436 optSequenceSize.size = sizeof(int);
437 optSequenceSize.type = kUridAtomInt;
438 optSequenceSize.value = &sequenceSize;
440 LV2_Options_Option& optBackgroundColor(opts[BackgroundColor]);
441 optBackgroundColor.context = LV2_OPTIONS_INSTANCE;
442 optBackgroundColor.subject = 0;
443 optBackgroundColor.key = kUridBackgroundColor;
444 optBackgroundColor.size = sizeof(int32_t);
445 optBackgroundColor.type = kUridAtomInt;
446 optBackgroundColor.value = &bgColor;
448 LV2_Options_Option& optForegroundColor(opts[ForegroundColor]);
449 optForegroundColor.context = LV2_OPTIONS_INSTANCE;
450 optForegroundColor.subject = 0;
451 optForegroundColor.key = kUridForegroundColor;
452 optForegroundColor.size = sizeof(int32_t);
453 optForegroundColor.type = kUridAtomInt;
454 optForegroundColor.value = &fgColor;
456 #ifndef CARLA_OS_MAC
457 LV2_Options_Option& optScaleFactor(opts[ScaleFactor]);
458 optScaleFactor.context = LV2_OPTIONS_INSTANCE;
459 optScaleFactor.subject = 0;
460 optScaleFactor.key = kUridScaleFactor;
461 optScaleFactor.size = sizeof(float);
462 optScaleFactor.type = kUridAtomFloat;
463 optScaleFactor.value = &uiScale;
464 #endif
466 LV2_Options_Option& optSampleRate(opts[SampleRate]);
467 optSampleRate.context = LV2_OPTIONS_INSTANCE;
468 optSampleRate.subject = 0;
469 optSampleRate.key = kUridParamSampleRate;
470 optSampleRate.size = sizeof(float);
471 optSampleRate.type = kUridAtomFloat;
472 optSampleRate.value = &sampleRate;
474 LV2_Options_Option& optTransientWinId(opts[TransientWinId]);
475 optTransientWinId.context = LV2_OPTIONS_INSTANCE;
476 optTransientWinId.subject = 0;
477 optTransientWinId.key = kUridCarlaTransientWindowId;
478 optTransientWinId.size = sizeof(int64_t);
479 optTransientWinId.type = kUridAtomLong;
480 optTransientWinId.value = &transientWinId;
482 LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
483 optWindowTitle.context = LV2_OPTIONS_INSTANCE;
484 optWindowTitle.subject = 0;
485 optWindowTitle.key = kUridWindowTitle;
486 optWindowTitle.size = 0;
487 optWindowTitle.type = kUridAtomString;
488 optWindowTitle.value = nullptr;
490 LV2_Options_Option& optNull(opts[Null]);
491 optNull.context = LV2_OPTIONS_INSTANCE;
492 optNull.subject = 0;
493 optNull.key = kUridNull;
494 optNull.size = 0;
495 optNull.type = kUridNull;
496 optNull.value = nullptr;
499 ~CarlaPluginLV2Options() noexcept
501 LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
503 optWindowTitle.size = 0;
504 optWindowTitle.value = nullptr;
506 if (windowTitle != nullptr)
508 std::free(const_cast<char*>(windowTitle));
509 windowTitle = nullptr;
513 CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2Options);
516 #ifndef LV2_UIS_ONLY_INPROCESS
517 // -------------------------------------------------------------------------------------------------------------------
519 class CarlaPluginLV2;
521 class CarlaPipeServerLV2 : public CarlaPipeServer
523 public:
524 enum UiState {
525 UiNone = 0,
526 UiHide,
527 UiShow,
528 UiCrashed
531 CarlaPipeServerLV2(CarlaEngine* const engine, CarlaPluginLV2* const plugin)
532 : kEngine(engine),
533 kPlugin(plugin),
534 fFilename(),
535 fPluginURI(),
536 fUiURI(),
537 fUiState(UiNone) {}
539 ~CarlaPipeServerLV2() noexcept override
541 CARLA_SAFE_ASSERT_INT(fUiState == UiNone, fUiState);
544 UiState getAndResetUiState() noexcept
546 const UiState uiState(fUiState);
547 fUiState = UiNone;
548 return uiState;
551 void setData(const char* const filename, const char* const pluginURI, const char* const uiURI) noexcept
553 fFilename = filename;
554 fPluginURI = pluginURI;
555 fUiURI = uiURI;
558 bool startPipeServer(const int size) noexcept
560 char sampleRateStr[32];
562 const CarlaScopedLocale csl;
563 std::snprintf(sampleRateStr, 31, "%.12g", kEngine->getSampleRate());
565 sampleRateStr[31] = '\0';
567 const ScopedEngineEnvironmentLocker _seel(kEngine);
568 const CarlaScopedEnvVar _sev1("LV2_PATH", kEngine->getOptions().pathLV2);
569 #ifdef CARLA_OS_LINUX
570 const CarlaScopedEnvVar _sev2("LD_PRELOAD", nullptr);
571 #endif
572 carla_setenv("CARLA_SAMPLE_RATE", sampleRateStr);
574 return CarlaPipeServer::startPipeServer(fFilename, fPluginURI, fUiURI, size);
577 void writeUiTitleMessage(const char* const title) const noexcept
579 CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
581 const CarlaMutexLocker cml(getPipeLock());
583 if (! _writeMsgBuffer("uiTitle\n", 8))
584 return;
585 if (! writeAndFixMessage(title))
586 return;
588 syncMessages();
591 protected:
592 // returns true if msg was handled
593 bool msgReceived(const char* const msg) noexcept override;
595 private:
596 CarlaEngine* const kEngine;
597 CarlaPluginLV2* const kPlugin;
599 CarlaString fFilename;
600 CarlaString fPluginURI;
601 CarlaString fUiURI;
602 UiState fUiState;
604 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServerLV2)
607 // -------------------------------------------------------------------------------------------------------------------
608 #endif
610 static void initAtomForge(LV2_Atom_Forge& atomForge) noexcept
612 carla_zeroStruct(atomForge);
614 atomForge.Bool = kUridAtomBool;
615 atomForge.Chunk = kUridAtomChunk;
616 atomForge.Double = kUridAtomDouble;
617 atomForge.Float = kUridAtomFloat;
618 atomForge.Int = kUridAtomInt;
619 atomForge.Literal = kUridAtomLiteral;
620 atomForge.Long = kUridAtomLong;
621 atomForge.Object = kUridAtomObject;
622 atomForge.Path = kUridAtomPath;
623 atomForge.Property = kUridAtomProperty;
624 atomForge.Sequence = kUridAtomSequence;
625 atomForge.String = kUridAtomString;
626 atomForge.Tuple = kUridAtomTuple;
627 atomForge.URI = kUridAtomURI;
628 atomForge.URID = kUridAtomURID;
629 atomForge.Vector = kUridAtomVector;
631 #if defined(__clang__)
632 # pragma clang diagnostic push
633 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
634 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
635 # pragma GCC diagnostic push
636 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
637 #endif
638 atomForge.Blank = kUridAtomBlank;
639 atomForge.Resource = kUridAtomResource;
640 #if defined(__clang__)
641 # pragma clang diagnostic pop
642 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
643 # pragma GCC diagnostic pop
644 #endif
647 // -------------------------------------------------------------------------------------------------------------------
649 class CarlaPluginLV2 : public CarlaPlugin,
650 private CarlaPluginUI::Callback
652 public:
653 CarlaPluginLV2(CarlaEngine* const engine, const uint id)
654 : CarlaPlugin(engine, id),
655 fHandle(nullptr),
656 fHandle2(nullptr),
657 fDescriptor(nullptr),
658 fRdfDescriptor(nullptr),
659 fAudioInBuffers(nullptr),
660 fAudioOutBuffers(nullptr),
661 fCvInBuffers(nullptr),
662 fCvOutBuffers(nullptr),
663 fParamBuffers(nullptr),
664 fHasLoadDefaultState(false),
665 fHasThreadSafeRestore(false),
666 fNeedsFixedBuffers(false),
667 fNeedsUiClose(false),
668 fInlineDisplayNeedsRedraw(false),
669 fInlineDisplayLastRedrawTime(0),
670 fLatencyIndex(-1),
671 fStrictBounds(-1),
672 fAtomBufferEvIn(),
673 fAtomBufferUiOut(),
674 fAtomBufferWorkerIn(),
675 fAtomBufferWorkerResp(),
676 fAtomBufferUiOutTmpData(nullptr),
677 fAtomBufferWorkerInTmpData(nullptr),
678 fAtomBufferRealtime(nullptr),
679 fAtomBufferRealtimeSize(0),
680 fEventsIn(),
681 fEventsOut(),
682 fLv2Options(),
683 #ifndef LV2_UIS_ONLY_INPROCESS
684 fPipeServer(engine, this),
685 #endif
686 fCustomURIDs(kUridCount, std::string("urn:null")),
687 fFirstActive(true),
688 fLastStateChunk(nullptr),
689 fLastTimeInfo(),
690 fFilePathURI(),
691 fExt(),
692 fUI()
694 carla_debug("CarlaPluginLV2::CarlaPluginLV2(%p, %i)", engine, id);
695 CARLA_SAFE_ASSERT(fCustomURIDs.size() == kUridCount);
697 carla_zeroPointers(fFeatures, kFeatureCountAll+1);
698 carla_zeroPointers(fStateFeatures, kStateFeatureCountAll+1);
701 ~CarlaPluginLV2() override
703 carla_debug("CarlaPluginLV2::~CarlaPluginLV2()");
705 fInlineDisplayNeedsRedraw = false;
707 // close UI
708 if (fUI.type != UI::TYPE_NULL)
710 showCustomUI(false);
712 #ifndef LV2_UIS_ONLY_INPROCESS
713 if (fUI.type == UI::TYPE_BRIDGE)
715 fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
717 else
718 #endif
720 if (fFeatures[kFeatureIdUiDataAccess] != nullptr && fFeatures[kFeatureIdUiDataAccess]->data != nullptr)
721 delete (LV2_Extension_Data_Feature*)fFeatures[kFeatureIdUiDataAccess]->data;
723 if (fFeatures[kFeatureIdUiPortMap] != nullptr && fFeatures[kFeatureIdUiPortMap]->data != nullptr)
724 delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data;
726 if (fFeatures[kFeatureIdUiRequestValue] != nullptr && fFeatures[kFeatureIdUiRequestValue]->data != nullptr)
727 delete (LV2UI_Request_Value*)fFeatures[kFeatureIdUiRequestValue]->data;
729 if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr)
730 delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data;
732 if (fFeatures[kFeatureIdUiTouch] != nullptr && fFeatures[kFeatureIdUiTouch]->data != nullptr)
733 delete (LV2UI_Touch*)fFeatures[kFeatureIdUiTouch]->data;
735 if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
736 delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data;
738 fUI.descriptor = nullptr;
739 pData->uiLibClose();
742 #ifndef LV2_UIS_ONLY_BRIDGES
743 if (fUI.window != nullptr)
745 delete fUI.window;
746 fUI.window = nullptr;
748 #endif
750 fUI.rdfDescriptor = nullptr;
753 pData->singleMutex.lock();
754 pData->masterMutex.lock();
756 if (pData->client != nullptr && pData->client->isActive())
757 pData->client->deactivate(true);
759 if (pData->active)
761 deactivate();
762 pData->active = false;
765 if (fExt.state != nullptr)
767 const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
769 if (tmpDir.exists())
770 tmpDir.deleteRecursively();
773 if (fDescriptor != nullptr)
775 if (fDescriptor->cleanup != nullptr)
777 if (fHandle != nullptr)
778 fDescriptor->cleanup(fHandle);
779 if (fHandle2 != nullptr)
780 fDescriptor->cleanup(fHandle2);
783 fHandle = nullptr;
784 fHandle2 = nullptr;
785 fDescriptor = nullptr;
788 if (fRdfDescriptor != nullptr)
790 delete fRdfDescriptor;
791 fRdfDescriptor = nullptr;
794 if (fFeatures[kFeatureIdEvent] != nullptr && fFeatures[kFeatureIdEvent]->data != nullptr)
795 delete (LV2_Event_Feature*)fFeatures[kFeatureIdEvent]->data;
797 if (fFeatures[kFeatureIdLogs] != nullptr && fFeatures[kFeatureIdLogs]->data != nullptr)
798 delete (LV2_Log_Log*)fFeatures[kFeatureIdLogs]->data;
800 if (fFeatures[kFeatureIdStateFreePath] != nullptr && fFeatures[kFeatureIdStateFreePath]->data != nullptr)
801 delete (LV2_State_Free_Path*)fFeatures[kFeatureIdStateFreePath]->data;
803 if (fFeatures[kFeatureIdStateMakePath] != nullptr && fFeatures[kFeatureIdStateMakePath]->data != nullptr)
804 delete (LV2_State_Make_Path*)fFeatures[kFeatureIdStateMakePath]->data;
806 if (fFeatures[kFeatureIdStateMapPath] != nullptr && fFeatures[kFeatureIdStateMapPath]->data != nullptr)
807 delete (LV2_State_Map_Path*)fFeatures[kFeatureIdStateMapPath]->data;
809 if (fFeatures[kFeatureIdPrograms] != nullptr && fFeatures[kFeatureIdPrograms]->data != nullptr)
810 delete (LV2_Programs_Host*)fFeatures[kFeatureIdPrograms]->data;
812 if (fFeatures[kFeatureIdResizePort] != nullptr && fFeatures[kFeatureIdResizePort]->data != nullptr)
813 delete (LV2_Resize_Port_Resize*)fFeatures[kFeatureIdResizePort]->data;
815 if (fFeatures[kFeatureIdRtMemPool] != nullptr && fFeatures[kFeatureIdRtMemPool]->data != nullptr)
816 delete (LV2_RtMemPool_Pool*)fFeatures[kFeatureIdRtMemPool]->data;
818 if (fFeatures[kFeatureIdRtMemPoolOld] != nullptr && fFeatures[kFeatureIdRtMemPoolOld]->data != nullptr)
819 delete (LV2_RtMemPool_Pool_Deprecated*)fFeatures[kFeatureIdRtMemPoolOld]->data;
821 if (fFeatures[kFeatureIdUriMap] != nullptr && fFeatures[kFeatureIdUriMap]->data != nullptr)
822 delete (LV2_URI_Map_Feature*)fFeatures[kFeatureIdUriMap]->data;
824 if (fFeatures[kFeatureIdUridMap] != nullptr && fFeatures[kFeatureIdUridMap]->data != nullptr)
825 delete (LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
827 if (fFeatures[kFeatureIdUridUnmap] != nullptr && fFeatures[kFeatureIdUridUnmap]->data != nullptr)
828 delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data;
830 if (fFeatures[kFeatureIdWorker] != nullptr && fFeatures[kFeatureIdWorker]->data != nullptr)
831 delete (LV2_Worker_Schedule*)fFeatures[kFeatureIdWorker]->data;
833 if (fFeatures[kFeatureIdInlineDisplay] != nullptr && fFeatures[kFeatureIdInlineDisplay]->data != nullptr)
834 delete (LV2_Inline_Display*)fFeatures[kFeatureIdInlineDisplay]->data;
836 if (fFeatures[kFeatureIdMidnam] != nullptr && fFeatures[kFeatureIdMidnam]->data != nullptr)
837 delete (LV2_Midnam*)fFeatures[kFeatureIdMidnam]->data;
839 if (fFeatures[kFeatureIdCtrlInPortChangeReq] != nullptr && fFeatures[kFeatureIdCtrlInPortChangeReq]->data != nullptr)
840 delete (LV2_ControlInputPort_Change_Request*)fFeatures[kFeatureIdCtrlInPortChangeReq]->data;
842 for (uint32_t i=0; i < kFeatureCountAll; ++i)
844 if (fFeatures[i] != nullptr)
846 delete fFeatures[i];
847 fFeatures[i] = nullptr;
851 if (fStateFeatures[kStateFeatureIdMakePath] != nullptr && fStateFeatures[kStateFeatureIdMakePath]->data != nullptr)
852 delete (LV2_State_Make_Path*)fStateFeatures[kStateFeatureIdMakePath]->data;
854 if (fStateFeatures[kStateFeatureIdMapPath] != nullptr && fStateFeatures[kStateFeatureIdMapPath]->data != nullptr)
855 delete (LV2_State_Map_Path*)fStateFeatures[kStateFeatureIdMapPath]->data;
857 for (uint32_t i=0; i < kStateFeatureCountAll; ++i)
859 if (fStateFeatures[i] != nullptr)
861 delete fStateFeatures[i];
862 fStateFeatures[i] = nullptr;
866 if (fLastStateChunk != nullptr)
868 std::free(fLastStateChunk);
869 fLastStateChunk = nullptr;
872 if (fAtomBufferUiOutTmpData != nullptr)
874 delete[] fAtomBufferUiOutTmpData;
875 fAtomBufferUiOutTmpData = nullptr;
878 if (fAtomBufferWorkerInTmpData != nullptr)
880 delete[] fAtomBufferWorkerInTmpData;
881 fAtomBufferWorkerInTmpData = nullptr;
884 if (fAtomBufferRealtime != nullptr)
886 std::free(fAtomBufferRealtime);
887 fAtomBufferRealtime = nullptr;
890 clearBuffers();
893 // -------------------------------------------------------------------
894 // Information (base)
896 PluginType getType() const noexcept override
898 return PLUGIN_LV2;
901 PluginCategory getCategory() const noexcept override
903 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, CarlaPlugin::getCategory());
905 const LV2_Property cat1(fRdfDescriptor->Type[0]);
906 const LV2_Property cat2(fRdfDescriptor->Type[1]);
908 if (LV2_IS_DELAY(cat1, cat2))
909 return PLUGIN_CATEGORY_DELAY;
910 if (LV2_IS_DISTORTION(cat1, cat2))
911 return PLUGIN_CATEGORY_OTHER;
912 if (LV2_IS_DYNAMICS(cat1, cat2))
913 return PLUGIN_CATEGORY_DYNAMICS;
914 if (LV2_IS_EQ(cat1, cat2))
915 return PLUGIN_CATEGORY_EQ;
916 if (LV2_IS_FILTER(cat1, cat2))
917 return PLUGIN_CATEGORY_FILTER;
918 if (LV2_IS_GENERATOR(cat1, cat2))
919 return PLUGIN_CATEGORY_SYNTH;
920 if (LV2_IS_MODULATOR(cat1, cat2))
921 return PLUGIN_CATEGORY_MODULATOR;
922 if (LV2_IS_REVERB(cat1, cat2))
923 return PLUGIN_CATEGORY_DELAY;
924 if (LV2_IS_SIMULATOR(cat1, cat2))
925 return PLUGIN_CATEGORY_OTHER;
926 if (LV2_IS_SPATIAL(cat1, cat2))
927 return PLUGIN_CATEGORY_OTHER;
928 if (LV2_IS_SPECTRAL(cat1, cat2))
929 return PLUGIN_CATEGORY_UTILITY;
930 if (LV2_IS_UTILITY(cat1, cat2))
931 return PLUGIN_CATEGORY_UTILITY;
933 return CarlaPlugin::getCategory();
936 uint32_t getLatencyInFrames() const noexcept override
938 if (fLatencyIndex < 0 || fParamBuffers == nullptr)
939 return 0;
941 const float latency(fParamBuffers[fLatencyIndex]);
942 CARLA_SAFE_ASSERT_RETURN(latency >= 0.0f, 0);
944 return static_cast<uint32_t>(latency);
947 // -------------------------------------------------------------------
948 // Information (count)
950 uint32_t getMidiInCount() const noexcept override
952 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
954 uint32_t count = 0;
956 for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
958 const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
960 if (LV2_IS_PORT_INPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
961 ++count;
964 return count;
967 uint32_t getMidiOutCount() const noexcept override
969 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
971 uint32_t count = 0;
973 for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
975 const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
977 if (LV2_IS_PORT_OUTPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
978 ++count;
981 return count;
984 uint32_t getParameterScalePointCount(const uint32_t parameterId) const noexcept override
986 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
987 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0);
989 const int32_t rindex(pData->param.data[parameterId].rindex);
991 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
993 const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
994 return port->ScalePointCount;
997 return 0;
1000 // -------------------------------------------------------------------
1001 // Information (current data)
1003 uint getAudioPortHints(bool isOutput, uint32_t portIndex) const noexcept override
1005 uint hints = 0x0;
1007 for (uint32_t i=0, j=0; i<fRdfDescriptor->PortCount; ++i)
1009 LV2_RDF_Port& port(fRdfDescriptor->Ports[i]);
1011 if (! LV2_IS_PORT_AUDIO(port.Types))
1012 continue;
1014 if (isOutput)
1016 if (! LV2_IS_PORT_OUTPUT(port.Types))
1017 continue;
1019 else
1021 if (! LV2_IS_PORT_INPUT(port.Types))
1022 continue;
1025 if (j++ != portIndex)
1026 continue;
1028 if (LV2_IS_PORT_SIDECHAIN(port.Properties))
1029 hints |= AUDIO_PORT_IS_SIDECHAIN;
1031 break;
1034 return hints;
1037 // -------------------------------------------------------------------
1038 // Information (per-plugin data)
1040 uint getOptionsAvailable() const noexcept override
1042 uint options = 0x0;
1044 // can't disable fixed buffers if using latency or MIDI output
1045 if (fLatencyIndex == -1 && getMidiOutCount() == 0 && ! fNeedsFixedBuffers)
1046 options |= PLUGIN_OPTION_FIXED_BUFFERS;
1048 // can't disable forced stereo if enabled in the engine
1049 if (pData->engine->getOptions().forceStereo)
1050 pass();
1051 // if there are event outputs, we can't force stereo
1052 else if (fEventsOut.count != 0)
1053 pass();
1054 // if inputs or outputs are just 1, then yes we can force stereo
1055 else if ((pData->audioIn.count == 1 || pData->audioOut.count == 1) || fHandle2 != nullptr)
1056 options |= PLUGIN_OPTION_FORCE_STEREO;
1058 if (fExt.programs != nullptr)
1059 options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
1061 if (getMidiInCount() != 0)
1063 options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
1064 options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
1065 options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
1066 options |= PLUGIN_OPTION_SEND_PITCHBEND;
1067 options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
1068 options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
1069 options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
1072 return options;
1075 float getParameterValue(const uint32_t parameterId) const noexcept override
1077 CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr, 0.0f);
1078 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
1080 if (pData->param.data[parameterId].type == PARAMETER_INPUT)
1082 if (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS)
1083 pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
1085 else
1087 if (fStrictBounds >= 0 && (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS) == 0)
1088 pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
1091 return fParamBuffers[parameterId];
1094 float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept override
1096 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0.0f);
1097 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
1099 const int32_t rindex(pData->param.data[parameterId].rindex);
1101 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1103 const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
1104 CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, 0.0f);
1106 const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
1107 return portScalePoint->Value;
1110 return 0.0f;
1113 bool getLabel(char* const strBuf) const noexcept override
1115 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1116 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor->URI != nullptr, false);
1118 std::strncpy(strBuf, fRdfDescriptor->URI, STR_MAX);
1119 return true;
1122 bool getMaker(char* const strBuf) const noexcept override
1124 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1126 if (fRdfDescriptor->Author != nullptr)
1128 std::strncpy(strBuf, fRdfDescriptor->Author, STR_MAX);
1129 return true;
1132 return false;
1135 bool getCopyright(char* const strBuf) const noexcept override
1137 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1139 if (fRdfDescriptor->License != nullptr)
1141 std::strncpy(strBuf, fRdfDescriptor->License, STR_MAX);
1142 return true;
1145 return false;
1148 bool getRealName(char* const strBuf) const noexcept override
1150 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1152 if (fRdfDescriptor->Name != nullptr)
1154 std::strncpy(strBuf, fRdfDescriptor->Name, STR_MAX);
1155 return true;
1158 return false;
1161 bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
1163 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1164 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1166 int32_t rindex = pData->param.data[parameterId].rindex;
1167 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1169 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1171 std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Name, STR_MAX);
1172 return true;
1175 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1177 if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1179 std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].Label, STR_MAX);
1180 return true;
1183 return CarlaPlugin::getParameterName(parameterId, strBuf);
1186 bool getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept override
1188 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1189 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1191 int32_t rindex = pData->param.data[parameterId].rindex;
1192 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1194 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1196 std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Symbol, STR_MAX);
1197 return true;
1200 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1202 if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1204 std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].URI, STR_MAX);
1205 return true;
1208 return CarlaPlugin::getParameterSymbol(parameterId, strBuf);
1211 bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
1213 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1214 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1216 LV2_RDF_PortUnit* portUnit = nullptr;
1218 int32_t rindex = pData->param.data[parameterId].rindex;
1219 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1221 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1223 portUnit = &fRdfDescriptor->Ports[rindex].Unit;
1225 else
1227 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1229 if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1231 portUnit = &fRdfDescriptor->Parameters[rindex].Unit;
1235 if (portUnit != nullptr)
1237 if (LV2_HAVE_PORT_UNIT_SYMBOL(portUnit->Hints) && portUnit->Symbol != nullptr)
1239 std::strncpy(strBuf, portUnit->Symbol, STR_MAX);
1240 return true;
1243 if (LV2_HAVE_PORT_UNIT_UNIT(portUnit->Hints))
1245 switch (portUnit->Unit)
1247 case LV2_PORT_UNIT_BAR:
1248 std::strncpy(strBuf, "bars", STR_MAX);
1249 return true;
1250 case LV2_PORT_UNIT_BEAT:
1251 std::strncpy(strBuf, "beats", STR_MAX);
1252 return true;
1253 case LV2_PORT_UNIT_BPM:
1254 std::strncpy(strBuf, "BPM", STR_MAX);
1255 return true;
1256 case LV2_PORT_UNIT_CENT:
1257 std::strncpy(strBuf, "ct", STR_MAX);
1258 return true;
1259 case LV2_PORT_UNIT_CM:
1260 std::strncpy(strBuf, "cm", STR_MAX);
1261 return true;
1262 case LV2_PORT_UNIT_COEF:
1263 std::strncpy(strBuf, "(coef)", STR_MAX);
1264 return true;
1265 case LV2_PORT_UNIT_DB:
1266 std::strncpy(strBuf, "dB", STR_MAX);
1267 return true;
1268 case LV2_PORT_UNIT_DEGREE:
1269 std::strncpy(strBuf, "deg", STR_MAX);
1270 return true;
1271 case LV2_PORT_UNIT_FRAME:
1272 std::strncpy(strBuf, "frames", STR_MAX);
1273 return true;
1274 case LV2_PORT_UNIT_HZ:
1275 std::strncpy(strBuf, "Hz", STR_MAX);
1276 return true;
1277 case LV2_PORT_UNIT_INCH:
1278 std::strncpy(strBuf, "in", STR_MAX);
1279 return true;
1280 case LV2_PORT_UNIT_KHZ:
1281 std::strncpy(strBuf, "kHz", STR_MAX);
1282 return true;
1283 case LV2_PORT_UNIT_KM:
1284 std::strncpy(strBuf, "km", STR_MAX);
1285 return true;
1286 case LV2_PORT_UNIT_M:
1287 std::strncpy(strBuf, "m", STR_MAX);
1288 return true;
1289 case LV2_PORT_UNIT_MHZ:
1290 std::strncpy(strBuf, "MHz", STR_MAX);
1291 return true;
1292 case LV2_PORT_UNIT_MIDINOTE:
1293 std::strncpy(strBuf, "note", STR_MAX);
1294 return true;
1295 case LV2_PORT_UNIT_MILE:
1296 std::strncpy(strBuf, "mi", STR_MAX);
1297 return true;
1298 case LV2_PORT_UNIT_MIN:
1299 std::strncpy(strBuf, "min", STR_MAX);
1300 return true;
1301 case LV2_PORT_UNIT_MM:
1302 std::strncpy(strBuf, "mm", STR_MAX);
1303 return true;
1304 case LV2_PORT_UNIT_MS:
1305 std::strncpy(strBuf, "ms", STR_MAX);
1306 return true;
1307 case LV2_PORT_UNIT_OCT:
1308 std::strncpy(strBuf, "oct", STR_MAX);
1309 return true;
1310 case LV2_PORT_UNIT_PC:
1311 std::strncpy(strBuf, "%", STR_MAX);
1312 return true;
1313 case LV2_PORT_UNIT_S:
1314 std::strncpy(strBuf, "s", STR_MAX);
1315 return true;
1316 case LV2_PORT_UNIT_SEMITONE:
1317 std::strncpy(strBuf, "semi", STR_MAX);
1318 return true;
1319 case LV2_PORT_UNIT_VOLTS:
1320 std::strncpy(strBuf, "v", STR_MAX);
1321 return true;
1326 return CarlaPlugin::getParameterUnit(parameterId, strBuf);
1329 bool getParameterComment(const uint32_t parameterId, char* const strBuf) const noexcept override
1331 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1332 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1334 int32_t rindex = pData->param.data[parameterId].rindex;
1335 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1337 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1339 if (const char* const comment = fRdfDescriptor->Ports[rindex].Comment)
1341 std::strncpy(strBuf, comment, STR_MAX);
1342 return true;
1344 return false;
1347 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1349 if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1351 if (const char* const comment = fRdfDescriptor->Parameters[rindex].Comment)
1353 std::strncpy(strBuf, comment, STR_MAX);
1354 return true;
1356 return false;
1359 return CarlaPlugin::getParameterComment(parameterId, strBuf);
1362 bool getParameterGroupName(const uint32_t parameterId, char* const strBuf) const noexcept override
1364 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1365 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1367 int32_t rindex = pData->param.data[parameterId].rindex;
1368 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1370 const char* uri = nullptr;
1372 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1374 uri = fRdfDescriptor->Ports[rindex].GroupURI;
1376 else
1378 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1380 if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1381 uri = fRdfDescriptor->Parameters[rindex].GroupURI;
1384 if (uri == nullptr)
1385 return false;
1387 for (uint32_t i=0; i<fRdfDescriptor->PortGroupCount; ++i)
1389 if (std::strcmp(fRdfDescriptor->PortGroups[i].URI, uri) == 0)
1391 const char* const name = fRdfDescriptor->PortGroups[i].Name;
1392 const char* const symbol = fRdfDescriptor->PortGroups[i].Symbol;
1394 if (name != nullptr && symbol != nullptr)
1396 std::snprintf(strBuf, STR_MAX, "%s:%s", symbol, name);
1397 return true;
1399 return false;
1403 return false;
1406 bool getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept override
1408 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1409 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1411 const int32_t rindex(pData->param.data[parameterId].rindex);
1412 CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1414 if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1416 const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
1417 CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, false);
1419 const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
1421 if (portScalePoint->Label != nullptr)
1423 std::strncpy(strBuf, portScalePoint->Label, STR_MAX);
1424 return true;
1428 return CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
1431 // -------------------------------------------------------------------
1432 // Set data (state)
1434 void prepareForSave(const bool temporary) override
1436 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1438 if (fExt.state != nullptr && fExt.state->save != nullptr)
1440 // move temporary stuff to main state dir on full save
1441 if (! temporary)
1443 const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
1445 if (tmpDir.exists())
1447 const File stateDir(handleStateMapToAbsolutePath(true, false, false, "."));
1449 if (stateDir.isNotNull())
1450 tmpDir.moveFileTo(stateDir);
1454 fExt.state->save(fHandle, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
1456 if (fHandle2 != nullptr)
1457 fExt.state->save(fHandle2, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
1461 // -------------------------------------------------------------------
1462 // Set data (internal stuff)
1464 void setName(const char* const newName) override
1466 const File tmpDir1(handleStateMapToAbsolutePath(false, false, true, "."));
1468 CarlaPlugin::setName(newName);
1470 if (tmpDir1.exists())
1472 const File tmpDir2(handleStateMapToAbsolutePath(false, false, true, "."));
1474 carla_stdout("dir1 %s, dir2 %s",
1475 tmpDir1.getFullPathName().toRawUTF8(),
1476 tmpDir2.getFullPathName().toRawUTF8());
1478 if (tmpDir2.isNotNull())
1480 if (tmpDir2.exists())
1481 tmpDir2.deleteRecursively();
1483 tmpDir1.moveFileTo(tmpDir2);
1487 if (fLv2Options.windowTitle != nullptr && pData->uiTitle.isEmpty())
1488 setWindowTitle(nullptr);
1491 void setWindowTitle(const char* const title) noexcept
1493 CarlaString uiTitle;
1495 if (title != nullptr)
1497 uiTitle = title;
1499 else
1501 uiTitle = pData->name;
1502 uiTitle += " (GUI)";
1505 std::free(const_cast<char*>(fLv2Options.windowTitle));
1506 fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
1508 fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle);
1509 fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
1511 if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
1512 ((LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data)->plugin_human_id = fLv2Options.windowTitle;
1514 #ifndef LV2_UIS_ONLY_INPROCESS
1515 if (fPipeServer.isPipeRunning())
1516 fPipeServer.writeUiTitleMessage(fLv2Options.windowTitle);
1517 #endif
1519 #ifndef LV2_UIS_ONLY_BRIDGES
1520 if (fUI.window != nullptr)
1522 try {
1523 fUI.window->setTitle(fLv2Options.windowTitle);
1524 } CARLA_SAFE_EXCEPTION("set custom title");
1526 #endif
1529 // -------------------------------------------------------------------
1530 // Set data (plugin-specific stuff)
1532 float setParamterValueCommon(const uint32_t parameterId, const float value) noexcept
1534 const float fixedValue(pData->param.getFixedValue(parameterId, value));
1535 fParamBuffers[parameterId] = fixedValue;
1537 if (pData->param.data[parameterId].rindex >= static_cast<int32_t>(fRdfDescriptor->PortCount))
1539 const uint32_t rparamId = static_cast<uint32_t>(pData->param.data[parameterId].rindex) - fRdfDescriptor->PortCount;
1540 CARLA_SAFE_ASSERT_UINT2_RETURN(rparamId < fRdfDescriptor->ParameterCount,
1541 rparamId, fRdfDescriptor->PortCount, fixedValue);
1543 uint8_t atomBuf[256];
1544 LV2_Atom_Forge atomForge;
1545 initAtomForge(atomForge);
1546 lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
1548 LV2_Atom_Forge_Frame forgeFrame;
1549 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
1551 lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
1552 lv2_atom_forge_bool(&atomForge, true);
1554 lv2_atom_forge_key(&atomForge, kUridPatchProperty);
1555 lv2_atom_forge_urid(&atomForge, getCustomURID(fRdfDescriptor->Parameters[rparamId].URI));
1557 lv2_atom_forge_key(&atomForge, kUridPatchValue);
1559 switch (fRdfDescriptor->Parameters[rparamId].Type)
1561 case LV2_PARAMETER_TYPE_BOOL:
1562 lv2_atom_forge_bool(&atomForge, fixedValue > 0.5f);
1563 break;
1564 case LV2_PARAMETER_TYPE_INT:
1565 lv2_atom_forge_int(&atomForge, static_cast<int32_t>(fixedValue + 0.5f));
1566 break;
1567 case LV2_PARAMETER_TYPE_LONG:
1568 lv2_atom_forge_long(&atomForge, static_cast<int64_t>(fixedValue + 0.5f));
1569 break;
1570 case LV2_PARAMETER_TYPE_FLOAT:
1571 lv2_atom_forge_float(&atomForge, fixedValue);
1572 break;
1573 case LV2_PARAMETER_TYPE_DOUBLE:
1574 lv2_atom_forge_double(&atomForge, fixedValue);
1575 break;
1576 default:
1577 carla_stderr2("setParameterValue called for invalid parameter, expect issues!");
1578 break;
1581 lv2_atom_forge_pop(&atomForge, &forgeFrame);
1583 LV2_Atom* const atom((LV2_Atom*)atomBuf);
1584 CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
1586 fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
1589 return fixedValue;
1592 void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
1594 CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
1595 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
1597 const float fixedValue = setParamterValueCommon(parameterId, value);
1599 CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
1602 void setParameterValueRT(const uint32_t parameterId, const float value, const uint32_t frameOffset, const bool sendCallbackLater) noexcept override
1604 CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
1605 CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
1607 const float fixedValue = setParamterValueCommon(parameterId, value);
1609 CarlaPlugin::setParameterValueRT(parameterId, fixedValue, frameOffset, sendCallbackLater);
1612 void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
1614 CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
1615 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1616 CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
1617 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
1618 CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
1619 carla_debug("CarlaPluginLV2::setCustomData(\"%s\", \"%s\", \"%s\", %s)", type, key, value, bool2str(sendGui));
1621 if (std::strcmp(type, CUSTOM_DATA_TYPE_PATH) == 0)
1623 if (std::strcmp(key, "file") != 0)
1624 return;
1626 CARLA_SAFE_ASSERT_RETURN(fFilePathURI.isNotEmpty(),);
1627 CARLA_SAFE_ASSERT_RETURN(value[0] != '\0',);
1629 carla_stdout("LV2 file path to send: '%s'", value);
1630 writeAtomPath(value, getCustomURID(fFilePathURI));
1631 return;
1634 if (std::strcmp(type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
1635 return CarlaPlugin::setCustomData(type, key, value, sendGui);
1637 // See if this key is from a parameter exposed by carla, apply value if yes
1638 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
1640 const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
1642 if (std::strcmp(rdfParam.URI, key) == 0)
1644 uint32_t parameterId = UINT32_MAX;
1645 const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
1647 switch (rdfParam.Type)
1649 case LV2_PARAMETER_TYPE_BOOL:
1650 case LV2_PARAMETER_TYPE_INT:
1651 // case LV2_PARAMETER_TYPE_LONG:
1652 case LV2_PARAMETER_TYPE_FLOAT:
1653 case LV2_PARAMETER_TYPE_DOUBLE:
1654 for (uint32_t j=0; j < pData->param.count; ++j)
1656 if (pData->param.data[j].rindex == rindex)
1658 parameterId = j;
1659 break;
1662 break;
1665 if (parameterId == UINT32_MAX)
1666 break;
1668 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(value));
1669 CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0,);
1671 #ifdef CARLA_PROPER_CPP11_SUPPORT
1672 const uint8_t* const valueptr = chunk.data();
1673 #else
1674 const uint8_t* const valueptr = &chunk.front();
1675 #endif
1676 float rvalue;
1678 switch (rdfParam.Type)
1680 case LV2_PARAMETER_TYPE_BOOL:
1681 rvalue = *(const int32_t*)valueptr != 0 ? 1.0f : 0.0f;
1682 break;
1683 case LV2_PARAMETER_TYPE_INT:
1684 rvalue = static_cast<float>(*(const int32_t*)valueptr);
1685 break;
1686 case LV2_PARAMETER_TYPE_FLOAT:
1687 rvalue = *(const float*)valueptr;
1688 break;
1689 case LV2_PARAMETER_TYPE_DOUBLE:
1690 rvalue = static_cast<float>(*(const double*)valueptr);
1691 break;
1692 default:
1693 // making compilers happy
1694 rvalue = pData->param.ranges[parameterId].def;
1695 break;
1698 fParamBuffers[parameterId] = pData->param.getFixedValue(parameterId, rvalue);
1699 break;
1703 CarlaPlugin::setCustomData(type, key, value, sendGui);
1706 void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
1708 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1709 CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
1710 CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);
1712 if (index >= 0 && index < static_cast<int32_t>(fRdfDescriptor->PresetCount))
1714 const LV2_URID_Map* const uridMap = (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
1716 LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fRdfDescriptor->Presets[index].URI,
1717 uridMap);
1718 CARLA_SAFE_ASSERT_RETURN(state != nullptr,);
1720 // invalidate midi-program selection
1721 CarlaPlugin::setMidiProgram(-1, false, false, sendCallback, false);
1723 if (fExt.state != nullptr)
1725 const bool block = (sendGui || sendOsc || sendCallback) && !fHasThreadSafeRestore;
1726 const ScopedSingleProcessLocker spl(this, block);
1728 lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
1730 if (fHandle2 != nullptr)
1731 lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
1733 else
1735 lilv_state_emit_port_values(state, carla_lilv_set_port_value, this);
1738 lilv_state_free(state);
1741 CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
1744 void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
1746 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1747 CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
1748 CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
1750 if (index >= 0 && fExt.programs != nullptr && fExt.programs->select_program != nullptr)
1752 const uint32_t bank(pData->midiprog.data[index].bank);
1753 const uint32_t program(pData->midiprog.data[index].program);
1755 const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
1757 try {
1758 fExt.programs->select_program(fHandle, bank, program);
1759 } CARLA_SAFE_EXCEPTION("select program");
1761 if (fHandle2 != nullptr)
1763 try {
1764 fExt.programs->select_program(fHandle2, bank, program);
1765 } CARLA_SAFE_EXCEPTION("select program 2");
1769 CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, doingInit);
1772 void setMidiProgramRT(const uint32_t uindex, const bool sendCallbackLater) noexcept override
1774 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1775 CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
1777 if (fExt.programs != nullptr && fExt.programs->select_program != nullptr)
1779 const uint32_t bank(pData->midiprog.data[uindex].bank);
1780 const uint32_t program(pData->midiprog.data[uindex].program);
1782 try {
1783 fExt.programs->select_program(fHandle, bank, program);
1784 } CARLA_SAFE_EXCEPTION("select program RT");
1786 if (fHandle2 != nullptr)
1788 try {
1789 fExt.programs->select_program(fHandle2, bank, program);
1790 } CARLA_SAFE_EXCEPTION("select program RT 2");
1794 CarlaPlugin::setMidiProgramRT(uindex, sendCallbackLater);
1797 // -------------------------------------------------------------------
1798 // Set ui stuff
1800 void setCustomUITitle(const char* const title) noexcept override
1802 setWindowTitle(title);
1803 CarlaPlugin::setCustomUITitle(title);
1806 void showCustomUI(const bool yesNo) override
1808 if (fUI.type == UI::TYPE_NULL)
1810 if (yesNo && fFilePathURI.isNotEmpty())
1812 const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN, false, "Open File", "");
1814 if (path != nullptr && path[0] != '\0')
1816 carla_stdout("LV2 file path to send: '%s'", path);
1817 writeAtomPath(path, getCustomURID(fFilePathURI));
1820 else
1822 CARLA_SAFE_ASSERT(!yesNo);
1824 pData->engine->callback(true, true,
1825 ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
1826 return;
1829 const uintptr_t frontendWinId = pData->engine->getOptions().frontendWinId;
1831 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
1832 if (! yesNo)
1833 pData->transientTryCounter = 0;
1834 #endif
1836 #ifndef LV2_UIS_ONLY_INPROCESS
1837 if (fUI.type == UI::TYPE_BRIDGE)
1839 if (yesNo)
1841 if (fPipeServer.isPipeRunning())
1843 fPipeServer.writeFocusMessage();
1844 return;
1847 if (! fPipeServer.startPipeServer(std::min(fLv2Options.sequenceSize, 819200)))
1849 pData->engine->callback(true, true,
1850 ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
1851 return;
1854 // manually write messages so we can take the lock for ourselves
1856 char tmpBuf[0xff];
1857 tmpBuf[0xfe] = '\0';
1859 const CarlaMutexLocker cml(fPipeServer.getPipeLock());
1860 const CarlaScopedLocale csl;
1862 // write URI mappings
1863 uint32_t u = 0;
1864 for (std::vector<std::string>::iterator it=fCustomURIDs.begin(), end=fCustomURIDs.end(); it != end; ++it, ++u)
1866 if (u < kUridCount)
1867 continue;
1868 const std::string& uri(*it);
1870 if (! fPipeServer.writeMessage("urid\n", 5))
1871 return;
1873 std::snprintf(tmpBuf, 0xfe, "%u\n", u);
1874 if (! fPipeServer.writeMessage(tmpBuf))
1875 return;
1877 std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(uri.length()));
1878 if (! fPipeServer.writeMessage(tmpBuf))
1879 return;
1881 if (! fPipeServer.writeAndFixMessage(uri.c_str()))
1882 return;
1885 // write UI options
1886 if (! fPipeServer.writeMessage("uiOptions\n", 10))
1887 return;
1889 const EngineOptions& opts(pData->engine->getOptions());
1891 std::snprintf(tmpBuf, 0xff, "%g\n", pData->engine->getSampleRate());
1892 if (! fPipeServer.writeMessage(tmpBuf))
1893 return;
1895 std::snprintf(tmpBuf, 0xff, "%u\n", opts.bgColor);
1896 if (! fPipeServer.writeMessage(tmpBuf))
1897 return;
1899 std::snprintf(tmpBuf, 0xff, "%u\n", opts.fgColor);
1900 if (! fPipeServer.writeMessage(tmpBuf))
1901 return;
1903 std::snprintf(tmpBuf, 0xff, "%.12g\n", static_cast<double>(opts.uiScale));
1904 if (! fPipeServer.writeMessage(tmpBuf))
1905 return;
1907 std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useTheme
1908 if (! fPipeServer.writeMessage(tmpBuf))
1909 return;
1911 std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useThemeColors
1912 if (! fPipeServer.writeMessage(tmpBuf))
1913 return;
1915 if (! fPipeServer.writeAndFixMessage(fLv2Options.windowTitle != nullptr
1916 ? fLv2Options.windowTitle
1917 : ""))
1918 return;
1920 std::snprintf(tmpBuf, 0xff, P_INTPTR "\n", frontendWinId);
1921 if (! fPipeServer.writeMessage(tmpBuf))
1922 return;
1924 // write parameter values
1925 for (uint32_t i=0; i < pData->param.count; ++i)
1927 ParameterData& pdata(pData->param.data[i]);
1929 if (pdata.hints & PARAMETER_IS_NOT_SAVED)
1931 int32_t rindex = pdata.rindex;
1932 CARLA_SAFE_ASSERT_CONTINUE(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0);
1934 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1935 CARLA_SAFE_ASSERT_CONTINUE(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount));
1937 if (! fPipeServer.writeLv2ParameterMessage(fRdfDescriptor->Parameters[rindex].URI,
1938 getParameterValue(i), false))
1939 return;
1941 else
1943 if (! fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[i].rindex),
1944 getParameterValue(i), false))
1945 return;
1949 // ready to show
1950 if (! fPipeServer.writeMessage("show\n", 5))
1951 return;
1953 fPipeServer.syncMessages();
1956 #ifndef BUILD_BRIDGE
1957 if (fUI.rdfDescriptor->Type == LV2_UI_MOD)
1958 pData->tryTransient();
1959 #endif
1961 else
1963 fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
1965 return;
1967 #endif
1969 // take some precautions
1970 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
1971 CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr,);
1973 if (yesNo)
1975 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr,);
1976 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr,);
1978 else
1980 if (fUI.handle == nullptr)
1981 return;
1984 if (yesNo)
1986 if (fUI.handle == nullptr)
1988 #ifndef LV2_UIS_ONLY_BRIDGES
1989 if (fUI.type == UI::TYPE_EMBED && fUI.rdfDescriptor->Type != LV2_UI_NONE && fUI.window == nullptr)
1991 const char* msg = nullptr;
1992 const bool isStandalone = pData->engine->getOptions().pluginsAreStandalone;
1994 switch (fUI.rdfDescriptor->Type)
1996 case LV2_UI_GTK2:
1997 case LV2_UI_GTK3:
1998 case LV2_UI_QT4:
1999 case LV2_UI_QT5:
2000 case LV2_UI_EXTERNAL:
2001 case LV2_UI_OLD_EXTERNAL:
2002 msg = "Invalid UI type";
2003 break;
2005 case LV2_UI_COCOA:
2006 # ifdef CARLA_OS_MAC
2007 fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId, isStandalone, isUiResizable());
2008 # else
2009 msg = "UI is for MacOS only";
2010 # endif
2011 break;
2013 case LV2_UI_WINDOWS:
2014 # ifdef CARLA_OS_WIN
2015 fUI.window = CarlaPluginUI::newWindows(this, frontendWinId, isStandalone, isUiResizable());
2016 # else
2017 msg = "UI is for Windows only";
2018 # endif
2019 break;
2021 case LV2_UI_X11:
2022 # ifdef HAVE_X11
2023 fUI.window = CarlaPluginUI::newX11(this, frontendWinId, isStandalone, isUiResizable(), true);
2024 # else
2025 msg = "UI is only for systems with X11";
2026 # endif
2027 break;
2029 default:
2030 msg = "Unknown UI type";
2031 break;
2034 if (fUI.window == nullptr && fExt.uishow == nullptr)
2035 return pData->engine->callback(true, true,
2036 ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, msg);
2038 if (fUI.window != nullptr)
2039 fFeatures[kFeatureIdUiParent]->data = fUI.window->getPtr();
2041 #endif
2042 fUI.widget = nullptr;
2043 fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
2044 carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
2046 if (fUI.window != nullptr)
2048 if (fUI.widget != nullptr)
2049 fUI.window->setChildWindow(fUI.widget);
2050 fUI.window->setTitle(fLv2Options.windowTitle);
2054 CARLA_SAFE_ASSERT(fUI.handle != nullptr);
2055 CARLA_SAFE_ASSERT(fUI.type != UI::TYPE_EXTERNAL || fUI.widget != nullptr);
2057 if (fUI.handle == nullptr || (fUI.type == UI::TYPE_EXTERNAL && fUI.widget == nullptr))
2059 fUI.widget = nullptr;
2061 if (fUI.handle != nullptr)
2063 fUI.descriptor->cleanup(fUI.handle);
2064 fUI.handle = nullptr;
2067 return pData->engine->callback(true, true,
2068 ENGINE_CALLBACK_UI_STATE_CHANGED,
2069 pData->id,
2071 0, 0, 0.0f,
2072 "Plugin refused to open its own UI");
2075 updateUi();
2077 #ifndef LV2_UIS_ONLY_BRIDGES
2078 if (fUI.type == UI::TYPE_EMBED)
2080 if (fUI.window != nullptr)
2082 fUI.window->show();
2084 else if (fExt.uishow != nullptr)
2086 fExt.uishow->show(fUI.handle);
2087 # ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2088 pData->tryTransient();
2089 # endif
2092 else
2093 #endif
2095 LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUI.widget);
2096 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2097 pData->tryTransient();
2098 #endif
2101 else
2103 #ifndef LV2_UIS_ONLY_BRIDGES
2104 if (fUI.type == UI::TYPE_EMBED)
2106 if (fUI.window != nullptr)
2107 fUI.window->hide();
2108 else if (fExt.uishow != nullptr)
2109 fExt.uishow->hide(fUI.handle);
2111 else
2112 #endif
2114 CARLA_SAFE_ASSERT(fUI.widget != nullptr);
2116 if (fUI.widget != nullptr)
2117 LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget*)fUI.widget);
2120 fUI.descriptor->cleanup(fUI.handle);
2121 fUI.handle = nullptr;
2122 fUI.widget = nullptr;
2124 if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
2126 delete fUI.window;
2127 fUI.window = nullptr;
2132 #ifndef LV2_UIS_ONLY_BRIDGES
2133 void* embedCustomUI(void* const ptr) override
2135 CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED, nullptr);
2136 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr, nullptr);
2137 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr, nullptr);
2138 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr, nullptr);
2139 CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor->Type != LV2_UI_NONE, nullptr);
2140 CARLA_SAFE_ASSERT_RETURN(fUI.window == nullptr, nullptr);
2142 fFeatures[kFeatureIdUiParent]->data = ptr;
2144 fUI.embedded = true;
2145 fUI.widget = nullptr;
2146 fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
2147 carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
2149 updateUi();
2151 return fUI.widget;
2153 #endif
2155 void idle() override
2157 if (fAtomBufferWorkerIn.isDataAvailableForReading())
2159 Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferWorkerIn, fAtomBufferWorkerInTmpData);
2160 CARLA_SAFE_ASSERT_RETURN(tmpRingBuffer.isDataAvailableForReading(),);
2161 CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr,);
2163 const size_t localSize = fAtomBufferWorkerIn.getSize();
2164 uint8_t* const localData = new uint8_t[localSize];
2165 LV2_Atom* const localAtom = static_cast<LV2_Atom*>(static_cast<void*>(localData));
2166 localAtom->size = localSize;
2167 uint32_t portIndex;
2169 for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize)
2171 CARLA_SAFE_ASSERT_CONTINUE(localAtom->type == kUridCarlaAtomWorkerIn);
2172 fExt.worker->work(fHandle, carla_lv2_worker_respond, this, localAtom->size, LV2_ATOM_BODY_CONST(localAtom));
2175 delete[] localData;
2178 if (fInlineDisplayNeedsRedraw)
2180 // TESTING
2181 CARLA_SAFE_ASSERT(pData->enabled)
2182 CARLA_SAFE_ASSERT(!pData->engine->isAboutToClose());
2183 CARLA_SAFE_ASSERT(pData->client->isActive());
2185 if (pData->enabled && !pData->engine->isAboutToClose() && pData->client->isActive())
2187 const int64_t timeNow = water::Time::currentTimeMillis();
2189 if (timeNow - fInlineDisplayLastRedrawTime > (1000 / 30))
2191 fInlineDisplayNeedsRedraw = false;
2192 fInlineDisplayLastRedrawTime = timeNow;
2193 pData->engine->callback(true, true,
2194 ENGINE_CALLBACK_INLINE_DISPLAY_REDRAW,
2195 pData->id,
2196 0, 0, 0, 0.0f, nullptr);
2199 else
2201 fInlineDisplayNeedsRedraw = false;
2205 CarlaPlugin::idle();
2208 void uiIdle() override
2210 if (const char* const fileNeededForURI = fUI.fileNeededForURI)
2212 fUI.fileBrowserOpen = true;
2213 fUI.fileNeededForURI = nullptr;
2215 const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN,
2216 /* isDir */ false,
2217 /* title */ "File open",
2218 /* filters */ "");
2220 fUI.fileBrowserOpen = false;
2222 if (path != nullptr)
2224 carla_stdout("LV2 requested path to send: '%s'", path);
2225 writeAtomPath(path, getCustomURID(fileNeededForURI));
2228 // this function will be called recursively, stop here
2229 return;
2232 if (fAtomBufferUiOut.isDataAvailableForReading())
2234 Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferUiOut, fAtomBufferUiOutTmpData);
2235 CARLA_SAFE_ASSERT(tmpRingBuffer.isDataAvailableForReading());
2237 const size_t localSize = fAtomBufferUiOut.getSize();
2238 uint8_t* const localData = new uint8_t[localSize];
2239 LV2_Atom* const localAtom = static_cast<LV2_Atom*>(static_cast<void*>(localData));
2240 localAtom->size = localSize;
2242 uint32_t portIndex;
2243 const bool hasPortEvent(fUI.handle != nullptr &&
2244 fUI.descriptor != nullptr &&
2245 fUI.descriptor->port_event != nullptr);
2247 for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize)
2249 #ifndef LV2_UIS_ONLY_INPROCESS
2250 if (fUI.type == UI::TYPE_BRIDGE)
2252 if (fPipeServer.isPipeRunning())
2253 fPipeServer.writeLv2AtomMessage(portIndex, localAtom);
2255 else
2256 #endif
2258 if (hasPortEvent && ! fNeedsUiClose)
2259 fUI.descriptor->port_event(fUI.handle, portIndex, lv2_atom_total_size(localAtom), kUridAtomTransferEvent, localAtom);
2262 inspectAtomForParameterChange(localAtom);
2265 delete[] localData;
2268 #ifndef LV2_UIS_ONLY_INPROCESS
2269 if (fPipeServer.isPipeRunning())
2271 fPipeServer.idlePipe();
2273 switch (fPipeServer.getAndResetUiState())
2275 case CarlaPipeServerLV2::UiNone:
2276 case CarlaPipeServerLV2::UiShow:
2277 break;
2278 case CarlaPipeServerLV2::UiHide:
2279 fPipeServer.stopPipeServer(2000);
2280 // fall through
2281 case CarlaPipeServerLV2::UiCrashed:
2282 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2283 pData->transientTryCounter = 0;
2284 #endif
2285 pData->engine->callback(true, true,
2286 ENGINE_CALLBACK_UI_STATE_CHANGED,
2287 pData->id,
2289 0, 0, 0.0f, nullptr);
2290 break;
2293 else
2295 // TODO - detect if ui-bridge crashed
2297 #endif
2299 if (fNeedsUiClose)
2301 fNeedsUiClose = false;
2302 showCustomUI(false);
2303 pData->engine->callback(true, true,
2304 ENGINE_CALLBACK_UI_STATE_CHANGED,
2305 pData->id,
2307 0, 0, 0.0f, nullptr);
2309 else if (fUI.handle != nullptr && fUI.descriptor != nullptr)
2311 if (fUI.type == UI::TYPE_EXTERNAL && fUI.widget != nullptr)
2312 LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUI.widget);
2313 #ifndef LV2_UIS_ONLY_BRIDGES
2314 else if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
2315 fUI.window->idle();
2317 // note: UI might have been closed by window idle
2318 if (fNeedsUiClose)
2320 pass();
2322 else if (fUI.handle != nullptr && fExt.uiidle != nullptr && fExt.uiidle->idle(fUI.handle) != 0)
2324 showCustomUI(false);
2325 pData->engine->callback(true, true,
2326 ENGINE_CALLBACK_UI_STATE_CHANGED,
2327 pData->id,
2329 0, 0, 0.0f, nullptr);
2330 CARLA_SAFE_ASSERT(fUI.handle == nullptr);
2332 #endif
2335 CarlaPlugin::uiIdle();
2338 // -------------------------------------------------------------------
2339 // Plugin state
2341 void reload() override
2343 CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
2344 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
2345 CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
2346 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
2347 carla_debug("CarlaPluginLV2::reload() - start");
2349 const EngineProcessMode processMode(pData->engine->getProccessMode());
2351 // Safely disable plugin for reload
2352 const ScopedDisabler sd(this);
2354 if (pData->active)
2355 deactivate();
2357 clearBuffers();
2359 const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
2360 const uint32_t portCount(fRdfDescriptor->PortCount);
2362 uint32_t aIns, aOuts, cvIns, cvOuts, params;
2363 aIns = aOuts = cvIns = cvOuts = params = 0;
2364 LinkedList<uint> evIns, evOuts;
2366 const uint32_t eventBufferSize = static_cast<uint32_t>(fLv2Options.sequenceSize) + 0xff;
2368 bool forcedStereoIn, forcedStereoOut;
2369 forcedStereoIn = forcedStereoOut = false;
2371 bool needsCtrlIn, needsCtrlOut, hasPatchParameterOutputs;
2372 needsCtrlIn = needsCtrlOut = hasPatchParameterOutputs = false;
2374 for (uint32_t i=0; i < portCount; ++i)
2376 const LV2_Property portTypes = fRdfDescriptor->Ports[i].Types;
2378 if (LV2_IS_PORT_AUDIO(portTypes))
2380 if (LV2_IS_PORT_INPUT(portTypes))
2381 aIns += 1;
2382 else if (LV2_IS_PORT_OUTPUT(portTypes))
2383 aOuts += 1;
2385 else if (LV2_IS_PORT_CV(portTypes))
2387 if (LV2_IS_PORT_INPUT(portTypes))
2388 cvIns += 1;
2389 else if (LV2_IS_PORT_OUTPUT(portTypes))
2390 cvOuts += 1;
2392 else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
2394 if (LV2_IS_PORT_INPUT(portTypes))
2395 evIns.append(CARLA_EVENT_DATA_ATOM);
2396 else if (LV2_IS_PORT_OUTPUT(portTypes))
2397 evOuts.append(CARLA_EVENT_DATA_ATOM);
2399 else if (LV2_IS_PORT_EVENT(portTypes))
2401 if (LV2_IS_PORT_INPUT(portTypes))
2402 evIns.append(CARLA_EVENT_DATA_EVENT);
2403 else if (LV2_IS_PORT_OUTPUT(portTypes))
2404 evOuts.append(CARLA_EVENT_DATA_EVENT);
2406 else if (LV2_IS_PORT_MIDI_LL(portTypes))
2408 if (LV2_IS_PORT_INPUT(portTypes))
2409 evIns.append(CARLA_EVENT_DATA_MIDI_LL);
2410 else if (LV2_IS_PORT_OUTPUT(portTypes))
2411 evOuts.append(CARLA_EVENT_DATA_MIDI_LL);
2413 else if (LV2_IS_PORT_CONTROL(portTypes))
2414 params += 1;
2417 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
2419 switch (fRdfDescriptor->Parameters[i].Type)
2421 case LV2_PARAMETER_TYPE_BOOL:
2422 case LV2_PARAMETER_TYPE_INT:
2423 // case LV2_PARAMETER_TYPE_LONG:
2424 case LV2_PARAMETER_TYPE_FLOAT:
2425 case LV2_PARAMETER_TYPE_DOUBLE:
2426 params += 1;
2427 break;
2428 case LV2_PARAMETER_TYPE_PATH:
2429 if (fFilePathURI.isEmpty())
2430 fFilePathURI = fRdfDescriptor->Parameters[i].URI;
2431 break;
2435 if ((pData->options & PLUGIN_OPTION_FORCE_STEREO) != 0 && aIns <= 1 && aOuts <= 1 && evOuts.count() == 0 && fExt.state == nullptr && fExt.worker == nullptr)
2437 if (fHandle2 == nullptr)
2439 try {
2440 fHandle2 = fDescriptor->instantiate(fDescriptor, sampleRate, fRdfDescriptor->Bundle, fFeatures);
2441 } catch(...) {}
2444 if (fHandle2 != nullptr)
2446 if (aIns == 1)
2448 aIns = 2;
2449 forcedStereoIn = true;
2452 if (aOuts == 1)
2454 aOuts = 2;
2455 forcedStereoOut = true;
2460 if (aIns > 0)
2462 pData->audioIn.createNew(aIns);
2463 fAudioInBuffers = new float*[aIns];
2465 for (uint32_t i=0; i < aIns; ++i)
2466 fAudioInBuffers[i] = nullptr;
2469 if (aOuts > 0)
2471 pData->audioOut.createNew(aOuts);
2472 fAudioOutBuffers = new float*[aOuts];
2473 needsCtrlIn = true;
2475 for (uint32_t i=0; i < aOuts; ++i)
2476 fAudioOutBuffers[i] = nullptr;
2479 if (cvIns > 0)
2481 pData->cvIn.createNew(cvIns);
2482 fCvInBuffers = new float*[cvIns];
2484 for (uint32_t i=0; i < cvIns; ++i)
2485 fCvInBuffers[i] = nullptr;
2488 if (cvOuts > 0)
2490 pData->cvOut.createNew(cvOuts);
2491 fCvOutBuffers = new float*[cvOuts];
2493 for (uint32_t i=0; i < cvOuts; ++i)
2494 fCvOutBuffers[i] = nullptr;
2497 if (params > 0)
2499 pData->param.createNew(params, true);
2500 fParamBuffers = new float[params];
2501 carla_zeroFloats(fParamBuffers, params);
2504 if (const uint32_t count = static_cast<uint32_t>(evIns.count()))
2506 fEventsIn.createNew(count);
2508 for (uint32_t i=0; i < count; ++i)
2510 const uint32_t type = evIns.getAt(i, 0x0);
2512 if (type == CARLA_EVENT_DATA_ATOM)
2514 fEventsIn.data[i].type = CARLA_EVENT_DATA_ATOM;
2515 fEventsIn.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, true);
2517 else if (type == CARLA_EVENT_DATA_EVENT)
2519 fEventsIn.data[i].type = CARLA_EVENT_DATA_EVENT;
2520 fEventsIn.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
2522 else if (type == CARLA_EVENT_DATA_MIDI_LL)
2524 fEventsIn.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
2525 fEventsIn.data[i].midi.capacity = eventBufferSize;
2526 fEventsIn.data[i].midi.data = new uchar[eventBufferSize];
2530 else
2532 fEventsIn.createNew(1);
2533 fEventsIn.ctrl = &fEventsIn.data[0];
2536 if (const uint32_t count = static_cast<uint32_t>(evOuts.count()))
2538 fEventsOut.createNew(count);
2540 for (uint32_t i=0; i < count; ++i)
2542 const uint32_t type = evOuts.getAt(i, 0x0);
2544 if (type == CARLA_EVENT_DATA_ATOM)
2546 fEventsOut.data[i].type = CARLA_EVENT_DATA_ATOM;
2547 fEventsOut.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, false);
2549 else if (type == CARLA_EVENT_DATA_EVENT)
2551 fEventsOut.data[i].type = CARLA_EVENT_DATA_EVENT;
2552 fEventsOut.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
2554 else if (type == CARLA_EVENT_DATA_MIDI_LL)
2556 fEventsOut.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
2557 fEventsOut.data[i].midi.capacity = eventBufferSize;
2558 fEventsOut.data[i].midi.data = new uchar[eventBufferSize];
2563 const uint portNameSize(pData->engine->getMaxPortNameSize());
2564 CarlaString portName;
2565 uint32_t iCtrl = 0;
2567 for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCvIn=0, iCvOut=0, iEvIn=0, iEvOut=0; i < portCount; ++i)
2569 const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
2571 portName.clear();
2573 if (LV2_IS_PORT_AUDIO(portTypes) || LV2_IS_PORT_CV(portTypes) || LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
2575 if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
2577 portName = pData->name;
2578 portName += ":";
2581 portName += fRdfDescriptor->Ports[i].Name;
2582 portName.truncate(portNameSize);
2585 if (LV2_IS_PORT_AUDIO(portTypes))
2587 if (LV2_IS_PORT_INPUT(portTypes))
2589 const uint32_t j = iAudioIn++;
2590 pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
2591 pData->audioIn.ports[j].rindex = i;
2593 if (forcedStereoIn)
2595 portName += "_2";
2596 pData->audioIn.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, 1);
2597 pData->audioIn.ports[1].rindex = i;
2600 else if (LV2_IS_PORT_OUTPUT(portTypes))
2602 const uint32_t j = iAudioOut++;
2603 pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
2604 pData->audioOut.ports[j].rindex = i;
2606 if (forcedStereoOut)
2608 portName += "_2";
2609 pData->audioOut.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, 1);
2610 pData->audioOut.ports[1].rindex = i;
2613 else
2614 carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
2616 else if (LV2_IS_PORT_CV(portTypes))
2618 const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
2619 float min, max;
2621 // min value
2622 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
2623 min = portPoints.Minimum;
2624 else
2625 min = -1.0f;
2627 // max value
2628 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
2629 max = portPoints.Maximum;
2630 else
2631 max = 1.0f;
2633 if (LV2_IS_PORT_INPUT(portTypes))
2635 const uint32_t j = iCvIn++;
2636 pData->cvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j);
2637 pData->cvIn.ports[j].rindex = i;
2638 pData->cvIn.ports[j].port->setRange(min, max);
2640 else if (LV2_IS_PORT_OUTPUT(portTypes))
2642 const uint32_t j = iCvOut++;
2643 pData->cvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j);
2644 pData->cvOut.ports[j].rindex = i;
2645 pData->cvOut.ports[j].port->setRange(min, max);
2647 else
2648 carla_stderr("WARNING - Got a broken Port (CV, but not input or output)");
2650 else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
2652 if (LV2_IS_PORT_INPUT(portTypes))
2654 const uint32_t j = iEvIn++;
2656 fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].atom->atoms);
2658 if (fHandle2 != nullptr)
2659 fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].atom->atoms);
2661 fEventsIn.data[j].rindex = i;
2663 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2664 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2665 if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2666 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2667 if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2668 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
2670 if (evIns.count() == 1)
2672 fEventsIn.ctrl = &fEventsIn.data[j];
2673 fEventsIn.ctrlIndex = j;
2675 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2676 needsCtrlIn = true;
2678 else
2680 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2681 fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2683 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2685 fEventsIn.ctrl = &fEventsIn.data[j];
2686 fEventsIn.ctrlIndex = j;
2690 else if (LV2_IS_PORT_OUTPUT(portTypes))
2692 const uint32_t j = iEvOut++;
2694 fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].atom->atoms);
2696 if (fHandle2 != nullptr)
2697 fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].atom->atoms);
2699 fEventsOut.data[j].rindex = i;
2701 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2702 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2703 if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2704 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2705 if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2706 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
2708 if (evOuts.count() == 1)
2710 fEventsOut.ctrl = &fEventsOut.data[j];
2711 fEventsOut.ctrlIndex = j;
2713 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2714 needsCtrlOut = true;
2716 else
2718 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2719 fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2721 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2723 fEventsOut.ctrl = &fEventsOut.data[j];
2724 fEventsOut.ctrlIndex = j;
2728 else
2729 carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
2731 else if (LV2_IS_PORT_EVENT(portTypes))
2733 if (LV2_IS_PORT_INPUT(portTypes))
2735 const uint32_t j = iEvIn++;
2737 fDescriptor->connect_port(fHandle, i, fEventsIn.data[j].event);
2739 if (fHandle2 != nullptr)
2740 fDescriptor->connect_port(fHandle2, i, fEventsIn.data[j].event);
2742 fEventsIn.data[j].rindex = i;
2744 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2745 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2746 if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2747 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2748 if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2749 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
2751 if (evIns.count() == 1)
2753 fEventsIn.ctrl = &fEventsIn.data[j];
2754 fEventsIn.ctrlIndex = j;
2756 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2757 needsCtrlIn = true;
2759 else
2761 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2762 fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2764 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2766 fEventsIn.ctrl = &fEventsIn.data[j];
2767 fEventsIn.ctrlIndex = j;
2771 else if (LV2_IS_PORT_OUTPUT(portTypes))
2773 const uint32_t j = iEvOut++;
2775 fDescriptor->connect_port(fHandle, i, fEventsOut.data[j].event);
2777 if (fHandle2 != nullptr)
2778 fDescriptor->connect_port(fHandle2, i, fEventsOut.data[j].event);
2780 fEventsOut.data[j].rindex = i;
2782 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2783 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2784 if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2785 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2786 if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2787 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
2789 if (evOuts.count() == 1)
2791 fEventsOut.ctrl = &fEventsOut.data[j];
2792 fEventsOut.ctrlIndex = j;
2794 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2795 needsCtrlOut = true;
2797 else
2799 if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2800 fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2802 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2804 fEventsOut.ctrl = &fEventsOut.data[j];
2805 fEventsOut.ctrlIndex = j;
2809 else
2810 carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
2812 else if (LV2_IS_PORT_MIDI_LL(portTypes))
2814 if (LV2_IS_PORT_INPUT(portTypes))
2816 const uint32_t j = iEvIn++;
2818 fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].midi);
2820 if (fHandle2 != nullptr)
2821 fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].midi);
2823 fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2824 fEventsIn.data[j].rindex = i;
2826 if (evIns.count() == 1)
2828 needsCtrlIn = true;
2829 fEventsIn.ctrl = &fEventsIn.data[j];
2830 fEventsIn.ctrlIndex = j;
2832 else
2834 fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2836 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2838 fEventsIn.ctrl = &fEventsIn.data[j];
2839 fEventsIn.ctrlIndex = j;
2843 else if (LV2_IS_PORT_OUTPUT(portTypes))
2845 const uint32_t j = iEvOut++;
2847 fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].midi);
2849 if (fHandle2 != nullptr)
2850 fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].midi);
2852 fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2853 fEventsOut.data[j].rindex = i;
2855 if (evOuts.count() == 1)
2857 needsCtrlOut = true;
2858 fEventsOut.ctrl = &fEventsOut.data[j];
2859 fEventsOut.ctrlIndex = j;
2861 else
2863 fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2865 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2867 fEventsOut.ctrl = &fEventsOut.data[j];
2868 fEventsOut.ctrlIndex = j;
2872 else
2873 carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
2875 else if (LV2_IS_PORT_CONTROL(portTypes))
2877 const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties);
2878 const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
2879 const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
2881 const uint32_t j = iCtrl++;
2882 pData->param.data[j].index = static_cast<int32_t>(j);
2883 pData->param.data[j].rindex = static_cast<int32_t>(i);
2885 float min, max, def, step, stepSmall, stepLarge;
2887 // min value
2888 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
2889 min = portPoints.Minimum;
2890 else
2891 min = 0.0f;
2893 // max value
2894 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
2895 max = portPoints.Maximum;
2896 else
2897 max = 1.0f;
2899 if (LV2_IS_PORT_SAMPLE_RATE(portProps))
2901 min *= sampleRate;
2902 max *= sampleRate;
2903 pData->param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
2906 // stupid hack for ir.lv2 (broken plugin)
2907 if (std::strcmp(fRdfDescriptor->URI, "http://factorial.hu/plugins/lv2/ir") == 0 && std::strncmp(fRdfDescriptor->Ports[i].Name, "FileHash", 8) == 0)
2909 min = 0.0f;
2910 max = (float)0xffffff;
2913 if (min >= max)
2915 carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", fRdfDescriptor->Ports[i].Name);
2916 max = min + 0.1f;
2919 // default value
2920 if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
2922 def = portPoints.Default;
2924 else
2926 // no default value
2927 if (min < 0.0f && max > 0.0f)
2928 def = 0.0f;
2929 else
2930 def = min;
2933 if (def < min)
2934 def = min;
2935 else if (def > max)
2936 def = max;
2938 if (LV2_IS_PORT_TOGGLED(portProps))
2940 step = max - min;
2941 stepSmall = step;
2942 stepLarge = step;
2943 pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
2945 else if (LV2_IS_PORT_INTEGER(portProps))
2947 step = 1.0f;
2948 stepSmall = 1.0f;
2949 stepLarge = 10.0f;
2950 pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
2952 else
2954 float range = max - min;
2955 step = range/100.0f;
2956 stepSmall = range/1000.0f;
2957 stepLarge = range/10.0f;
2960 if (LV2_IS_PORT_INPUT(portTypes))
2962 pData->param.data[j].type = PARAMETER_INPUT;
2964 if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
2966 carla_stderr("Plugin has latency input port, this should not happen!");
2968 else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
2970 def = sampleRate;
2971 step = 1.0f;
2972 stepSmall = 1.0f;
2973 stepLarge = 1.0f;
2974 pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
2976 else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
2978 pData->param.special[j] = PARAMETER_SPECIAL_FREEWHEEL;
2980 else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
2982 pData->param.special[j] = PARAMETER_SPECIAL_TIME;
2984 else
2986 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
2987 pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
2988 needsCtrlIn = true;
2990 if (! LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) &&
2991 ! LV2_IS_PORT_ENUMERATION(portProps) &&
2992 ! LV2_IS_PORT_EXPENSIVE(portProps) &&
2993 ! LV2_IS_PORT_NOT_AUTOMATIC(portProps) &&
2994 ! LV2_IS_PORT_NOT_ON_GUI(portProps) &&
2995 ! LV2_IS_PORT_TRIGGER(portProps))
2997 pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED;
3001 // MIDI CC value
3002 const LV2_RDF_PortMidiMap& portMidiMap(fRdfDescriptor->Ports[i].MidiMap);
3004 if (LV2_IS_PORT_MIDI_MAP_CC(portMidiMap.Type))
3006 if (portMidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(portMidiMap.Number))
3007 pData->param.data[j].mappedControlIndex = static_cast<int16_t>(portMidiMap.Number);
3010 else if (LV2_IS_PORT_OUTPUT(portTypes))
3012 pData->param.data[j].type = PARAMETER_OUTPUT;
3014 if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
3016 min = 0.0f;
3017 max = sampleRate;
3018 def = 0.0f;
3019 step = 1.0f;
3020 stepSmall = 1.0f;
3021 stepLarge = 1.0f;
3022 pData->param.special[j] = PARAMETER_SPECIAL_LATENCY;
3023 CARLA_SAFE_ASSERT_INT2(fLatencyIndex == static_cast<int32_t>(j), fLatencyIndex, j);
3025 else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
3027 def = sampleRate;
3028 step = 1.0f;
3029 stepSmall = 1.0f;
3030 stepLarge = 1.0f;
3031 pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
3033 else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
3035 carla_stderr("Plugin has freewheeling output port, this should not happen!");
3037 else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
3039 pData->param.special[j] = PARAMETER_SPECIAL_TIME;
3041 else
3043 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
3044 pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
3045 needsCtrlOut = true;
3048 else
3050 pData->param.data[j].type = PARAMETER_UNKNOWN;
3051 carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)");
3054 // extra parameter hints
3055 if (LV2_IS_PORT_LOGARITHMIC(portProps))
3056 pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
3058 if (LV2_IS_PORT_TRIGGER(portProps))
3059 pData->param.data[j].hints |= PARAMETER_IS_TRIGGER;
3061 if (LV2_IS_PORT_STRICT_BOUNDS(portProps))
3062 pData->param.data[j].hints |= PARAMETER_IS_STRICT_BOUNDS;
3064 if (LV2_IS_PORT_ENUMERATION(portProps))
3065 pData->param.data[j].hints |= PARAMETER_USES_SCALEPOINTS;
3067 // check if parameter is not enabled or automatable
3068 if (LV2_IS_PORT_NOT_ON_GUI(portProps))
3069 pData->param.data[j].hints &= ~(PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMATABLE);
3070 else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) || LV2_IS_PORT_EXPENSIVE(portProps))
3071 pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMATABLE;
3072 else if (LV2_IS_PORT_NOT_AUTOMATIC(portProps) || LV2_IS_PORT_NON_AUTOMATABLE(portProps))
3073 pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMATABLE;
3075 pData->param.ranges[j].min = min;
3076 pData->param.ranges[j].max = max;
3077 pData->param.ranges[j].def = def;
3078 pData->param.ranges[j].step = step;
3079 pData->param.ranges[j].stepSmall = stepSmall;
3080 pData->param.ranges[j].stepLarge = stepLarge;
3082 // Start parameters in their default values (except freewheel, which is off by default)
3083 if (pData->param.data[j].type == PARAMETER_INPUT && pData->param.special[j] == PARAMETER_SPECIAL_FREEWHEEL)
3084 fParamBuffers[j] = min;
3085 else
3086 fParamBuffers[j] = def;
3088 fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);
3090 if (fHandle2 != nullptr)
3091 fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
3093 else
3095 // Port Type not supported, but it's optional anyway
3096 fDescriptor->connect_port(fHandle, i, nullptr);
3098 if (fHandle2 != nullptr)
3099 fDescriptor->connect_port(fHandle2, i, nullptr);
3103 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
3105 const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
3107 switch (rdfParam.Type)
3109 case LV2_PARAMETER_TYPE_BOOL:
3110 case LV2_PARAMETER_TYPE_INT:
3111 // case LV2_PARAMETER_TYPE_LONG:
3112 case LV2_PARAMETER_TYPE_FLOAT:
3113 case LV2_PARAMETER_TYPE_DOUBLE:
3114 break;
3115 default:
3116 continue;
3119 const LV2_RDF_PortPoints& portPoints(rdfParam.Points);
3121 const uint32_t j = iCtrl++;
3122 pData->param.data[j].index = static_cast<int32_t>(j);
3123 pData->param.data[j].rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
3125 float min, max, def, step, stepSmall, stepLarge;
3127 // min value
3128 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
3129 min = portPoints.Minimum;
3130 else
3131 min = 0.0f;
3133 // max value
3134 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
3135 max = portPoints.Maximum;
3136 else
3137 max = 1.0f;
3139 if (min >= max)
3141 carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", rdfParam.Label);
3142 max = min + 0.1f;
3145 // default value
3146 if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
3148 def = portPoints.Default;
3150 else
3152 // no default value
3153 if (min < 0.0f && max > 0.0f)
3154 def = 0.0f;
3155 else
3156 def = min;
3159 if (def < min)
3160 def = min;
3161 else if (def > max)
3162 def = max;
3164 switch (rdfParam.Type)
3166 case LV2_PARAMETER_TYPE_BOOL:
3167 step = max - min;
3168 stepSmall = step;
3169 stepLarge = step;
3170 pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
3171 break;
3173 case LV2_PARAMETER_TYPE_INT:
3174 case LV2_PARAMETER_TYPE_LONG:
3175 step = 1.0f;
3176 stepSmall = 1.0f;
3177 stepLarge = 10.0f;
3178 pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
3179 break;
3181 default:
3182 const float range = max - min;
3183 step = range/100.0f;
3184 stepSmall = range/1000.0f;
3185 stepLarge = range/10.0f;
3186 break;
3189 if (rdfParam.Flags & LV2_PARAMETER_FLAG_INPUT)
3191 pData->param.data[j].type = PARAMETER_INPUT;
3192 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
3193 pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
3194 pData->param.data[j].hints |= PARAMETER_IS_NOT_SAVED;
3195 needsCtrlIn = true;
3197 if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
3198 hasPatchParameterOutputs = true;
3200 if (LV2_IS_PORT_MIDI_MAP_CC(rdfParam.MidiMap.Type))
3202 if (rdfParam.MidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(rdfParam.MidiMap.Number))
3203 pData->param.data[j].mappedControlIndex = static_cast<int16_t>(rdfParam.MidiMap.Number);
3206 else if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
3208 pData->param.data[j].type = PARAMETER_OUTPUT;
3209 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
3210 pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
3211 needsCtrlOut = true;
3212 hasPatchParameterOutputs = true;
3215 pData->param.ranges[j].min = min;
3216 pData->param.ranges[j].max = max;
3217 pData->param.ranges[j].def = def;
3218 pData->param.ranges[j].step = step;
3219 pData->param.ranges[j].stepSmall = stepSmall;
3220 pData->param.ranges[j].stepLarge = stepLarge;
3222 fParamBuffers[j] = def;
3225 if (needsCtrlIn)
3227 portName.clear();
3229 if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
3231 portName = pData->name;
3232 portName += ":";
3235 portName += "events-in";
3236 portName.truncate(portNameSize);
3238 pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
3239 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3240 pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
3241 #endif
3244 if (needsCtrlOut)
3246 portName.clear();
3248 if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
3250 portName = pData->name;
3251 portName += ":";
3254 portName += "events-out";
3255 portName.truncate(portNameSize);
3257 pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
3260 if (fExt.worker != nullptr && fEventsIn.ctrl != nullptr)
3262 fAtomBufferWorkerIn.createBuffer(eventBufferSize, true);
3263 fAtomBufferWorkerResp.createBuffer(eventBufferSize, true);
3264 fAtomBufferRealtimeSize = fAtomBufferWorkerIn.getSize(); // actual buffer size will be next power of 2
3265 fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize));
3266 fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferRealtimeSize];
3267 carla_mlock(fAtomBufferRealtime, fAtomBufferRealtimeSize);
3270 if (fRdfDescriptor->ParameterCount > 0 ||
3271 (fUI.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
3273 fAtomBufferEvIn.createBuffer(eventBufferSize, true);
3275 if (fAtomBufferRealtimeSize == 0)
3277 fAtomBufferRealtimeSize = fAtomBufferEvIn.getSize(); // actual buffer size will be next power of 2
3278 fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize));
3279 carla_mlock(fAtomBufferRealtime, fAtomBufferRealtimeSize);
3283 if (hasPatchParameterOutputs ||
3284 (fUI.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
3286 fAtomBufferUiOut.createBuffer(std::min(eventBufferSize*32, 1638400U), true);
3287 fAtomBufferUiOutTmpData = new uint8_t[fAtomBufferUiOut.getSize()];
3290 if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port == nullptr)
3291 fEventsIn.ctrl->port = pData->event.portIn;
3293 if (fEventsOut.ctrl != nullptr && fEventsOut.ctrl->port == nullptr)
3294 fEventsOut.ctrl->port = pData->event.portOut;
3296 if (fEventsIn.ctrl != nullptr && fExt.midnam != nullptr)
3298 if (char* const midnam = fExt.midnam->midnam(fHandle))
3300 fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd",
3301 midnam, "text/xml");
3302 if (fExt.midnam->free != nullptr)
3303 fExt.midnam->free(midnam);
3307 if (forcedStereoIn || forcedStereoOut)
3308 pData->options |= PLUGIN_OPTION_FORCE_STEREO;
3309 else
3310 pData->options &= ~PLUGIN_OPTION_FORCE_STEREO;
3312 // plugin hints
3313 pData->hints = (pData->hints & PLUGIN_HAS_INLINE_DISPLAY) ? PLUGIN_HAS_INLINE_DISPLAY : 0
3314 | (pData->hints & PLUGIN_NEEDS_UI_MAIN_THREAD) ? PLUGIN_NEEDS_UI_MAIN_THREAD : 0;
3316 if (isRealtimeSafe())
3317 pData->hints |= PLUGIN_IS_RTSAFE;
3319 if (fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty())
3321 pData->hints |= PLUGIN_HAS_CUSTOM_UI;
3323 if (fUI.type == UI::TYPE_EMBED)
3325 switch (fUI.rdfDescriptor->Type)
3327 case LV2_UI_GTK2:
3328 case LV2_UI_GTK3:
3329 case LV2_UI_QT4:
3330 case LV2_UI_QT5:
3331 case LV2_UI_EXTERNAL:
3332 case LV2_UI_OLD_EXTERNAL:
3333 break;
3334 default:
3335 pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI;
3336 break;
3340 if (fUI.type == UI::TYPE_EMBED || fUI.type == UI::TYPE_EXTERNAL)
3341 pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
3342 else if (fFilePathURI.isNotEmpty())
3343 pData->hints |= PLUGIN_HAS_CUSTOM_UI_USING_FILE_OPEN;
3346 if (LV2_IS_GENERATOR(fRdfDescriptor->Type[0], fRdfDescriptor->Type[1]))
3347 pData->hints |= PLUGIN_IS_SYNTH;
3349 if (aOuts > 0 && (aIns == aOuts || aIns == 1))
3350 pData->hints |= PLUGIN_CAN_DRYWET;
3352 if (aOuts > 0)
3353 pData->hints |= PLUGIN_CAN_VOLUME;
3355 if (aOuts >= 2 && aOuts % 2 == 0)
3356 pData->hints |= PLUGIN_CAN_BALANCE;
3358 // extra plugin hints
3359 pData->extraHints = 0x0;
3361 // check initial latency
3362 findInitialLatencyValue(aIns, cvIns, aOuts, cvOuts);
3364 bufferSizeChanged(pData->engine->getBufferSize());
3365 reloadPrograms(true);
3367 evIns.clear();
3368 evOuts.clear();
3370 if (pData->active)
3371 activate();
3373 carla_debug("CarlaPluginLV2::reload() - end");
3376 void findInitialLatencyValue(const uint32_t aIns,
3377 const uint32_t cvIns,
3378 const uint32_t aOuts,
3379 const uint32_t cvOuts) const
3381 if (fLatencyIndex < 0)
3382 return;
3384 // we need to pre-run the plugin so it can update its latency control-port
3385 const uint32_t bufferSize = static_cast<uint32_t>(fLv2Options.nominalBufferSize);
3387 float* tmpIn[96];
3388 float* tmpOut[96];
3391 uint32_t i=0;
3392 for (; i < aIns; ++i)
3394 tmpIn[i] = new float[bufferSize];
3395 carla_zeroFloats(tmpIn[i], bufferSize);
3397 try {
3398 fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, tmpIn[i]);
3399 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio input");
3402 for (uint32_t j=0; j < cvIns; ++i, ++j)
3404 tmpIn[i] = new float[bufferSize];
3405 carla_zeroFloats(tmpIn[i], bufferSize);
3407 try {
3408 fDescriptor->connect_port(fHandle, pData->cvIn.ports[j].rindex, tmpIn[i]);
3409 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv input");
3414 uint32_t i=0;
3415 for (; i < aOuts; ++i)
3417 tmpOut[i] = new float[bufferSize];
3418 carla_zeroFloats(tmpOut[i], bufferSize);
3420 try {
3421 fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, tmpOut[i]);
3422 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio output");
3425 for (uint32_t j=0; j < cvOuts; ++i, ++j)
3427 tmpOut[i] = new float[bufferSize];
3428 carla_zeroFloats(tmpOut[i], bufferSize);
3430 try {
3431 fDescriptor->connect_port(fHandle, pData->cvOut.ports[j].rindex, tmpOut[i]);
3432 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv output");
3436 if (fDescriptor->activate != nullptr)
3438 try {
3439 fDescriptor->activate(fHandle);
3440 } CARLA_SAFE_EXCEPTION("LV2 latency activate");
3443 try {
3444 fDescriptor->run(fHandle, bufferSize);
3445 } CARLA_SAFE_EXCEPTION("LV2 latency run");
3447 if (fDescriptor->deactivate != nullptr)
3449 try {
3450 fDescriptor->deactivate(fHandle);
3451 } CARLA_SAFE_EXCEPTION("LV2 latency deactivate");
3454 // done, let's get the value
3455 if (const uint32_t latency = getLatencyInFrames())
3457 pData->client->setLatency(latency);
3458 #ifndef BUILD_BRIDGE
3459 pData->latency.recreateBuffers(std::max(aIns, aOuts), latency);
3460 #endif
3463 for (uint32_t i=0; i < aIns + cvIns; ++i)
3464 delete[] tmpIn[i];
3466 for (uint32_t i=0; i < aOuts + cvOuts; ++i)
3467 delete[] tmpOut[i];
3470 void reloadPrograms(const bool doInit) override
3472 carla_debug("CarlaPluginLV2::reloadPrograms(%s)", bool2str(doInit));
3473 const uint32_t oldCount = pData->midiprog.count;
3474 const int32_t current = pData->midiprog.current;
3476 // special LV2 programs handling
3477 if (doInit)
3479 pData->prog.clear();
3481 const uint32_t presetCount(fRdfDescriptor->PresetCount);
3483 if (presetCount > 0)
3485 pData->prog.createNew(presetCount);
3487 for (uint32_t i=0; i < presetCount; ++i)
3488 pData->prog.names[i] = carla_strdup(fRdfDescriptor->Presets[i].Label);
3492 // Delete old programs
3493 pData->midiprog.clear();
3495 // Query new programs
3496 uint32_t newCount = 0;
3497 if (fExt.programs != nullptr && fExt.programs->get_program != nullptr && fExt.programs->select_program != nullptr)
3499 for (; fExt.programs->get_program(fHandle, newCount);)
3500 ++newCount;
3503 if (newCount > 0)
3505 pData->midiprog.createNew(newCount);
3507 // Update data
3508 for (uint32_t i=0; i < newCount; ++i)
3510 const LV2_Program_Descriptor* const pdesc(fExt.programs->get_program(fHandle, i));
3511 CARLA_SAFE_ASSERT_CONTINUE(pdesc != nullptr);
3512 CARLA_SAFE_ASSERT(pdesc->name != nullptr);
3514 pData->midiprog.data[i].bank = pdesc->bank;
3515 pData->midiprog.data[i].program = pdesc->program;
3516 pData->midiprog.data[i].name = carla_strdup(pdesc->name);
3520 if (doInit)
3522 if (newCount > 0)
3524 setMidiProgram(0, false, false, false, true);
3526 else if (fHasLoadDefaultState)
3528 // load default state
3529 if (LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fDescriptor->URI,
3530 (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data))
3532 lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
3534 if (fHandle2 != nullptr)
3535 lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
3537 lilv_state_free(state);
3541 else
3543 // Check if current program is invalid
3544 bool programChanged = false;
3546 if (newCount == oldCount+1)
3548 // one midi program added, probably created by user
3549 pData->midiprog.current = static_cast<int32_t>(oldCount);
3550 programChanged = true;
3552 else if (current < 0 && newCount > 0)
3554 // programs exist now, but not before
3555 pData->midiprog.current = 0;
3556 programChanged = true;
3558 else if (current >= 0 && newCount == 0)
3560 // programs existed before, but not anymore
3561 pData->midiprog.current = -1;
3562 programChanged = true;
3564 else if (current >= static_cast<int32_t>(newCount))
3566 // current midi program > count
3567 pData->midiprog.current = 0;
3568 programChanged = true;
3570 else
3572 // no change
3573 pData->midiprog.current = current;
3576 if (programChanged)
3577 setMidiProgram(pData->midiprog.current, true, true, true, false);
3579 pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
3583 // -------------------------------------------------------------------
3584 // Plugin processing
3586 void activate() noexcept override
3588 CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
3589 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
3591 if (fDescriptor->activate != nullptr)
3593 try {
3594 fDescriptor->activate(fHandle);
3595 } CARLA_SAFE_EXCEPTION("LV2 activate");
3597 if (fHandle2 != nullptr)
3599 try {
3600 fDescriptor->activate(fHandle2);
3601 } CARLA_SAFE_EXCEPTION("LV2 activate #2");
3605 fFirstActive = true;
3608 void deactivate() noexcept override
3610 CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
3611 CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
3613 if (fDescriptor->deactivate != nullptr)
3615 try {
3616 fDescriptor->deactivate(fHandle);
3617 } CARLA_SAFE_EXCEPTION("LV2 deactivate");
3619 if (fHandle2 != nullptr)
3621 try {
3622 fDescriptor->deactivate(fHandle2);
3623 } CARLA_SAFE_EXCEPTION("LV2 deactivate #2");
3628 void process(const float* const* const audioIn, float** const audioOut,
3629 const float* const* const cvIn, float** const cvOut, const uint32_t frames) override
3631 // --------------------------------------------------------------------------------------------------------
3632 // Check if active
3634 if (! pData->active)
3636 // disable any output sound
3637 for (uint32_t i=0; i < pData->audioOut.count; ++i)
3638 carla_zeroFloats(audioOut[i], frames);
3639 for (uint32_t i=0; i < pData->cvOut.count; ++i)
3640 carla_zeroFloats(cvOut[i], frames);
3641 return;
3644 // --------------------------------------------------------------------------------------------------------
3645 // Event itenerators from different APIs (input)
3647 for (uint32_t i=0; i < fEventsIn.count; ++i)
3649 if (fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM)
3651 lv2_atom_buffer_reset(fEventsIn.data[i].atom, true);
3652 lv2_atom_buffer_begin(&fEventsIn.iters[i].atom, fEventsIn.data[i].atom);
3654 else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_EVENT)
3656 lv2_event_buffer_reset(fEventsIn.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[i].event->data);
3657 lv2_event_begin(&fEventsIn.iters[i].event, fEventsIn.data[i].event);
3659 else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
3661 fEventsIn.data[i].midi.event_count = 0;
3662 fEventsIn.data[i].midi.size = 0;
3663 LV2_MIDIState& midiState(fEventsIn.iters[i].midiState);
3664 midiState.midi = &fEventsIn.data[i].midi;
3665 midiState.frame_count = frames;
3666 midiState.position = 0;
3670 for (uint32_t i=0; i < fEventsOut.count; ++i)
3672 if (fEventsOut.data[i].type & CARLA_EVENT_DATA_ATOM)
3674 lv2_atom_buffer_reset(fEventsOut.data[i].atom, false);
3676 else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_EVENT)
3678 lv2_event_buffer_reset(fEventsOut.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[i].event->data);
3680 else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
3682 // not needed
3686 // --------------------------------------------------------------------------------------------------------
3687 // Check if needs reset
3689 if (pData->needsReset)
3691 if (fEventsIn.ctrl != nullptr && (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) != 0)
3693 const uint32_t j = fEventsIn.ctrlIndex;
3694 CARLA_ASSERT(j < fEventsIn.count);
3696 uint8_t midiData[3] = { 0, 0, 0 };
3698 if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
3700 for (uint8_t i=0; i < MAX_MIDI_CHANNELS; ++i)
3702 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
3703 midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
3705 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3706 lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
3708 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3709 lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
3711 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3712 lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
3714 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
3715 midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
3717 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3718 lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
3720 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3721 lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
3723 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3724 lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
3727 else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
3729 for (uint8_t k=0; k < MAX_MIDI_NOTE; ++k)
3731 midiData[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
3732 midiData[1] = k;
3734 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3735 lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiData);
3737 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3738 lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiData);
3740 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3741 lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiData);
3746 pData->needsReset = false;
3749 // --------------------------------------------------------------------------------------------------------
3750 // TimeInfo
3752 const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
3754 if (fFirstActive || fLastTimeInfo != timeInfo)
3756 bool doPostRt;
3757 int32_t rindex;
3759 const double barBeat = static_cast<double>(timeInfo.bbt.beat - 1)
3760 + (timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat);
3762 // update input ports
3763 for (uint32_t k=0; k < pData->param.count; ++k)
3765 if (pData->param.data[k].type != PARAMETER_INPUT)
3766 continue;
3767 if (pData->param.special[k] != PARAMETER_SPECIAL_TIME)
3768 continue;
3770 doPostRt = false;
3771 rindex = pData->param.data[k].rindex;
3773 CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount));
3775 switch (fRdfDescriptor->Ports[rindex].Designation)
3777 // Non-BBT
3778 case LV2_PORT_DESIGNATION_TIME_SPEED:
3779 if (fLastTimeInfo.playing != timeInfo.playing)
3781 fParamBuffers[k] = timeInfo.playing ? 1.0f : 0.0f;
3782 doPostRt = true;
3784 break;
3786 case LV2_PORT_DESIGNATION_TIME_FRAME:
3787 if (fLastTimeInfo.frame != timeInfo.frame)
3789 fParamBuffers[k] = static_cast<float>(timeInfo.frame);
3790 doPostRt = true;
3792 break;
3794 case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
3795 break;
3797 // BBT
3798 case LV2_PORT_DESIGNATION_TIME_BAR:
3799 if (timeInfo.bbt.valid && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
3801 fParamBuffers[k] = static_cast<float>(timeInfo.bbt.bar - 1);
3802 doPostRt = true;
3804 break;
3806 case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
3807 if (timeInfo.bbt.valid && (carla_isNotEqual(fLastTimeInfo.bbt.tick, timeInfo.bbt.tick) ||
3808 fLastTimeInfo.bbt.beat != timeInfo.bbt.beat))
3810 fParamBuffers[k] = static_cast<float>(barBeat);
3811 doPostRt = true;
3813 break;
3815 case LV2_PORT_DESIGNATION_TIME_BEAT:
3816 if (timeInfo.bbt.valid && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
3818 fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beat - 1);
3819 doPostRt = true;
3821 break;
3823 case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
3824 if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatType, timeInfo.bbt.beatType))
3826 fParamBuffers[k] = timeInfo.bbt.beatType;
3827 doPostRt = true;
3829 break;
3830 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
3831 if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerBar, timeInfo.bbt.beatsPerBar))
3833 fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
3834 doPostRt = true;
3836 break;
3838 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
3839 if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerMinute, timeInfo.bbt.beatsPerMinute))
3841 fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beatsPerMinute);
3842 doPostRt = true;
3844 break;
3846 case LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT:
3847 if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.ticksPerBeat, timeInfo.bbt.ticksPerBeat))
3849 fParamBuffers[k] = static_cast<float>(timeInfo.bbt.ticksPerBeat);
3850 doPostRt = true;
3852 break;
3855 if (doPostRt)
3856 pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
3859 for (uint32_t i=0; i < fEventsIn.count; ++i)
3861 if ((fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM) == 0 || (fEventsIn.data[i].type & CARLA_EVENT_TYPE_TIME) == 0)
3862 continue;
3864 uint8_t timeInfoBuf[256];
3865 LV2_Atom_Forge atomForge;
3866 initAtomForge(atomForge);
3867 lv2_atom_forge_set_buffer(&atomForge, timeInfoBuf, sizeof(timeInfoBuf));
3869 LV2_Atom_Forge_Frame forgeFrame;
3870 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridTimePosition);
3872 lv2_atom_forge_key(&atomForge, kUridTimeSpeed);
3873 lv2_atom_forge_float(&atomForge, timeInfo.playing ? 1.0f : 0.0f);
3875 lv2_atom_forge_key(&atomForge, kUridTimeFrame);
3876 lv2_atom_forge_long(&atomForge, static_cast<int64_t>(timeInfo.frame));
3878 if (timeInfo.bbt.valid)
3880 lv2_atom_forge_key(&atomForge, kUridTimeBar);
3881 lv2_atom_forge_long(&atomForge, timeInfo.bbt.bar - 1);
3883 lv2_atom_forge_key(&atomForge, kUridTimeBarBeat);
3884 lv2_atom_forge_float(&atomForge, static_cast<float>(barBeat));
3886 lv2_atom_forge_key(&atomForge, kUridTimeBeat);
3887 lv2_atom_forge_double(&atomForge, timeInfo.bbt.beat - 1);
3889 lv2_atom_forge_key(&atomForge, kUridTimeBeatUnit);
3890 lv2_atom_forge_int(&atomForge, static_cast<int32_t>(timeInfo.bbt.beatType));
3892 lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerBar);
3893 lv2_atom_forge_float(&atomForge, timeInfo.bbt.beatsPerBar);
3895 lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerMinute);
3896 lv2_atom_forge_float(&atomForge, static_cast<float>(timeInfo.bbt.beatsPerMinute));
3898 lv2_atom_forge_key(&atomForge, kUridTimeTicksPerBeat);
3899 lv2_atom_forge_double(&atomForge, timeInfo.bbt.ticksPerBeat);
3902 lv2_atom_forge_pop(&atomForge, &forgeFrame);
3904 LV2_Atom* const atom((LV2_Atom*)timeInfoBuf);
3905 CARLA_SAFE_ASSERT_BREAK(atom->size < 256);
3907 // send only deprecated blank object for now
3908 lv2_atom_buffer_write(&fEventsIn.iters[i].atom, 0, 0, kUridAtomBlank, atom->size, LV2_ATOM_BODY_CONST(atom));
3910 // for atom:object
3911 //lv2_atom_buffer_write(&fEventsIn.iters[i].atom, 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom));
3914 pData->postRtEvents.trySplice();
3916 fLastTimeInfo = timeInfo;
3919 // --------------------------------------------------------------------------------------------------------
3920 // Event Input and Processing
3922 if (fEventsIn.ctrl != nullptr)
3924 // ----------------------------------------------------------------------------------------------------
3925 // Message Input
3927 if (fAtomBufferEvIn.tryLock())
3929 if (fAtomBufferEvIn.isDataAvailableForReading())
3931 uint32_t j, portIndex;
3932 LV2_Atom* const atom = fAtomBufferRealtime;
3933 atom->size = fAtomBufferRealtimeSize;
3935 for (; fAtomBufferEvIn.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize)
3937 j = (portIndex < fEventsIn.count) ? portIndex : fEventsIn.ctrlIndex;
3939 if (! lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)))
3941 carla_stderr2("Event input buffer full, at least 1 message lost");
3942 continue;
3945 inspectAtomForParameterChange(atom);
3949 fAtomBufferEvIn.unlock();
3952 // ----------------------------------------------------------------------------------------------------
3953 // MIDI Input (External)
3955 if (pData->extNotes.mutex.tryLock())
3957 if ((fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) == 0)
3959 // does not handle MIDI
3960 pData->extNotes.data.clear();
3962 else
3964 const uint32_t j = fEventsIn.ctrlIndex;
3966 for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
3968 const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
3969 CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
3971 uint8_t midiEvent[3];
3972 midiEvent[0] = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
3973 midiEvent[1] = note.note;
3974 midiEvent[2] = note.velo;
3976 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3977 lv2_atom_buffer_write(&fEventsIn.iters[j].atom, 0, 0, kUridMidiEvent, 3, midiEvent);
3979 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3980 lv2_event_write(&fEventsIn.iters[j].event, 0, 0, kUridMidiEvent, 3, midiEvent);
3982 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3983 lv2midi_put_event(&fEventsIn.iters[j].midiState, 0.0, 3, midiEvent);
3986 pData->extNotes.data.clear();
3989 pData->extNotes.mutex.unlock();
3991 } // End of MIDI Input (External)
3993 // ----------------------------------------------------------------------------------------------------
3994 // Event Input (System)
3996 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3997 bool allNotesOffSent = false;
3998 #endif
3999 bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
4001 uint32_t startTime = 0;
4002 uint32_t timeOffset = 0;
4003 uint32_t nextBankId;
4005 if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
4006 nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
4007 else
4008 nextBankId = 0;
4010 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4011 if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr)
4012 pData->event.cvSourcePorts->initPortBuffers(cvIn + pData->cvIn.count, frames, isSampleAccurate, pData->event.portIn);
4013 #endif
4015 const uint32_t numEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
4017 for (uint32_t i=0; i < numEvents; ++i)
4019 EngineEvent& event(fEventsIn.ctrl->port->getEvent(i));
4021 uint32_t eventTime = event.time;
4022 CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime < frames, eventTime, frames);
4024 if (eventTime < timeOffset)
4026 carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
4027 eventTime, timeOffset, pData->name);
4028 eventTime = timeOffset;
4031 if (isSampleAccurate && eventTime > timeOffset)
4033 if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset))
4035 startTime = 0;
4036 timeOffset = eventTime;
4038 if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
4039 nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
4040 else
4041 nextBankId = 0;
4043 for (uint32_t j=0; j < fEventsIn.count; ++j)
4045 if (fEventsIn.data[j].type & CARLA_EVENT_DATA_ATOM)
4047 lv2_atom_buffer_reset(fEventsIn.data[j].atom, true);
4048 lv2_atom_buffer_begin(&fEventsIn.iters[j].atom, fEventsIn.data[j].atom);
4050 else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_EVENT)
4052 lv2_event_buffer_reset(fEventsIn.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[j].event->data);
4053 lv2_event_begin(&fEventsIn.iters[j].event, fEventsIn.data[j].event);
4055 else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
4057 fEventsIn.data[j].midi.event_count = 0;
4058 fEventsIn.data[j].midi.size = 0;
4059 fEventsIn.iters[j].midiState.position = eventTime;
4063 for (uint32_t j=0; j < fEventsOut.count; ++j)
4065 if (fEventsOut.data[j].type & CARLA_EVENT_DATA_ATOM)
4067 lv2_atom_buffer_reset(fEventsOut.data[j].atom, false);
4069 else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_EVENT)
4071 lv2_event_buffer_reset(fEventsOut.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[j].event->data);
4073 else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
4075 // not needed
4079 else
4081 startTime += timeOffset;
4085 switch (event.type)
4087 case kEngineEventTypeNull:
4088 break;
4090 case kEngineEventTypeControl: {
4091 EngineControlEvent& ctrlEvent(event.ctrl);
4093 switch (ctrlEvent.type)
4095 case kEngineControlEventTypeNull:
4096 break;
4098 case kEngineControlEventTypeParameter: {
4099 float value;
4101 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4102 // non-midi
4103 if (event.channel == kEngineEventNonMidiChannel)
4105 const uint32_t k = ctrlEvent.param;
4106 CARLA_SAFE_ASSERT_CONTINUE(k < pData->param.count);
4108 ctrlEvent.handled = true;
4109 value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
4110 setParameterValueRT(k, value, event.time, true);
4111 continue;
4114 // Control backend stuff
4115 if (event.channel == pData->ctrlChannel)
4117 if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
4119 ctrlEvent.handled = true;
4120 value = ctrlEvent.normalizedValue;
4121 setDryWetRT(value, true);
4123 else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
4125 ctrlEvent.handled = true;
4126 value = ctrlEvent.normalizedValue*127.0f/100.0f;
4127 setVolumeRT(value, true);
4129 else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
4131 float left, right;
4132 value = ctrlEvent.normalizedValue/0.5f - 1.0f;
4134 if (value < 0.0f)
4136 left = -1.0f;
4137 right = (value*2.0f)+1.0f;
4139 else if (value > 0.0f)
4141 left = (value*2.0f)-1.0f;
4142 right = 1.0f;
4144 else
4146 left = -1.0f;
4147 right = 1.0f;
4150 ctrlEvent.handled = true;
4151 setBalanceLeftRT(left, true);
4152 setBalanceRightRT(right, true);
4155 #endif
4156 // Control plugin parameters
4157 uint32_t k;
4158 for (k=0; k < pData->param.count; ++k)
4160 if (pData->param.data[k].midiChannel != event.channel)
4161 continue;
4162 if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
4163 continue;
4164 if (pData->param.data[k].type != PARAMETER_INPUT)
4165 continue;
4166 if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMATABLE) == 0)
4167 continue;
4169 ctrlEvent.handled = true;
4171 if (pData->param.data[k].mappedFlags & PARAMETER_MAPPING_MIDI_DELTA)
4172 value = pData->param.getFinalValueWithMidiDelta(k, fParamBuffers[k], ctrlEvent.midiValue);
4173 else
4174 value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
4176 setParameterValueRT(k, value, event.time, true);
4179 if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
4181 uint8_t midiData[3];
4182 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4183 midiData[1] = uint8_t(ctrlEvent.param);
4184 midiData[2] = uint8_t(ctrlEvent.normalizedValue*127.0f + 0.5f);
4186 const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4188 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4189 lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
4191 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4192 lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
4194 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4195 lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
4198 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4199 if (! ctrlEvent.handled)
4200 checkForMidiLearn(event);
4201 #endif
4202 break;
4203 } // case kEngineControlEventTypeParameter
4205 case kEngineControlEventTypeMidiBank:
4206 if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
4208 if (event.channel == pData->ctrlChannel)
4209 nextBankId = ctrlEvent.param;
4211 else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
4213 uint8_t midiData[3];
4214 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4215 midiData[1] = MIDI_CONTROL_BANK_SELECT;
4216 midiData[2] = uint8_t(ctrlEvent.param);
4218 const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4220 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4221 lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
4223 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4224 lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
4226 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4227 lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
4229 break;
4231 case kEngineControlEventTypeMidiProgram:
4232 if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
4234 if (event.channel == pData->ctrlChannel)
4236 const uint32_t nextProgramId(ctrlEvent.param);
4238 for (uint32_t k=0; k < pData->midiprog.count; ++k)
4240 if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
4242 setMidiProgramRT(k, true);
4243 break;
4248 else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
4250 uint8_t midiData[2];
4251 midiData[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4252 midiData[1] = uint8_t(ctrlEvent.param);
4254 const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4256 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4257 lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 2, midiData);
4259 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4260 lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 2, midiData);
4262 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4263 lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 2, midiData);
4265 break;
4267 case kEngineControlEventTypeAllSoundOff:
4268 if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
4270 const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4272 uint8_t midiData[3];
4273 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4274 midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
4275 midiData[2] = 0;
4277 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4278 lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
4280 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4281 lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
4283 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4284 lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
4286 break;
4288 case kEngineControlEventTypeAllNotesOff:
4289 if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
4291 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4292 if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
4294 allNotesOffSent = true;
4295 postponeRtAllNotesOff();
4297 #endif
4299 const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4301 uint8_t midiData[3];
4302 midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4303 midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
4304 midiData[2] = 0;
4306 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4307 lv2_atom_buffer_write(&fEventsIn.iters[fEventsIn.ctrlIndex].atom, mtime, 0, kUridMidiEvent, 3, midiData);
4309 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4310 lv2_event_write(&fEventsIn.iters[fEventsIn.ctrlIndex].event, mtime, 0, kUridMidiEvent, 3, midiData);
4312 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4313 lv2midi_put_event(&fEventsIn.iters[fEventsIn.ctrlIndex].midiState, mtime, 3, midiData);
4315 break;
4316 } // switch (ctrlEvent.type)
4317 break;
4318 } // case kEngineEventTypeControl
4320 case kEngineEventTypeMidi: {
4321 const EngineMidiEvent& midiEvent(event.midi);
4323 const uint8_t* const midiData = midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data;
4325 uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
4327 if ((status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON) && (pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES))
4328 continue;
4329 if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
4330 continue;
4331 if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
4332 continue;
4333 if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
4334 continue;
4335 if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
4336 continue;
4338 // Fix bad note-off (per LV2 spec)
4339 if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
4340 status = MIDI_STATUS_NOTE_OFF;
4342 const uint32_t j = fEventsIn.ctrlIndex;
4343 const uint32_t mtime = isSampleAccurate ? startTime : eventTime;
4345 // put back channel in data
4346 uint8_t midiData2[4]; // FIXME
4347 if (midiEvent.size > 4)
4348 continue;
4350 midiData2[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT));
4351 std::memcpy(midiData2+1, midiData+1, static_cast<std::size_t>(midiEvent.size-1));
4354 if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4355 lv2_atom_buffer_write(&fEventsIn.iters[j].atom, mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
4357 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4358 lv2_event_write(&fEventsIn.iters[j].event, mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
4360 else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4361 lv2midi_put_event(&fEventsIn.iters[j].midiState, mtime, midiEvent.size, midiData2);
4363 if (status == MIDI_STATUS_NOTE_ON)
4365 pData->postponeNoteOnRtEvent(true, event.channel, midiData[1], midiData[2]);
4367 else if (status == MIDI_STATUS_NOTE_OFF)
4369 pData->postponeNoteOffRtEvent(true, event.channel, midiData[1]);
4371 } break;
4372 } // switch (event.type)
4375 pData->postRtEvents.trySplice();
4377 if (frames > timeOffset)
4378 processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset);
4380 } // End of Event Input and Processing
4382 // --------------------------------------------------------------------------------------------------------
4383 // Plugin processing (no events)
4385 else
4387 processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0);
4389 } // End of Plugin processing (no events)
4391 // --------------------------------------------------------------------------------------------------------
4392 // Final work
4394 if (fEventsIn.ctrl != nullptr && fExt.worker != nullptr && fAtomBufferWorkerResp.tryLock())
4396 if (fAtomBufferWorkerResp.isDataAvailableForReading())
4398 uint32_t portIndex;
4399 LV2_Atom* const atom = fAtomBufferRealtime;
4400 atom->size = fAtomBufferRealtimeSize;
4402 for (; fAtomBufferWorkerResp.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize)
4404 CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerResp);
4405 fExt.worker->work_response(fHandle, atom->size, LV2_ATOM_BODY_CONST(atom));
4409 fAtomBufferWorkerResp.unlock();
4412 if (fExt.worker != nullptr && fExt.worker->end_run != nullptr)
4414 fExt.worker->end_run(fHandle);
4416 if (fHandle2 != nullptr)
4417 fExt.worker->end_run(fHandle2);
4420 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4421 // --------------------------------------------------------------------------------------------------------
4422 // Control Output
4424 if (pData->event.portOut != nullptr)
4426 uint8_t channel;
4427 uint16_t param;
4428 float value;
4430 for (uint32_t k=0; k < pData->param.count; ++k)
4432 if (pData->param.data[k].type != PARAMETER_OUTPUT)
4433 continue;
4435 if (fStrictBounds >= 0 && (pData->param.data[k].hints & PARAMETER_IS_STRICT_BOUNDS) != 0)
4436 // plugin is responsible to ensure correct bounds
4437 pData->param.ranges[k].fixValue(fParamBuffers[k]);
4439 if (pData->param.data[k].mappedControlIndex > 0)
4441 channel = pData->param.data[k].midiChannel;
4442 param = static_cast<uint16_t>(pData->param.data[k].mappedControlIndex);
4443 value = pData->param.ranges[k].getNormalizedValue(fParamBuffers[k]);
4444 pData->event.portOut->writeControlEvent(0, channel, kEngineControlEventTypeParameter,
4445 param, -1, value);
4448 } // End of Control Output
4449 #endif
4451 // --------------------------------------------------------------------------------------------------------
4452 // Events/MIDI Output
4454 for (uint32_t i=0; i < fEventsOut.count; ++i)
4456 uint32_t lastFrame = 0;
4457 Lv2EventData& evData(fEventsOut.data[i]);
4459 if (evData.type & CARLA_EVENT_DATA_ATOM)
4461 const LV2_Atom_Event* ev;
4462 LV2_Atom_Buffer_Iterator iter;
4464 uint8_t* data;
4465 lv2_atom_buffer_begin(&iter, evData.atom);
4467 for (;;)
4469 data = nullptr;
4470 ev = lv2_atom_buffer_get(&iter, &data);
4472 if (ev == nullptr || ev->body.size == 0 || data == nullptr)
4473 break;
4475 if (ev->body.type == kUridMidiEvent)
4477 if (evData.port != nullptr)
4479 CARLA_SAFE_ASSERT_CONTINUE(ev->time.frames >= 0);
4480 CARLA_SAFE_ASSERT_CONTINUE(ev->body.size < 0xFF);
4482 uint32_t currentFrame = static_cast<uint32_t>(ev->time.frames);
4483 if (currentFrame < lastFrame)
4484 currentFrame = lastFrame;
4485 else if (currentFrame >= frames)
4486 currentFrame = frames - 1;
4488 evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->body.size), data);
4491 else if (fAtomBufferUiOutTmpData != nullptr)
4493 fAtomBufferUiOut.put(&ev->body, evData.rindex);
4496 lv2_atom_buffer_increment(&iter);
4499 else if ((evData.type & CARLA_EVENT_DATA_EVENT) != 0 && evData.port != nullptr)
4501 const LV2_Event* ev;
4502 LV2_Event_Iterator iter;
4504 uint8_t* data;
4505 lv2_event_begin(&iter, evData.event);
4507 for (;;)
4509 data = nullptr;
4510 ev = lv2_event_get(&iter, &data);
4512 if (ev == nullptr || data == nullptr)
4513 break;
4515 uint32_t currentFrame = ev->frames;
4516 if (currentFrame < lastFrame)
4517 currentFrame = lastFrame;
4518 else if (currentFrame >= frames)
4519 currentFrame = frames - 1;
4521 if (ev->type == kUridMidiEvent)
4523 CARLA_SAFE_ASSERT_CONTINUE(ev->size < 0xFF);
4524 evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->size), data);
4527 lv2_event_increment(&iter);
4530 else if ((evData.type & CARLA_EVENT_DATA_MIDI_LL) != 0 && evData.port != nullptr)
4532 LV2_MIDIState state = { &evData.midi, frames, 0 };
4534 uint32_t eventSize;
4535 double eventTime;
4536 uchar* eventData;
4538 for (;;)
4540 eventSize = 0;
4541 eventTime = 0.0;
4542 eventData = nullptr;
4543 lv2midi_get_event(&state, &eventTime, &eventSize, &eventData);
4545 if (eventData == nullptr || eventSize == 0)
4546 break;
4548 CARLA_SAFE_ASSERT_CONTINUE(eventSize < 0xFF);
4549 CARLA_SAFE_ASSERT_CONTINUE(eventTime >= 0.0);
4551 evData.port->writeMidiEvent(static_cast<uint32_t>(eventTime), static_cast<uint8_t>(eventSize), eventData);
4552 lv2midi_step(&state);
4557 fFirstActive = false;
4559 // --------------------------------------------------------------------------------------------------------
4562 bool processSingle(const float* const* const audioIn, float** const audioOut,
4563 const float* const* const cvIn, float** const cvOut,
4564 const uint32_t frames, const uint32_t timeOffset)
4566 CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
4568 if (pData->audioIn.count > 0)
4570 CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
4571 CARLA_SAFE_ASSERT_RETURN(fAudioInBuffers != nullptr, false);
4573 if (pData->audioOut.count > 0)
4575 CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false);
4576 CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false);
4578 if (pData->cvIn.count > 0)
4580 CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false);
4582 if (pData->cvOut.count > 0)
4584 CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false);
4587 // --------------------------------------------------------------------------------------------------------
4588 // Try lock, silence otherwise
4590 #ifndef STOAT_TEST_BUILD
4591 if (pData->engine->isOffline())
4593 pData->singleMutex.lock();
4595 else
4596 #endif
4597 if (! pData->singleMutex.tryLock())
4599 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4601 for (uint32_t k=0; k < frames; ++k)
4602 audioOut[i][k+timeOffset] = 0.0f;
4604 for (uint32_t i=0; i < pData->cvOut.count; ++i)
4606 for (uint32_t k=0; k < frames; ++k)
4607 cvOut[i][k+timeOffset] = 0.0f;
4610 return false;
4613 // --------------------------------------------------------------------------------------------------------
4614 // Set audio buffers
4616 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4617 carla_copyFloats(fAudioInBuffers[i], audioIn[i]+timeOffset, frames);
4619 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4620 carla_zeroFloats(fAudioOutBuffers[i], frames);
4622 // --------------------------------------------------------------------------------------------------------
4623 // Set CV buffers
4625 for (uint32_t i=0; i < pData->cvIn.count; ++i)
4626 carla_copyFloats(fCvInBuffers[i], cvIn[i]+timeOffset, frames);
4628 for (uint32_t i=0; i < pData->cvOut.count; ++i)
4629 carla_zeroFloats(fCvOutBuffers[i], frames);
4631 // --------------------------------------------------------------------------------------------------------
4632 // Run plugin
4634 fDescriptor->run(fHandle, frames);
4636 if (fHandle2 != nullptr)
4637 fDescriptor->run(fHandle2, frames);
4639 // --------------------------------------------------------------------------------------------------------
4640 // Handle trigger parameters
4642 for (uint32_t k=0; k < pData->param.count; ++k)
4644 if (pData->param.data[k].type != PARAMETER_INPUT)
4645 continue;
4647 if (pData->param.data[k].hints & PARAMETER_IS_TRIGGER)
4649 if (carla_isNotEqual(fParamBuffers[k], pData->param.ranges[k].def))
4651 fParamBuffers[k] = pData->param.ranges[k].def;
4652 pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4657 pData->postRtEvents.trySplice();
4659 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4660 // --------------------------------------------------------------------------------------------------------
4661 // Post-processing (dry/wet, volume and balance)
4664 const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
4665 const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
4666 const bool isMono = (pData->audioIn.count == 1);
4668 bool isPair;
4669 float bufValue;
4670 float* const oldBufLeft = pData->postProc.extraBuffer;
4672 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4674 // Dry/Wet
4675 if (doDryWet)
4677 const uint32_t c = isMono ? 0 : i;
4679 for (uint32_t k=0; k < frames; ++k)
4681 # ifndef BUILD_BRIDGE
4682 if (k < pData->latency.frames && pData->latency.buffers != nullptr)
4683 bufValue = pData->latency.buffers[c][k];
4684 else if (pData->latency.frames < frames)
4685 bufValue = fAudioInBuffers[c][k-pData->latency.frames];
4686 else
4687 # endif
4688 bufValue = fAudioInBuffers[c][k];
4690 fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
4694 // Balance
4695 if (doBalance)
4697 isPair = (i % 2 == 0);
4699 if (isPair)
4701 CARLA_ASSERT(i+1 < pData->audioOut.count);
4702 carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames);
4705 float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
4706 float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
4708 for (uint32_t k=0; k < frames; ++k)
4710 if (isPair)
4712 // left
4713 fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
4714 fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
4716 else
4718 // right
4719 fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
4720 fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
4725 // Volume (and buffer copy)
4727 for (uint32_t k=0; k < frames; ++k)
4728 audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume;
4731 } // End of Post-processing
4733 # ifndef BUILD_BRIDGE
4734 // --------------------------------------------------------------------------------------------------------
4735 // Save latency values for next callback
4737 if (pData->latency.frames != 0 && pData->latency.buffers != nullptr)
4739 CARLA_SAFE_ASSERT(timeOffset == 0);
4740 const uint32_t latframes = pData->latency.frames;
4742 if (latframes <= frames)
4744 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4745 carla_copyFloats(pData->latency.buffers[i], audioIn[i]+(frames-latframes), latframes);
4747 else
4749 const uint32_t diff = latframes - frames;
4751 for (uint32_t i=0, k; i<pData->audioIn.count; ++i)
4753 // push back buffer by 'frames'
4754 for (k=0; k < diff; ++k)
4755 pData->latency.buffers[i][k] = pData->latency.buffers[i][k+frames];
4757 // put current input at the end
4758 for (uint32_t j=0; k < latframes; ++j, ++k)
4759 pData->latency.buffers[i][k] = audioIn[i][j];
4763 # endif
4764 #else // BUILD_BRIDGE_ALTERNATIVE_ARCH
4765 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4767 for (uint32_t k=0; k < frames; ++k)
4768 audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k];
4770 #endif
4772 for (uint32_t i=0; i < pData->cvOut.count; ++i)
4774 for (uint32_t k=0; k < frames; ++k)
4775 cvOut[i][k+timeOffset] = fCvOutBuffers[i][k];
4778 // --------------------------------------------------------------------------------------------------------
4780 pData->singleMutex.unlock();
4781 return true;
4784 void bufferSizeChanged(const uint32_t newBufferSize) override
4786 CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
4787 carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - start", newBufferSize);
4789 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4791 if (fAudioInBuffers[i] != nullptr)
4792 delete[] fAudioInBuffers[i];
4793 fAudioInBuffers[i] = new float[newBufferSize];
4796 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4798 if (fAudioOutBuffers[i] != nullptr)
4799 delete[] fAudioOutBuffers[i];
4800 fAudioOutBuffers[i] = new float[newBufferSize];
4803 if (fHandle2 == nullptr)
4805 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4807 CARLA_ASSERT(fAudioInBuffers[i] != nullptr);
4808 fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
4811 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4813 CARLA_ASSERT(fAudioOutBuffers[i] != nullptr);
4814 fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
4817 else
4819 if (pData->audioIn.count > 0)
4821 CARLA_ASSERT(pData->audioIn.count == 2);
4822 CARLA_ASSERT(fAudioInBuffers[0] != nullptr);
4823 CARLA_ASSERT(fAudioInBuffers[1] != nullptr);
4825 fDescriptor->connect_port(fHandle, pData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
4826 fDescriptor->connect_port(fHandle2, pData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
4829 if (pData->audioOut.count > 0)
4831 CARLA_ASSERT(pData->audioOut.count == 2);
4832 CARLA_ASSERT(fAudioOutBuffers[0] != nullptr);
4833 CARLA_ASSERT(fAudioOutBuffers[1] != nullptr);
4835 fDescriptor->connect_port(fHandle, pData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
4836 fDescriptor->connect_port(fHandle2, pData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
4840 for (uint32_t i=0; i < pData->cvIn.count; ++i)
4842 if (fCvInBuffers[i] != nullptr)
4843 delete[] fCvInBuffers[i];
4844 fCvInBuffers[i] = new float[newBufferSize];
4846 fDescriptor->connect_port(fHandle, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
4848 if (fHandle2 != nullptr)
4849 fDescriptor->connect_port(fHandle2, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
4852 for (uint32_t i=0; i < pData->cvOut.count; ++i)
4854 if (fCvOutBuffers[i] != nullptr)
4855 delete[] fCvOutBuffers[i];
4856 fCvOutBuffers[i] = new float[newBufferSize];
4858 fDescriptor->connect_port(fHandle, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
4860 if (fHandle2 != nullptr)
4861 fDescriptor->connect_port(fHandle2, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
4864 const int newBufferSizeInt(static_cast<int>(newBufferSize));
4866 if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt))
4868 fLv2Options.maxBufferSize = fLv2Options.nominalBufferSize = newBufferSizeInt;
4870 if (fLv2Options.minBufferSize != 1)
4871 fLv2Options.minBufferSize = newBufferSizeInt;
4873 if (fExt.options != nullptr && fExt.options->set != nullptr)
4875 LV2_Options_Option options[4];
4876 carla_zeroStructs(options, 4);
4878 carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::MaxBlockLenth]);
4879 carla_copyStruct(options[1], fLv2Options.opts[CarlaPluginLV2Options::NominalBlockLenth]);
4881 if (fLv2Options.minBufferSize != 1)
4882 carla_copyStruct(options[2], fLv2Options.opts[CarlaPluginLV2Options::MinBlockLenth]);
4884 fExt.options->set(fHandle, options);
4888 carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - end", newBufferSize);
4890 CarlaPlugin::bufferSizeChanged(newBufferSize);
4893 void sampleRateChanged(const double newSampleRate) override
4895 CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
4896 carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - start", newSampleRate);
4898 const float sampleRatef = static_cast<float>(newSampleRate);
4900 if (carla_isNotEqual(fLv2Options.sampleRate, sampleRatef))
4902 fLv2Options.sampleRate = sampleRatef;
4904 if (fExt.options != nullptr && fExt.options->set != nullptr)
4906 LV2_Options_Option options[2];
4907 carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::SampleRate]);
4908 carla_zeroStruct(options[1]);
4910 fExt.options->set(fHandle, options);
4914 for (uint32_t k=0; k < pData->param.count; ++k)
4916 if (pData->param.data[k].type != PARAMETER_INPUT)
4917 continue;
4918 if (pData->param.special[k] != PARAMETER_SPECIAL_SAMPLE_RATE)
4919 continue;
4921 fParamBuffers[k] = sampleRatef;
4922 pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4923 break;
4926 carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - end", newSampleRate);
4929 void offlineModeChanged(const bool isOffline) override
4931 for (uint32_t k=0; k < pData->param.count; ++k)
4933 if (pData->param.data[k].type == PARAMETER_INPUT && pData->param.special[k] == PARAMETER_SPECIAL_FREEWHEEL)
4935 fParamBuffers[k] = isOffline ? pData->param.ranges[k].max : pData->param.ranges[k].min;
4936 pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4937 break;
4942 // -------------------------------------------------------------------
4943 // Plugin buffers
4945 void initBuffers() const noexcept override
4947 fEventsIn.initBuffers();
4948 fEventsOut.initBuffers();
4950 CarlaPlugin::initBuffers();
4953 void clearBuffers() noexcept override
4955 carla_debug("CarlaPluginLV2::clearBuffers() - start");
4957 if (fAudioInBuffers != nullptr)
4959 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4961 if (fAudioInBuffers[i] != nullptr)
4963 delete[] fAudioInBuffers[i];
4964 fAudioInBuffers[i] = nullptr;
4968 delete[] fAudioInBuffers;
4969 fAudioInBuffers = nullptr;
4972 if (fAudioOutBuffers != nullptr)
4974 for (uint32_t i=0; i < pData->audioOut.count; ++i)
4976 if (fAudioOutBuffers[i] != nullptr)
4978 delete[] fAudioOutBuffers[i];
4979 fAudioOutBuffers[i] = nullptr;
4983 delete[] fAudioOutBuffers;
4984 fAudioOutBuffers = nullptr;
4987 if (fCvInBuffers != nullptr)
4989 for (uint32_t i=0; i < pData->cvIn.count; ++i)
4991 if (fCvInBuffers[i] != nullptr)
4993 delete[] fCvInBuffers[i];
4994 fCvInBuffers[i] = nullptr;
4998 delete[] fCvInBuffers;
4999 fCvInBuffers = nullptr;
5002 if (fCvOutBuffers != nullptr)
5004 for (uint32_t i=0; i < pData->cvOut.count; ++i)
5006 if (fCvOutBuffers[i] != nullptr)
5008 delete[] fCvOutBuffers[i];
5009 fCvOutBuffers[i] = nullptr;
5013 delete[] fCvOutBuffers;
5014 fCvOutBuffers = nullptr;
5017 if (fParamBuffers != nullptr)
5019 delete[] fParamBuffers;
5020 fParamBuffers = nullptr;
5023 fEventsIn.clear(pData->event.portIn);
5024 fEventsOut.clear(pData->event.portOut);
5026 CarlaPlugin::clearBuffers();
5028 carla_debug("CarlaPluginLV2::clearBuffers() - end");
5031 // -------------------------------------------------------------------
5032 // Post-poned UI Stuff
5034 void uiParameterChange(const uint32_t index, const float value) noexcept override
5036 CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5037 CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,);
5038 CARLA_SAFE_ASSERT_RETURN(pData->param.data[index].rindex >= 0,);
5040 #ifndef LV2_UIS_ONLY_INPROCESS
5041 if (fUI.type == UI::TYPE_BRIDGE)
5043 if (! fPipeServer.isPipeRunning())
5044 return;
5046 else
5047 #endif
5049 if (fUI.handle == nullptr)
5050 return;
5051 if (fUI.descriptor == nullptr || fUI.descriptor->port_event == nullptr)
5052 return;
5053 if (fNeedsUiClose)
5054 return;
5057 ParameterData& pdata(pData->param.data[index]);
5059 if (pdata.hints & PARAMETER_IS_NOT_SAVED)
5061 int32_t rindex = pdata.rindex;
5062 CARLA_SAFE_ASSERT_RETURN(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0,);
5064 rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
5065 CARLA_SAFE_ASSERT_RETURN(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount),);
5067 const char* const uri = fRdfDescriptor->Parameters[rindex].URI;
5069 #ifndef LV2_UIS_ONLY_INPROCESS
5070 if (fUI.type == UI::TYPE_BRIDGE)
5072 fPipeServer.writeLv2ParameterMessage(uri, value);
5074 else
5075 #endif
5076 if (fEventsIn.ctrl != nullptr)
5078 uint8_t atomBuf[256];
5079 LV2_Atom_Forge atomForge;
5080 initAtomForge(atomForge);
5081 lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
5083 LV2_Atom_Forge_Frame forgeFrame;
5084 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
5086 lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
5087 lv2_atom_forge_bool(&atomForge, true);
5089 lv2_atom_forge_key(&atomForge, kUridPatchProperty);
5090 lv2_atom_forge_urid(&atomForge, getCustomURID(uri));
5092 lv2_atom_forge_key(&atomForge, kUridPatchValue);
5094 switch (fRdfDescriptor->Parameters[rindex].Type)
5096 case LV2_PARAMETER_TYPE_BOOL:
5097 lv2_atom_forge_bool(&atomForge, value > 0.5f);
5098 break;
5099 case LV2_PARAMETER_TYPE_INT:
5100 lv2_atom_forge_int(&atomForge, static_cast<int32_t>(value + 0.5f));
5101 break;
5102 case LV2_PARAMETER_TYPE_LONG:
5103 lv2_atom_forge_long(&atomForge, static_cast<int64_t>(value + 0.5f));
5104 break;
5105 case LV2_PARAMETER_TYPE_FLOAT:
5106 lv2_atom_forge_float(&atomForge, value);
5107 break;
5108 case LV2_PARAMETER_TYPE_DOUBLE:
5109 lv2_atom_forge_double(&atomForge, value);
5110 break;
5111 default:
5112 carla_stderr2("uiParameterChange called for invalid parameter, abort!");
5113 return;
5116 lv2_atom_forge_pop(&atomForge, &forgeFrame);
5118 LV2_Atom* const atom((LV2_Atom*)atomBuf);
5119 CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
5121 fUI.descriptor->port_event(fUI.handle,
5122 fEventsIn.ctrl->rindex,
5123 lv2_atom_total_size(atom),
5124 kUridAtomTransferEvent,
5125 atom);
5128 else
5130 #ifndef LV2_UIS_ONLY_INPROCESS
5131 if (fUI.type == UI::TYPE_BRIDGE)
5133 fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[index].rindex), value);
5135 else
5136 #endif
5138 fUI.descriptor->port_event(fUI.handle,
5139 static_cast<uint32_t>(pData->param.data[index].rindex),
5140 sizeof(float), kUridNull, &value);
5145 void uiMidiProgramChange(const uint32_t index) noexcept override
5147 CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5148 CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
5150 #ifndef LV2_UIS_ONLY_INPROCESS
5151 if (fUI.type == UI::TYPE_BRIDGE)
5153 if (fPipeServer.isPipeRunning())
5154 fPipeServer.writeMidiProgramMessage(pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
5156 else
5157 #endif
5159 if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program != nullptr && ! fNeedsUiClose)
5160 fExt.uiprograms->select_program(fUI.handle, pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
5164 void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override
5166 CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5167 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
5168 CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
5169 CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
5171 #if 0
5172 if (fUI.type == UI::TYPE_BRIDGE)
5174 if (fPipeServer.isPipeRunning())
5175 fPipeServer.writeMidiNoteMessage(false, channel, note, velo);
5177 else
5179 if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
5181 LV2_Atom_MidiEvent midiEv;
5182 midiEv.atom.type = kUridMidiEvent;
5183 midiEv.atom.size = 3;
5184 midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT));
5185 midiEv.data[1] = note;
5186 midiEv.data[2] = velo;
5188 fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
5191 #endif
5194 void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override
5196 CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5197 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
5198 CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
5200 #if 0
5201 if (fUI.type == UI::TYPE_BRIDGE)
5203 if (fPipeServer.isPipeRunning())
5204 fPipeServer.writeMidiNoteMessage(false, channel, note, 0);
5206 else
5208 if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
5210 LV2_Atom_MidiEvent midiEv;
5211 midiEv.atom.type = kUridMidiEvent;
5212 midiEv.atom.size = 3;
5213 midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (channel & MIDI_CHANNEL_BIT));
5214 midiEv.data[1] = note;
5215 midiEv.data[2] = 0;
5217 fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
5220 #endif
5223 // -------------------------------------------------------------------
5224 // Internal helper functions
5226 void cloneLV2Files(const CarlaPlugin& other) override
5228 CARLA_SAFE_ASSERT_RETURN(other.getType() == PLUGIN_LV2,);
5230 const CarlaPluginLV2& otherLV2((const CarlaPluginLV2&)other);
5232 const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5234 if (tmpDir.exists())
5235 tmpDir.deleteRecursively();
5237 const File otherStateDir(otherLV2.handleStateMapToAbsolutePath(false, false, false, "."));
5239 if (otherStateDir.exists())
5240 otherStateDir.copyDirectoryTo(tmpDir);
5242 const File otherTmpDir(otherLV2.handleStateMapToAbsolutePath(false, false, true, "."));
5244 if (otherTmpDir.exists())
5245 otherTmpDir.copyDirectoryTo(tmpDir);
5248 void restoreLV2State(const bool temporary) noexcept override
5250 if (fExt.state == nullptr || fExt.state->restore == nullptr)
5251 return;
5253 if (! temporary)
5255 const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5257 if (tmpDir.exists())
5258 tmpDir.deleteRecursively();
5261 LV2_State_Status status = LV2_STATE_ERR_UNKNOWN;
5264 const ScopedSingleProcessLocker spl(this, !fHasThreadSafeRestore);
5266 try {
5267 status = fExt.state->restore(fHandle,
5268 carla_lv2_state_retrieve,
5269 this,
5270 LV2_STATE_IS_POD,
5271 temporary ? fFeatures : fStateFeatures);
5272 } catch(...) {}
5274 if (fHandle2 != nullptr)
5276 try {
5277 fExt.state->restore(fHandle,
5278 carla_lv2_state_retrieve,
5279 this,
5280 LV2_STATE_IS_POD,
5281 temporary ? fFeatures : fStateFeatures);
5282 } catch(...) {}
5286 switch (status)
5288 case LV2_STATE_SUCCESS:
5289 carla_debug("CarlaPluginLV2::updateLV2State() - success");
5290 break;
5291 case LV2_STATE_ERR_UNKNOWN:
5292 carla_stderr("CarlaPluginLV2::updateLV2State() - unknown error");
5293 break;
5294 case LV2_STATE_ERR_BAD_TYPE:
5295 carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad type");
5296 break;
5297 case LV2_STATE_ERR_BAD_FLAGS:
5298 carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad flags");
5299 break;
5300 case LV2_STATE_ERR_NO_FEATURE:
5301 carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing feature");
5302 break;
5303 case LV2_STATE_ERR_NO_PROPERTY:
5304 carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing property");
5305 break;
5306 case LV2_STATE_ERR_NO_SPACE:
5307 carla_stderr("CarlaPluginLV2::updateLV2State() - error, insufficient space");
5308 break;
5312 // -------------------------------------------------------------------
5314 bool isRealtimeSafe() const noexcept
5316 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
5318 for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
5320 if (std::strcmp(fRdfDescriptor->Features[i].URI, LV2_CORE__hardRTCapable) == 0)
5321 return true;
5324 return false;
5327 // -------------------------------------------------------------------
5329 bool isUiBridgeable(const uint32_t uiId) const noexcept
5331 CARLA_SAFE_ASSERT_RETURN(uiId < fRdfDescriptor->UICount, false);
5333 #ifndef LV2_UIS_ONLY_INPROCESS
5334 const LV2_RDF_UI* const rdfUI(&fRdfDescriptor->UIs[uiId]);
5336 for (uint32_t i=0; i < rdfUI->FeatureCount; ++i)
5338 const LV2_RDF_Feature& feat(rdfUI->Features[i]);
5340 if (! feat.Required)
5341 continue;
5342 if (std::strcmp(feat.URI, LV2_INSTANCE_ACCESS_URI) == 0)
5343 return false;
5344 if (std::strcmp(feat.URI, LV2_DATA_ACCESS_URI) == 0)
5345 return false;
5348 // Calf UIs are mostly useless without their special graphs
5349 // but they can be crashy under certain conditions, so follow user preferences
5350 if (std::strstr(rdfUI->URI, "http://calf.sourceforge.net/plugins/gui/") != nullptr)
5351 return pData->engine->getOptions().preferUiBridges;
5353 // LSP-Plugins UIs make heavy use of URIDs, for which carla right now is very slow
5354 // FIXME after some optimization, remove this
5355 if (std::strstr(rdfUI->URI, "http://lsp-plug.in/ui/lv2/") != nullptr)
5356 return false;
5358 return true;
5359 #else
5360 return false;
5361 #endif
5364 bool isUiResizable() const noexcept
5366 CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr, false);
5368 for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
5370 if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0)
5371 return false;
5372 if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
5373 return false;
5376 return true;
5379 const char* getUiBridgeBinary(const LV2_Property type) const
5381 CarlaString bridgeBinary(pData->engine->getOptions().binaryDir);
5383 if (bridgeBinary.isEmpty())
5384 return nullptr;
5386 switch (type)
5388 case LV2_UI_GTK2:
5389 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk2";
5390 break;
5391 case LV2_UI_GTK3:
5392 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk3";
5393 break;
5394 case LV2_UI_QT4:
5395 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt4";
5396 break;
5397 case LV2_UI_QT5:
5398 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt5";
5399 break;
5400 case LV2_UI_COCOA:
5401 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-cocoa";
5402 break;
5403 case LV2_UI_WINDOWS:
5404 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-windows";
5405 break;
5406 case LV2_UI_X11:
5407 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-x11";
5408 break;
5409 case LV2_UI_MOD:
5410 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-modgui";
5411 break;
5412 #if 0
5413 case LV2_UI_EXTERNAL:
5414 case LV2_UI_OLD_EXTERNAL:
5415 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-external";
5416 break;
5417 #endif
5418 default:
5419 return nullptr;
5422 #ifdef CARLA_OS_WIN
5423 bridgeBinary += ".exe";
5424 #endif
5426 if (! File(bridgeBinary.buffer()).existsAsFile())
5427 return nullptr;
5429 return bridgeBinary.dupSafe();
5432 // -------------------------------------------------------------------
5434 void recheckExtensions()
5436 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
5437 carla_debug("CarlaPluginLV2::recheckExtensions()");
5439 fExt.options = nullptr;
5440 fExt.programs = nullptr;
5441 fExt.state = nullptr;
5442 fExt.worker = nullptr;
5443 fExt.inlineDisplay = nullptr;
5445 for (uint32_t i=0; i < fRdfDescriptor->ExtensionCount; ++i)
5447 const char* const extension = fRdfDescriptor->Extensions[i];
5448 CARLA_SAFE_ASSERT_CONTINUE(extension != nullptr);
5450 /**/ if (std::strcmp(extension, LV2_OPTIONS__interface) == 0)
5451 pData->hints |= PLUGIN_HAS_EXTENSION_OPTIONS;
5452 else if (std::strcmp(extension, LV2_PROGRAMS__Interface) == 0)
5453 pData->hints |= PLUGIN_HAS_EXTENSION_PROGRAMS;
5454 else if (std::strcmp(extension, LV2_STATE__interface) == 0)
5455 pData->hints |= PLUGIN_HAS_EXTENSION_STATE;
5456 else if (std::strcmp(extension, LV2_WORKER__interface) == 0)
5457 pData->hints |= PLUGIN_HAS_EXTENSION_WORKER;
5458 else if (std::strcmp(extension, LV2_INLINEDISPLAY__interface) == 0)
5459 pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
5460 else if (std::strcmp(extension, LV2_MIDNAM__interface) == 0)
5461 pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
5462 else
5463 carla_stdout("Plugin '%s' has non-supported extension: '%s'", fRdfDescriptor->URI, extension);
5466 // Fix for broken plugins, nasty!
5467 for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
5469 const LV2_RDF_Feature& feature(fRdfDescriptor->Features[i]);
5471 if (std::strcmp(feature.URI, LV2_INLINEDISPLAY__queue_draw) == 0)
5473 if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
5474 break;
5476 carla_stdout("Plugin '%s' uses inline-display but does not set extension data, nasty!", fRdfDescriptor->URI);
5477 pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
5479 else if (std::strcmp(feature.URI, LV2_MIDNAM__update) == 0)
5481 if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
5482 break;
5484 carla_stdout("Plugin '%s' uses midnam but does not set extension data, nasty!", fRdfDescriptor->URI);
5485 pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
5489 if (fDescriptor->extension_data != nullptr)
5491 if (pData->hints & PLUGIN_HAS_EXTENSION_OPTIONS)
5492 fExt.options = (const LV2_Options_Interface*)fDescriptor->extension_data(LV2_OPTIONS__interface);
5494 if (pData->hints & PLUGIN_HAS_EXTENSION_PROGRAMS)
5495 fExt.programs = (const LV2_Programs_Interface*)fDescriptor->extension_data(LV2_PROGRAMS__Interface);
5497 if (pData->hints & PLUGIN_HAS_EXTENSION_STATE)
5498 fExt.state = (const LV2_State_Interface*)fDescriptor->extension_data(LV2_STATE__interface);
5500 if (pData->hints & PLUGIN_HAS_EXTENSION_WORKER)
5501 fExt.worker = (const LV2_Worker_Interface*)fDescriptor->extension_data(LV2_WORKER__interface);
5503 if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
5504 fExt.inlineDisplay = (const LV2_Inline_Display_Interface*)fDescriptor->extension_data(LV2_INLINEDISPLAY__interface);
5506 if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
5507 fExt.midnam = (const LV2_Midnam_Interface*)fDescriptor->extension_data(LV2_MIDNAM__interface);
5509 // check if invalid
5510 if (fExt.options != nullptr && fExt.options->get == nullptr && fExt.options->set == nullptr)
5511 fExt.options = nullptr;
5513 if (fExt.programs != nullptr && (fExt.programs->get_program == nullptr || fExt.programs->select_program == nullptr))
5514 fExt.programs = nullptr;
5516 if (fExt.state != nullptr && (fExt.state->save == nullptr || fExt.state->restore == nullptr))
5517 fExt.state = nullptr;
5519 if (fExt.worker != nullptr && fExt.worker->work == nullptr)
5520 fExt.worker = nullptr;
5522 if (fExt.inlineDisplay != nullptr)
5524 if (fExt.inlineDisplay->render != nullptr)
5526 pData->hints |= PLUGIN_HAS_INLINE_DISPLAY;
5527 pData->setCanDeleteLib(false);
5529 else
5531 fExt.inlineDisplay = nullptr;
5535 if (fExt.midnam != nullptr && fExt.midnam->midnam == nullptr)
5536 fExt.midnam = nullptr;
5539 CARLA_SAFE_ASSERT_RETURN(fLatencyIndex == -1,);
5541 int32_t iCtrl=0;
5542 for (uint32_t i=0, count=fRdfDescriptor->PortCount; i<count; ++i)
5544 const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
5546 if (! LV2_IS_PORT_CONTROL(portTypes))
5547 continue;
5549 const CarlaScopedValueSetter<int32_t> svs(iCtrl, iCtrl, iCtrl+1);
5551 if (! LV2_IS_PORT_OUTPUT(portTypes))
5552 continue;
5554 const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
5556 if (! LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
5557 continue;
5559 fLatencyIndex = iCtrl;
5560 break;
5564 // -------------------------------------------------------------------
5566 void updateUi()
5568 CARLA_SAFE_ASSERT_RETURN(fUI.handle != nullptr,);
5569 CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
5570 carla_debug("CarlaPluginLV2::updateUi()");
5572 // update midi program
5573 if (fExt.uiprograms != nullptr && pData->midiprog.count > 0 && pData->midiprog.current >= 0)
5575 const MidiProgramData& curData(pData->midiprog.getCurrent());
5576 fExt.uiprograms->select_program(fUI.handle, curData.bank, curData.program);
5579 // update control ports
5580 if (fUI.descriptor->port_event != nullptr)
5582 float value;
5583 for (uint32_t i=0; i < pData->param.count; ++i)
5585 value = getParameterValue(i);
5586 fUI.descriptor->port_event(fUI.handle, static_cast<uint32_t>(pData->param.data[i].rindex), sizeof(float), kUridNull, &value);
5591 void inspectAtomForParameterChange(const LV2_Atom* const atom)
5593 if (atom->type != kUridAtomBlank && atom->type != kUridAtomObject)
5594 return;
5596 const LV2_Atom_Object_Body* const objbody = (const LV2_Atom_Object_Body*)(atom + 1);
5598 if (objbody->otype != kUridPatchSet)
5599 return;
5601 const LV2_Atom_URID *property = NULL;
5602 const LV2_Atom_Bool *carlaParam = NULL;
5603 const LV2_Atom *value = NULL;
5605 lv2_atom_object_body_get(atom->size, objbody,
5606 kUridCarlaParameterChange, (const LV2_Atom**)&carlaParam,
5607 kUridPatchProperty, (const LV2_Atom**)&property,
5608 kUridPatchValue, &value,
5611 if (carlaParam != nullptr && carlaParam->body != 0)
5612 return;
5614 if (property == nullptr || value == nullptr)
5615 return;
5617 switch (value->type)
5619 case kUridAtomBool:
5620 case kUridAtomInt:
5621 //case kUridAtomLong:
5622 case kUridAtomFloat:
5623 case kUridAtomDouble:
5624 break;
5625 default:
5626 return;
5629 uint32_t parameterId;
5630 if (! getParameterIndexForURID(property->body, parameterId))
5631 return;
5633 const uint8_t* const vbody = (const uint8_t*)(value + 1);
5634 float rvalue;
5636 switch (value->type)
5638 case kUridAtomBool:
5639 rvalue = *(const int32_t*)vbody != 0 ? 1.0f : 0.0f;
5640 break;
5641 case kUridAtomInt:
5642 rvalue = static_cast<float>(*(const int32_t*)vbody);
5643 break;
5645 case kUridAtomLong:
5646 rvalue = *(int64_t*)vbody;
5647 break;
5649 case kUridAtomFloat:
5650 rvalue = *(const float*)vbody;
5651 break;
5652 case kUridAtomDouble:
5653 rvalue = static_cast<float>(*(const double*)vbody);
5654 break;
5655 default:
5656 rvalue = 0.0f;
5657 break;
5660 rvalue = pData->param.getFixedValue(parameterId, rvalue);
5661 fParamBuffers[parameterId] = rvalue;
5663 CarlaPlugin::setParameterValue(parameterId, rvalue, false, true, true);
5666 bool getParameterIndexForURI(const char* const uri, uint32_t& parameterId) noexcept
5668 parameterId = UINT32_MAX;
5670 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
5672 const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
5674 switch (rdfParam.Type)
5676 case LV2_PARAMETER_TYPE_BOOL:
5677 case LV2_PARAMETER_TYPE_INT:
5678 // case LV2_PARAMETER_TYPE_LONG:
5679 case LV2_PARAMETER_TYPE_FLOAT:
5680 case LV2_PARAMETER_TYPE_DOUBLE:
5681 break;
5682 default:
5683 continue;
5686 if (std::strcmp(rdfParam.URI, uri) == 0)
5688 const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
5690 for (uint32_t j=0; j < pData->param.count; ++j)
5692 if (pData->param.data[j].rindex == rindex)
5694 parameterId = j;
5695 break;
5698 break;
5702 return (parameterId != UINT32_MAX);
5705 bool getParameterIndexForURID(const LV2_URID urid, uint32_t& parameterId) noexcept
5707 parameterId = UINT32_MAX;
5709 if (urid >= fCustomURIDs.size())
5710 return false;
5712 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
5714 const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
5716 switch (rdfParam.Type)
5718 case LV2_PARAMETER_TYPE_BOOL:
5719 case LV2_PARAMETER_TYPE_INT:
5720 // case LV2_PARAMETER_TYPE_LONG:
5721 case LV2_PARAMETER_TYPE_FLOAT:
5722 case LV2_PARAMETER_TYPE_DOUBLE:
5723 break;
5724 default:
5725 continue;
5728 const std::string& uri(fCustomURIDs[urid]);
5730 if (uri != rdfParam.URI)
5731 continue;
5733 const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
5735 for (uint32_t j=0; j < pData->param.count; ++j)
5737 if (pData->param.data[j].rindex == rindex)
5739 parameterId = j;
5740 break;
5743 break;
5746 return (parameterId != UINT32_MAX);
5749 // -------------------------------------------------------------------
5751 LV2_URID getCustomURID(const char* const uri)
5753 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
5754 carla_debug("CarlaPluginLV2::getCustomURID(\"%s\")", uri);
5756 const std::string s_uri(uri);
5757 const std::ptrdiff_t s_pos(std::find(fCustomURIDs.begin(), fCustomURIDs.end(), s_uri) - fCustomURIDs.begin());
5759 if (s_pos <= 0 || s_pos >= INT32_MAX)
5760 return kUridNull;
5762 const LV2_URID urid = static_cast<LV2_URID>(s_pos);
5763 const LV2_URID uriCount = static_cast<LV2_URID>(fCustomURIDs.size());
5765 if (urid < uriCount)
5766 return urid;
5768 CARLA_SAFE_ASSERT(urid == uriCount);
5770 fCustomURIDs.push_back(uri);
5772 #ifndef LV2_UIS_ONLY_INPROCESS
5773 if (fUI.type == UI::TYPE_BRIDGE && fPipeServer.isPipeRunning())
5774 fPipeServer.writeLv2UridMessage(urid, uri);
5775 #endif
5777 return urid;
5780 const char* getCustomURIDString(const LV2_URID urid) const noexcept
5782 CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, kUnmapFallback);
5783 CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.size(), kUnmapFallback);
5784 carla_debug("CarlaPluginLV2::getCustomURIString(%i)", urid);
5786 return fCustomURIDs[urid].c_str();
5789 // -------------------------------------------------------------------
5791 void handleProgramChanged(const int32_t index)
5793 CARLA_SAFE_ASSERT_RETURN(index >= -1,);
5794 carla_debug("CarlaPluginLV2::handleProgramChanged(%i)", index);
5796 if (index == -1)
5798 const ScopedSingleProcessLocker spl(this, true);
5799 return reloadPrograms(false);
5802 if (index < static_cast<int32_t>(pData->midiprog.count) && fExt.programs != nullptr && fExt.programs->get_program != nullptr)
5804 if (const LV2_Program_Descriptor* const progDesc = fExt.programs->get_program(fHandle, static_cast<uint32_t>(index)))
5806 CARLA_SAFE_ASSERT_RETURN(progDesc->name != nullptr,);
5808 if (pData->midiprog.data[index].name != nullptr)
5809 delete[] pData->midiprog.data[index].name;
5811 pData->midiprog.data[index].name = carla_strdup(progDesc->name);
5813 if (index == pData->midiprog.current)
5814 pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0, nullptr);
5815 else
5816 pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0, nullptr);
5821 // -------------------------------------------------------------------
5823 LV2_Resize_Port_Status handleResizePort(const uint32_t index, const size_t size)
5825 CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_RESIZE_PORT_ERR_UNKNOWN);
5826 carla_debug("CarlaPluginLV2::handleResizePort(%i, " P_SIZE ")", index, size);
5828 // TODO
5829 return LV2_RESIZE_PORT_ERR_NO_SPACE;
5830 (void)index;
5833 // -------------------------------------------------------------------
5835 char* handleStateMapToAbstractPath(const bool temporary, const char* const absolutePath) const
5837 // may already be an abstract path
5838 if (! File::isAbsolutePath(absolutePath))
5839 return strdup(absolutePath);
5841 File projectDir, targetDir;
5843 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5844 if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
5845 projectDir = projFolder;
5846 else
5847 #endif
5848 projectDir = File::getCurrentWorkingDirectory();
5850 if (projectDir.isNull())
5852 carla_stdout("Project directory not set, cannot map absolutePath %s", absolutePath);
5853 return nullptr;
5856 water::String basedir(pData->engine->getName());
5858 if (temporary)
5859 basedir += ".tmp";
5861 targetDir = projectDir.getChildFile(basedir)
5862 .getChildFile(getName());
5864 if (! targetDir.exists())
5865 targetDir.createDirectory();
5867 const File wabsolutePath(absolutePath);
5869 // we may be saving to non-tmp path, let's check
5870 if (! temporary)
5872 const File tmpDir = projectDir.getChildFile(basedir + ".tmp")
5873 .getChildFile(getName());
5875 if (wabsolutePath.getFullPathName().startsWith(tmpDir.getFullPathName()))
5877 // gotcha, the temporary path is now the real one
5878 targetDir = tmpDir;
5880 else if (! wabsolutePath.getFullPathName().startsWith(targetDir.getFullPathName()))
5882 // seems like a normal save, let's be nice and put a symlink
5883 const water::String abstractFilename(wabsolutePath.getFileName());
5884 const File targetPath(targetDir.getChildFile(abstractFilename));
5886 wabsolutePath.createSymbolicLink(targetPath, true);
5888 carla_stdout("Creating symlink for '%s' in '%s'", absolutePath, targetDir.getFullPathName().toRawUTF8());
5889 return strdup(abstractFilename.toRawUTF8());
5893 carla_stdout("Mapping absolutePath '%s' relative to targetDir '%s'",
5894 absolutePath, targetDir.getFullPathName().toRawUTF8());
5896 return strdup(wabsolutePath.getRelativePathFrom(targetDir).toRawUTF8());
5899 File handleStateMapToAbsolutePath(const bool createDirIfNeeded,
5900 const bool symlinkIfNeeded,
5901 const bool temporary,
5902 const char* const abstractPath) const
5904 File targetDir, targetPath;
5906 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5907 if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
5908 targetDir = projFolder;
5909 else
5910 #endif
5911 targetDir = File::getCurrentWorkingDirectory();
5913 if (targetDir.isNull())
5915 carla_stdout("Project directory not set, cannot map abstractPath '%s'", abstractPath);
5916 return File();
5919 water::String basedir(pData->engine->getName());
5921 if (temporary)
5922 basedir += ".tmp";
5924 targetDir = targetDir.getChildFile(basedir)
5925 .getChildFile(getName());
5927 if (createDirIfNeeded && ! targetDir.exists())
5928 targetDir.createDirectory();
5930 if (File::isAbsolutePath(abstractPath))
5932 File wabstractPath(abstractPath);
5933 targetPath = targetDir.getChildFile(wabstractPath.getFileName());
5935 if (symlinkIfNeeded)
5937 carla_stdout("Creating symlink for '%s' in '%s'",
5938 abstractPath, targetDir.getFullPathName().toRawUTF8());
5939 wabstractPath.createSymbolicLink(targetPath, true);
5942 else
5944 targetPath = targetDir.getChildFile(abstractPath);
5945 targetDir = targetPath.getParentDirectory();
5947 if (createDirIfNeeded && ! targetDir.exists())
5948 targetDir.createDirectory();
5951 if (std::strcmp(abstractPath, ".") != 0)
5952 carla_stdout("Mapping abstractPath '%s' relative to targetDir '%s'",
5953 abstractPath, targetDir.getFullPathName().toRawUTF8());
5955 return targetPath;
5958 LV2_State_Status handleStateStore(const uint32_t key, const void* const value, const size_t size, const uint32_t type, const uint32_t flags)
5960 CARLA_SAFE_ASSERT_RETURN(key != kUridNull, LV2_STATE_ERR_NO_PROPERTY);
5961 CARLA_SAFE_ASSERT_RETURN(value != nullptr, LV2_STATE_ERR_NO_PROPERTY);
5962 CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_STATE_ERR_NO_PROPERTY);
5963 CARLA_SAFE_ASSERT_RETURN(type != kUridNull, LV2_STATE_ERR_BAD_TYPE);
5965 // FIXME linuxsampler does not set POD flag
5966 // CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
5968 carla_debug("CarlaPluginLV2::handleStateStore(%i:\"%s\", %p, " P_SIZE ", %i:\"%s\", %i)",
5969 key, carla_lv2_urid_unmap(this, key), value, size, type, carla_lv2_urid_unmap(this, type), flags);
5971 const char* const skey(carla_lv2_urid_unmap(this, key));
5972 const char* const stype(carla_lv2_urid_unmap(this, type));
5974 CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
5975 CARLA_SAFE_ASSERT_RETURN(stype != nullptr && stype != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
5977 // Check if we already have this key
5978 for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
5980 CustomData& cData(it.getValue(kCustomDataFallbackNC));
5981 CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
5983 if (std::strcmp(cData.key, skey) == 0)
5985 // found it
5986 delete[] cData.value;
5988 if (type == kUridAtomString || type == kUridAtomPath)
5989 cData.value = carla_strdup((const char*)value);
5990 else
5991 cData.value = CarlaString::asBase64(value, size).dup();
5993 return LV2_STATE_SUCCESS;
5997 // Otherwise store it
5998 CustomData newData;
5999 newData.type = carla_strdup(stype);
6000 newData.key = carla_strdup(skey);
6002 if (type == kUridAtomString || type == kUridAtomPath)
6003 newData.value = carla_strdup((const char*)value);
6004 else
6005 newData.value = CarlaString::asBase64(value, size).dup();
6007 pData->custom.append(newData);
6009 return LV2_STATE_SUCCESS;
6011 // unused
6012 (void)flags;
6015 const void* handleStateRetrieve(const uint32_t key, size_t* const size, uint32_t* const type, uint32_t* const flags)
6017 CARLA_SAFE_ASSERT_RETURN(key != kUridNull, nullptr);
6018 CARLA_SAFE_ASSERT_RETURN(size != nullptr, nullptr);
6019 CARLA_SAFE_ASSERT_RETURN(type != nullptr, nullptr);
6020 CARLA_SAFE_ASSERT_RETURN(flags != nullptr, nullptr);
6021 carla_debug("CarlaPluginLV2::handleStateRetrieve(%i, %p, %p, %p)", key, size, type, flags);
6023 const char* const skey(carla_lv2_urid_unmap(this, key));
6024 CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, nullptr);
6026 const char* stype = nullptr;
6027 const char* stringData = nullptr;
6029 for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
6031 const CustomData& cData(it.getValue(kCustomDataFallback));
6032 CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
6034 if (std::strcmp(cData.key, skey) == 0)
6036 stype = cData.type;
6037 stringData = cData.value;
6038 break;
6042 if (stype == nullptr || stringData == nullptr)
6044 carla_stderr("Plugin requested value for '%s' which is not available", skey);
6045 *size = *type = *flags = 0;
6046 return nullptr;
6049 *type = carla_lv2_urid_map(this, stype);
6050 *flags = LV2_STATE_IS_POD;
6052 if (*type == kUridAtomString || *type == kUridAtomPath)
6054 *size = std::strlen(stringData);
6055 return stringData;
6058 if (fLastStateChunk != nullptr)
6060 std::free(fLastStateChunk);
6061 fLastStateChunk = nullptr;
6064 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(stringData));
6065 CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0, nullptr);
6067 fLastStateChunk = std::malloc(chunk.size());
6068 CARLA_SAFE_ASSERT_RETURN(fLastStateChunk != nullptr, nullptr);
6070 #ifdef CARLA_PROPER_CPP11_SUPPORT
6071 std::memcpy(fLastStateChunk, chunk.data(), chunk.size());
6072 #else
6073 std::memcpy(fLastStateChunk, &chunk.front(), chunk.size());
6074 #endif
6076 *size = chunk.size();
6077 return fLastStateChunk;
6080 // -------------------------------------------------------------------
6082 LV2_Worker_Status handleWorkerSchedule(const uint32_t size, const void* const data)
6084 CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr, LV2_WORKER_ERR_UNKNOWN);
6085 CARLA_SAFE_ASSERT_RETURN(fEventsIn.ctrl != nullptr, LV2_WORKER_ERR_UNKNOWN);
6086 carla_debug("CarlaPluginLV2::handleWorkerSchedule(%i, %p)", size, data);
6088 if (pData->engine->isOffline())
6090 fExt.worker->work(fHandle, carla_lv2_worker_respond, this, size, data);
6091 return LV2_WORKER_SUCCESS;
6094 LV2_Atom atom;
6095 atom.size = size;
6096 atom.type = kUridCarlaAtomWorkerIn;
6098 return fAtomBufferWorkerIn.putChunk(&atom, data, fEventsOut.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
6101 LV2_Worker_Status handleWorkerRespond(const uint32_t size, const void* const data)
6103 CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work_response != nullptr, LV2_WORKER_ERR_UNKNOWN);
6104 carla_debug("CarlaPluginLV2::handleWorkerRespond(%i, %p)", size, data);
6106 LV2_Atom atom;
6107 atom.size = size;
6108 atom.type = kUridCarlaAtomWorkerResp;
6110 return fAtomBufferWorkerResp.putChunk(&atom, data, fEventsIn.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
6113 // -------------------------------------------------------------------
6115 void handleInlineDisplayQueueRedraw()
6117 switch (pData->engine->getProccessMode())
6119 case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
6120 case ENGINE_PROCESS_MODE_PATCHBAY:
6121 fInlineDisplayNeedsRedraw = true;
6122 break;
6123 default:
6124 break;
6128 const LV2_Inline_Display_Image_Surface* renderInlineDisplay(const uint32_t width, const uint32_t height) const
6130 CARLA_SAFE_ASSERT_RETURN(fExt.inlineDisplay != nullptr && fExt.inlineDisplay->render != nullptr, nullptr);
6131 CARLA_SAFE_ASSERT_RETURN(width > 0, nullptr);
6132 CARLA_SAFE_ASSERT_RETURN(height > 0, nullptr);
6134 return fExt.inlineDisplay->render(fHandle, width, height);
6137 // -------------------------------------------------------------------
6139 void handleMidnamUpdate()
6141 CARLA_SAFE_ASSERT_RETURN(fExt.midnam != nullptr,);
6143 if (fEventsIn.ctrl == nullptr)
6144 return;
6146 char* const midnam = fExt.midnam->midnam(fHandle);
6147 CARLA_SAFE_ASSERT_RETURN(midnam != nullptr,);
6149 fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd", midnam, "text/xml");
6151 if (fExt.midnam->free != nullptr)
6152 fExt.midnam->free(midnam);
6155 // -------------------------------------------------------------------
6157 LV2_ControlInputPort_Change_Status handleCtrlInPortChangeReq(const uint32_t index, const float value)
6159 CARLA_SAFE_ASSERT_RETURN(index < fRdfDescriptor->PortCount, LV2_CONTROL_INPUT_PORT_CHANGE_ERR_INVALID_INDEX);
6160 CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr, LV2_CONTROL_INPUT_PORT_CHANGE_ERR_UNKNOWN);
6162 const float fixedValue = pData->param.getFixedValue(index, value);
6163 fParamBuffers[index] = fixedValue;
6165 CarlaPlugin::setParameterValueRT(index, fixedValue, 0, true);
6166 return LV2_CONTROL_INPUT_PORT_CHANGE_SUCCESS;
6169 // -------------------------------------------------------------------
6171 void handleExternalUIClosed()
6173 CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EXTERNAL,);
6174 carla_debug("CarlaPluginLV2::handleExternalUIClosed()");
6176 fNeedsUiClose = true;
6179 void handlePluginUIClosed() override
6181 CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
6182 CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
6183 carla_debug("CarlaPluginLV2::handlePluginUIClosed()");
6185 fNeedsUiClose = true;
6188 void handlePluginUIResized(const uint width, const uint height) override
6190 CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
6191 CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
6192 carla_debug("CarlaPluginLV2::handlePluginUIResized(%u, %u)", width, height);
6194 if (fUI.handle != nullptr && fExt.uiresize != nullptr)
6195 fExt.uiresize->ui_resize(fUI.handle, static_cast<int>(width), static_cast<int>(height));
6198 // -------------------------------------------------------------------
6200 uint32_t handleUIPortMap(const char* const symbol) const noexcept
6202 CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', LV2UI_INVALID_PORT_INDEX);
6203 carla_debug("CarlaPluginLV2::handleUIPortMap(\"%s\")", symbol);
6205 for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
6207 if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, symbol) == 0)
6208 return i;
6211 return LV2UI_INVALID_PORT_INDEX;
6214 LV2UI_Request_Value_Status handleUIRequestValue(const LV2_URID key,
6215 const LV2_URID type,
6216 const LV2_Feature* const* features)
6218 CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
6219 carla_debug("CarlaPluginLV2::handleUIRequestValue(%u, %u, %p)", key, type, features);
6221 if (type != kUridAtomPath)
6222 return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
6224 const char* const uri = getCustomURIDString(key);
6225 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
6227 // check if a file browser is already open
6228 if (fUI.fileNeededForURI != nullptr || fUI.fileBrowserOpen)
6229 return LV2UI_REQUEST_VALUE_BUSY;
6231 for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
6233 if (fRdfDescriptor->Parameters[i].Type != LV2_PARAMETER_TYPE_PATH)
6234 continue;
6235 if (std::strcmp(fRdfDescriptor->Parameters[i].URI, uri) != 0)
6236 continue;
6238 // TODO file browser filters, also store label to use for title
6239 fUI.fileNeededForURI = uri;
6241 return LV2UI_REQUEST_VALUE_SUCCESS;
6244 return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
6246 // may be unused
6247 (void)features;
6250 int handleUIResize(const int width, const int height)
6252 CARLA_SAFE_ASSERT_RETURN(width > 0, 1);
6253 CARLA_SAFE_ASSERT_RETURN(height > 0, 1);
6254 carla_debug("CarlaPluginLV2::handleUIResize(%i, %i)", width, height);
6256 if (fUI.embedded)
6258 pData->engine->callback(true, true,
6259 ENGINE_CALLBACK_EMBED_UI_RESIZED,
6260 pData->id, width, height,
6261 0, 0.0f, nullptr);
6263 else
6265 CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr, 1);
6266 fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true, true);
6269 return 0;
6272 void handleUITouch(const uint32_t rindex, const bool touch)
6274 carla_debug("CarlaPluginLV2::handleUITouch(%u, %s)", rindex, bool2str(touch));
6276 uint32_t index = LV2UI_INVALID_PORT_INDEX;
6278 for (uint32_t i=0; i < pData->param.count; ++i)
6280 if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
6281 continue;
6282 index = i;
6283 break;
6286 CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
6288 pData->engine->touchPluginParameter(pData->id, index, touch);
6291 void handleUIWrite(const uint32_t rindex, const uint32_t bufferSize, const uint32_t format, const void* const buffer)
6293 CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
6294 CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,);
6295 carla_debug("CarlaPluginLV2::handleUIWrite(%i, %i, %i, %p)", rindex, bufferSize, format, buffer);
6297 uint32_t index = LV2UI_INVALID_PORT_INDEX;
6299 switch (format)
6301 case kUridNull: {
6302 CARLA_SAFE_ASSERT_RETURN(rindex < fRdfDescriptor->PortCount,);
6303 CARLA_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),);
6305 for (uint32_t i=0; i < pData->param.count; ++i)
6307 if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
6308 continue;
6309 index = i;
6310 break;
6313 CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
6315 const float value(*(const float*)buffer);
6317 // check if we should feedback message back to UI
6318 bool sendGui = false;
6320 if (const uint32_t notifCount = fUI.rdfDescriptor->PortNotificationCount)
6322 const char* const portSymbol = fRdfDescriptor->Ports[rindex].Symbol;
6324 for (uint32_t i=0; i < notifCount; ++i)
6326 const LV2_RDF_UI_PortNotification& portNotif(fUI.rdfDescriptor->PortNotifications[i]);
6328 if (portNotif.Protocol != LV2_UI_PORT_PROTOCOL_FLOAT)
6329 continue;
6331 if (portNotif.Symbol != nullptr)
6333 if (std::strcmp(portNotif.Symbol, portSymbol) != 0)
6334 continue;
6336 else if (portNotif.Index != rindex)
6338 continue;
6341 sendGui = true;
6342 break;
6346 setParameterValue(index, value, sendGui, true, true);
6348 } break;
6350 case kUridAtomTransferAtom:
6351 case kUridAtomTransferEvent: {
6352 CARLA_SAFE_ASSERT_RETURN(bufferSize >= sizeof(LV2_Atom),);
6354 const LV2_Atom* const atom((const LV2_Atom*)buffer);
6356 // plugins sometimes fail on this, not good...
6357 const uint32_t totalSize = lv2_atom_total_size(atom);
6358 const uint32_t paddedSize = lv2_atom_pad_size(totalSize);
6360 if (bufferSize != totalSize && bufferSize != paddedSize)
6361 carla_stderr2("Warning: LV2 UI sending atom with invalid size %u! size: %u, padded-size: %u",
6362 bufferSize, totalSize, paddedSize);
6364 for (uint32_t i=0; i < fEventsIn.count; ++i)
6366 if (fEventsIn.data[i].rindex != rindex)
6367 continue;
6368 index = i;
6369 break;
6372 // for bad plugins
6373 if (index == LV2UI_INVALID_PORT_INDEX)
6375 CARLA_SAFE_ASSERT(index != LV2UI_INVALID_PORT_INDEX); // FIXME
6376 index = fEventsIn.ctrlIndex;
6379 fAtomBufferEvIn.put(atom, index);
6380 } break;
6382 default:
6383 carla_stdout("CarlaPluginLV2::handleUIWrite(%i, %i, %i:\"%s\", %p) - unknown format",
6384 rindex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer);
6385 break;
6389 void handleUIBridgeParameter(const char* const uri, const float value)
6391 CARLA_SAFE_ASSERT_RETURN(uri != nullptr,);
6392 carla_debug("CarlaPluginLV2::handleUIBridgeParameter(%s, %f)", uri, static_cast<double>(value));
6394 uint32_t parameterId;
6396 if (getParameterIndexForURI(uri, parameterId))
6397 setParameterValue(parameterId, value, false, true, true);
6400 // -------------------------------------------------------------------
6402 void handleLilvSetPortValue(const char* const portSymbol, const void* const value, const uint32_t size, const uint32_t type)
6404 CARLA_SAFE_ASSERT_RETURN(portSymbol != nullptr && portSymbol[0] != '\0',);
6405 CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
6406 CARLA_SAFE_ASSERT_RETURN(size > 0,);
6407 CARLA_SAFE_ASSERT_RETURN(type != kUridNull,);
6408 carla_debug("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i)", portSymbol, value, size, type);
6410 int32_t rindex = -1;
6412 for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
6414 if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, portSymbol) == 0)
6416 rindex = static_cast<int32_t>(i);
6417 break;
6421 CARLA_SAFE_ASSERT_RETURN(rindex >= 0,);
6423 float paramValue;
6425 switch (type)
6427 case kUridAtomBool:
6428 CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
6429 paramValue = *(const int32_t*)value != 0 ? 1.0f : 0.0f;
6430 break;
6431 case kUridAtomDouble:
6432 CARLA_SAFE_ASSERT_RETURN(size == sizeof(double),);
6433 paramValue = static_cast<float>((*(const double*)value));
6434 break;
6435 case kUridAtomFloat:
6436 CARLA_SAFE_ASSERT_RETURN(size == sizeof(float),);
6437 paramValue = *(const float*)value;
6438 break;
6439 case kUridAtomInt:
6440 CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
6441 paramValue = static_cast<float>(*(const int32_t*)value);
6442 break;
6443 case kUridAtomLong:
6444 CARLA_SAFE_ASSERT_RETURN(size == sizeof(int64_t),);
6445 paramValue = static_cast<float>(*(const int64_t*)value);
6446 break;
6447 default:
6448 carla_stdout("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i:\"%s\") - unknown type",
6449 portSymbol, value, size, type, carla_lv2_urid_unmap(this, type));
6450 return;
6453 for (uint32_t i=0; i < pData->param.count; ++i)
6455 if (pData->param.data[i].rindex == rindex)
6457 setParameterValueRT(i, paramValue, 0, true);
6458 break;
6463 // -------------------------------------------------------------------
6465 void* getNativeHandle() const noexcept override
6467 return fHandle;
6470 const void* getNativeDescriptor() const noexcept override
6472 return fDescriptor;
6475 #ifndef LV2_UIS_ONLY_INPROCESS
6476 uintptr_t getUiBridgeProcessId() const noexcept override
6478 return fPipeServer.isPipeRunning() ? fPipeServer.getPID() : 0;
6480 #endif
6482 // -------------------------------------------------------------------
6484 public:
6485 bool init(const CarlaPluginPtr plugin,
6486 const char* const name, const char* const uri, const uint options,
6487 const char*& needsArchBridge)
6489 CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
6491 // ---------------------------------------------------------------
6492 // first checks
6494 if (pData->client != nullptr)
6496 pData->engine->setLastError("Plugin client is already registered");
6497 return false;
6500 if (uri == nullptr || uri[0] == '\0')
6502 pData->engine->setLastError("null uri");
6503 return false;
6506 const EngineOptions& opts(pData->engine->getOptions());
6508 // ---------------------------------------------------------------
6509 // Init LV2 World if needed, sets LV2_PATH for lilv
6511 Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
6513 if (opts.pathLV2 != nullptr && opts.pathLV2[0] != '\0')
6514 lv2World.initIfNeeded(opts.pathLV2);
6515 else if (const char* const LV2_PATH = std::getenv("LV2_PATH"))
6516 lv2World.initIfNeeded(LV2_PATH);
6517 else
6518 lv2World.initIfNeeded(LILV_DEFAULT_LV2_PATH);
6520 // ---------------------------------------------------------------
6521 // get plugin from lv2_rdf (lilv)
6523 fRdfDescriptor = lv2_rdf_new(uri, true);
6525 if (fRdfDescriptor == nullptr)
6527 pData->engine->setLastError("Failed to find the requested plugin");
6528 return false;
6531 #ifdef ADAPT_FOR_APPLE_SILLICON
6532 // ---------------------------------------------------------------
6533 // check if we can open this binary, might need a bridge
6536 const CarlaMagic magic;
6538 if (const char* const output = magic.getFileDescription(fRdfDescriptor->Binary))
6540 # ifdef __aarch64__
6541 if (std::strstr(output, "arm64") == nullptr && std::strstr(output, "x86_64") != nullptr)
6542 needsArchBridge = "x86_64";
6543 # else
6544 if (std::strstr(output, "x86_64") == nullptr && std::strstr(output, "arm64") != nullptr)
6545 needsArchBridge = "arm64";
6546 # endif
6547 if (needsArchBridge != nullptr)
6548 return false;
6551 #endif // ADAPT_FOR_APPLE_SILLICON
6553 // ---------------------------------------------------------------
6554 // open DLL
6556 #ifdef CARLA_OS_MAC
6557 // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
6558 removeFileFromQuarantine(fRdfDescriptor->Binary);
6559 #endif
6561 if (! pData->libOpen(fRdfDescriptor->Binary))
6563 pData->engine->setLastError(pData->libError(fRdfDescriptor->Binary));
6564 return false;
6567 // ---------------------------------------------------------------
6568 // try to get DLL main entry via new mode
6570 if (const LV2_Lib_Descriptor_Function libDescFn = pData->libSymbol<LV2_Lib_Descriptor_Function>("lv2_lib_descriptor"))
6572 // -----------------------------------------------------------
6573 // all ok, get lib descriptor
6575 const LV2_Lib_Descriptor* const libDesc = libDescFn(fRdfDescriptor->Bundle, nullptr);
6577 if (libDesc == nullptr)
6579 pData->engine->setLastError("Could not find the LV2 Descriptor");
6580 return false;
6583 // -----------------------------------------------------------
6584 // get descriptor that matches URI (new mode)
6586 uint32_t i = 0;
6587 while ((fDescriptor = libDesc->get_plugin(libDesc->handle, i++)))
6589 if (std::strcmp(fDescriptor->URI, uri) == 0)
6590 break;
6593 else
6595 // -----------------------------------------------------------
6596 // get DLL main entry (old mode)
6598 const LV2_Descriptor_Function descFn = pData->libSymbol<LV2_Descriptor_Function>("lv2_descriptor");
6600 if (descFn == nullptr)
6602 pData->engine->setLastError("Could not find the LV2 Descriptor in the plugin library");
6603 return false;
6606 // -----------------------------------------------------------
6607 // get descriptor that matches URI (old mode)
6609 uint32_t i = 0;
6610 while ((fDescriptor = descFn(i++)))
6612 if (std::strcmp(fDescriptor->URI, uri) == 0)
6613 break;
6617 if (fDescriptor == nullptr)
6619 pData->engine->setLastError("Could not find the requested plugin URI in the plugin library");
6620 return false;
6623 // ---------------------------------------------------------------
6624 // check supported port-types and features
6626 bool canContinue = true;
6628 // Check supported ports
6629 for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
6631 const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
6633 if (! is_lv2_port_supported(portTypes))
6635 if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor->Ports[j].Properties))
6637 pData->engine->setLastError("Plugin requires a port type that is not currently supported");
6638 canContinue = false;
6639 break;
6644 // Check supported features
6645 for (uint32_t j=0; j < fRdfDescriptor->FeatureCount && canContinue; ++j)
6647 const LV2_RDF_Feature& feature(fRdfDescriptor->Features[j]);
6649 if (std::strcmp(feature.URI, LV2_DATA_ACCESS_URI) == 0 || std::strcmp(feature.URI, LV2_INSTANCE_ACCESS_URI) == 0)
6651 carla_stderr("Plugin DSP wants UI feature '%s', ignoring this", feature.URI);
6653 else if (std::strcmp(feature.URI, LV2_BUF_SIZE__fixedBlockLength) == 0)
6655 fNeedsFixedBuffers = true;
6657 else if (std::strcmp(feature.URI, LV2_PORT_PROPS__supportsStrictBounds) == 0)
6659 fStrictBounds = feature.Required ? 1 : 0;
6661 else if (std::strcmp(feature.URI, LV2_STATE__loadDefaultState) == 0)
6663 fHasLoadDefaultState = true;
6665 else if (std::strcmp(feature.URI, LV2_STATE__threadSafeRestore) == 0)
6667 fHasThreadSafeRestore = true;
6669 else if (feature.Required && ! is_lv2_feature_supported(feature.URI))
6671 CarlaString msg("Plugin wants a feature that is not supported:\n");
6672 msg += feature.URI;
6674 canContinue = false;
6675 pData->engine->setLastError(msg);
6676 break;
6680 if (! canContinue)
6682 // error already set
6683 return false;
6686 if (fNeedsFixedBuffers && ! pData->engine->usesConstantBufferSize())
6688 pData->engine->setLastError("Cannot use this plugin under the current engine.\n"
6689 "The plugin requires a fixed block size which is not possible right now.");
6690 return false;
6693 // ---------------------------------------------------------------
6694 // set icon
6696 if (std::strncmp(fDescriptor->URI, "http://distrho.sf.net/", 22) == 0)
6697 pData->iconName = carla_strdup_safe("distrho");
6699 // ---------------------------------------------------------------
6700 // set info
6702 if (name != nullptr && name[0] != '\0')
6703 pData->name = pData->engine->getUniquePluginName(name);
6704 else
6705 pData->name = pData->engine->getUniquePluginName(fRdfDescriptor->Name);
6707 // ---------------------------------------------------------------
6708 // register client
6710 pData->client = pData->engine->addClient(plugin);
6712 if (pData->client == nullptr || ! pData->client->isOk())
6714 pData->engine->setLastError("Failed to register plugin client");
6715 return false;
6718 // ---------------------------------------------------------------
6719 // initialize options
6721 const int bufferSize = static_cast<int>(pData->engine->getBufferSize());
6723 fLv2Options.minBufferSize = fNeedsFixedBuffers ? bufferSize : 1;
6724 fLv2Options.maxBufferSize = bufferSize;
6725 fLv2Options.nominalBufferSize = bufferSize;
6726 fLv2Options.sampleRate = static_cast<float>(pData->engine->getSampleRate());
6727 fLv2Options.transientWinId = static_cast<int64_t>(opts.frontendWinId);
6729 uint32_t eventBufferSize = MAX_DEFAULT_BUFFER_SIZE;
6731 for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
6733 const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
6735 if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
6737 if (fRdfDescriptor->Ports[j].MinimumSize > eventBufferSize)
6738 eventBufferSize = fRdfDescriptor->Ports[j].MinimumSize;
6742 fLv2Options.sequenceSize = static_cast<int>(eventBufferSize);
6744 fLv2Options.bgColor = opts.bgColor;
6745 fLv2Options.fgColor = opts.fgColor;
6746 fLv2Options.uiScale = opts.uiScale;
6748 // ---------------------------------------------------------------
6749 // initialize features (part 1)
6751 LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
6752 eventFt->callback_data = this;
6753 eventFt->lv2_event_ref = carla_lv2_event_ref;
6754 eventFt->lv2_event_unref = carla_lv2_event_unref;
6756 LV2_Log_Log* const logFt = new LV2_Log_Log;
6757 logFt->handle = this;
6758 logFt->printf = carla_lv2_log_printf;
6759 logFt->vprintf = carla_lv2_log_vprintf;
6761 LV2_State_Free_Path* const stateFreePathFt = new LV2_State_Free_Path;
6762 stateFreePathFt->handle = this;
6763 stateFreePathFt->free_path = carla_lv2_state_free_path;
6765 LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
6766 stateMakePathFt->handle = this;
6767 stateMakePathFt->path = carla_lv2_state_make_path_tmp;
6769 LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
6770 stateMapPathFt->handle = this;
6771 stateMapPathFt->abstract_path = carla_lv2_state_map_to_abstract_path_tmp;
6772 stateMapPathFt->absolute_path = carla_lv2_state_map_to_absolute_path_tmp;
6774 LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
6775 programsFt->handle = this;
6776 programsFt->program_changed = carla_lv2_program_changed;
6778 LV2_Resize_Port_Resize* const rsPortFt = new LV2_Resize_Port_Resize;
6779 rsPortFt->data = this;
6780 rsPortFt->resize = carla_lv2_resize_port;
6782 LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
6783 lv2_rtmempool_init(rtMemPoolFt);
6785 LV2_RtMemPool_Pool_Deprecated* const rtMemPoolOldFt = new LV2_RtMemPool_Pool_Deprecated;
6786 lv2_rtmempool_init_deprecated(rtMemPoolOldFt);
6788 LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
6789 uriMapFt->callback_data = this;
6790 uriMapFt->uri_to_id = carla_lv2_uri_to_id;
6792 LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
6793 uridMapFt->handle = this;
6794 uridMapFt->map = carla_lv2_urid_map;
6796 LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
6797 uridUnmapFt->handle = this;
6798 uridUnmapFt->unmap = carla_lv2_urid_unmap;
6800 LV2_Worker_Schedule* const workerFt = new LV2_Worker_Schedule;
6801 workerFt->handle = this;
6802 workerFt->schedule_work = carla_lv2_worker_schedule;
6804 LV2_Inline_Display* const inlineDisplay = new LV2_Inline_Display;
6805 inlineDisplay->handle = this;
6806 inlineDisplay->queue_draw = carla_lv2_inline_display_queue_draw;
6808 LV2_Midnam* const midnam = new LV2_Midnam;
6809 midnam->handle = this;
6810 midnam->update = carla_lv2_midnam_update;
6812 LV2_ControlInputPort_Change_Request* const portChangeReq = new LV2_ControlInputPort_Change_Request;
6813 portChangeReq->handle = this;
6814 portChangeReq->request_change = carla_lv2_ctrl_in_port_change_req;
6816 // ---------------------------------------------------------------
6817 // initialize features (part 2)
6819 for (uint32_t j=0; j < kFeatureCountPlugin; ++j)
6820 fFeatures[j] = new LV2_Feature;
6822 fFeatures[kFeatureIdBufSizeBounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
6823 fFeatures[kFeatureIdBufSizeBounded]->data = nullptr;
6825 fFeatures[kFeatureIdBufSizeFixed]->URI = fNeedsFixedBuffers
6826 ? LV2_BUF_SIZE__fixedBlockLength
6827 : LV2_BUF_SIZE__boundedBlockLength;
6828 fFeatures[kFeatureIdBufSizeFixed]->data = nullptr;
6830 fFeatures[kFeatureIdBufSizePowerOf2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
6831 fFeatures[kFeatureIdBufSizePowerOf2]->data = nullptr;
6833 fFeatures[kFeatureIdEvent]->URI = LV2_EVENT_URI;
6834 fFeatures[kFeatureIdEvent]->data = eventFt;
6836 fFeatures[kFeatureIdHardRtCapable]->URI = LV2_CORE__hardRTCapable;
6837 fFeatures[kFeatureIdHardRtCapable]->data = nullptr;
6839 fFeatures[kFeatureIdInPlaceBroken]->URI = LV2_CORE__inPlaceBroken;
6840 fFeatures[kFeatureIdInPlaceBroken]->data = nullptr;
6842 fFeatures[kFeatureIdIsLive]->URI = LV2_CORE__isLive;
6843 fFeatures[kFeatureIdIsLive]->data = nullptr;
6845 fFeatures[kFeatureIdLogs]->URI = LV2_LOG__log;
6846 fFeatures[kFeatureIdLogs]->data = logFt;
6848 fFeatures[kFeatureIdOptions]->URI = LV2_OPTIONS__options;
6849 fFeatures[kFeatureIdOptions]->data = fLv2Options.opts;
6851 fFeatures[kFeatureIdPrograms]->URI = LV2_PROGRAMS__Host;
6852 fFeatures[kFeatureIdPrograms]->data = programsFt;
6854 fFeatures[kFeatureIdResizePort]->URI = LV2_RESIZE_PORT__resize;
6855 fFeatures[kFeatureIdResizePort]->data = rsPortFt;
6857 fFeatures[kFeatureIdRtMemPool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
6858 fFeatures[kFeatureIdRtMemPool]->data = rtMemPoolFt;
6860 fFeatures[kFeatureIdRtMemPoolOld]->URI = LV2_RTSAFE_MEMORY_POOL_DEPRECATED_URI;
6861 fFeatures[kFeatureIdRtMemPoolOld]->data = rtMemPoolOldFt;
6863 fFeatures[kFeatureIdStateFreePath]->URI = LV2_STATE__freePath;
6864 fFeatures[kFeatureIdStateFreePath]->data = stateFreePathFt;
6866 fFeatures[kFeatureIdStateMakePath]->URI = LV2_STATE__makePath;
6867 fFeatures[kFeatureIdStateMakePath]->data = stateMakePathFt;
6869 fFeatures[kFeatureIdStateMapPath]->URI = LV2_STATE__mapPath;
6870 fFeatures[kFeatureIdStateMapPath]->data = stateMapPathFt;
6872 fFeatures[kFeatureIdStrictBounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
6873 fFeatures[kFeatureIdStrictBounds]->data = nullptr;
6875 fFeatures[kFeatureIdUriMap]->URI = LV2_URI_MAP_URI;
6876 fFeatures[kFeatureIdUriMap]->data = uriMapFt;
6878 fFeatures[kFeatureIdUridMap]->URI = LV2_URID__map;
6879 fFeatures[kFeatureIdUridMap]->data = uridMapFt;
6881 fFeatures[kFeatureIdUridUnmap]->URI = LV2_URID__unmap;
6882 fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;
6884 fFeatures[kFeatureIdWorker]->URI = LV2_WORKER__schedule;
6885 fFeatures[kFeatureIdWorker]->data = workerFt;
6887 fFeatures[kFeatureIdInlineDisplay]->URI = LV2_INLINEDISPLAY__queue_draw;
6888 fFeatures[kFeatureIdInlineDisplay]->data = inlineDisplay;
6890 fFeatures[kFeatureIdMidnam]->URI = LV2_MIDNAM__update;
6891 fFeatures[kFeatureIdMidnam]->data = midnam;
6893 fFeatures[kFeatureIdCtrlInPortChangeReq]->URI = LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI;
6894 fFeatures[kFeatureIdCtrlInPortChangeReq]->data = portChangeReq;
6896 // ---------------------------------------------------------------
6897 // initialize features (part 3)
6899 LV2_State_Make_Path* const stateMakePathFt2 = new LV2_State_Make_Path;
6900 stateMakePathFt2->handle = this;
6901 stateMakePathFt2->path = carla_lv2_state_make_path_real;
6903 LV2_State_Map_Path* const stateMapPathFt2 = new LV2_State_Map_Path;
6904 stateMapPathFt2->handle = this;
6905 stateMapPathFt2->abstract_path = carla_lv2_state_map_to_abstract_path_real;
6906 stateMapPathFt2->absolute_path = carla_lv2_state_map_to_absolute_path_real;
6908 for (uint32_t j=0; j < kStateFeatureCountAll; ++j)
6909 fStateFeatures[j] = new LV2_Feature;
6911 fStateFeatures[kStateFeatureIdFreePath]->URI = LV2_STATE__freePath;
6912 fStateFeatures[kStateFeatureIdFreePath]->data = stateFreePathFt;
6914 fStateFeatures[kStateFeatureIdMakePath]->URI = LV2_STATE__makePath;
6915 fStateFeatures[kStateFeatureIdMakePath]->data = stateMakePathFt2;
6917 fStateFeatures[kStateFeatureIdMapPath]->URI = LV2_STATE__mapPath;
6918 fStateFeatures[kStateFeatureIdMapPath]->data = stateMapPathFt2;
6920 fStateFeatures[kStateFeatureIdWorker]->URI = LV2_WORKER__schedule;
6921 fStateFeatures[kStateFeatureIdWorker]->data = workerFt;
6923 // ---------------------------------------------------------------
6924 // initialize plugin
6926 try {
6927 fHandle = fDescriptor->instantiate(fDescriptor, pData->engine->getSampleRate(), fRdfDescriptor->Bundle, fFeatures);
6928 } catch(...) {}
6930 if (fHandle == nullptr)
6932 pData->engine->setLastError("Plugin failed to initialize");
6933 return false;
6936 recheckExtensions();
6938 // ---------------------------------------------------------------
6939 // set options
6941 pData->options = 0x0;
6943 if (fLatencyIndex >= 0 || getMidiOutCount() != 0 || fNeedsFixedBuffers)
6944 pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
6945 else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
6946 pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
6948 if (opts.forceStereo)
6949 pData->options |= PLUGIN_OPTION_FORCE_STEREO;
6950 else if (options & PLUGIN_OPTION_FORCE_STEREO)
6951 pData->options |= PLUGIN_OPTION_FORCE_STEREO;
6953 if (getMidiInCount() != 0)
6955 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
6956 pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
6957 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
6958 pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
6959 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
6960 pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
6961 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
6962 pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
6963 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
6964 pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
6965 if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PROGRAM_CHANGES))
6966 pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
6967 if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
6968 pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
6971 if (fExt.programs != nullptr && (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0)
6973 if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
6974 pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
6977 // ---------------------------------------------------------------
6978 // gui stuff
6980 if (fRdfDescriptor->UICount != 0)
6981 initUi();
6983 return true;
6985 // might be unused
6986 (void)needsArchBridge;
6989 // -------------------------------------------------------------------
6991 void initUi()
6993 // ---------------------------------------------------------------
6994 // find the most appropriate ui
6996 int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eMod, iCocoa, iWindows, iX11, iExt, iFinal;
6997 eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eMod = iCocoa = iWindows = iX11 = iExt = iFinal = -1;
6999 #if defined(LV2_UIS_ONLY_BRIDGES)
7000 const bool preferUiBridges = true;
7001 #elif defined(BUILD_BRIDGE)
7002 const bool preferUiBridges = false;
7003 #else
7004 const bool preferUiBridges = pData->engine->getOptions().preferUiBridges;
7005 #endif
7006 bool hasShowInterface = false;
7008 for (uint32_t i=0; i < fRdfDescriptor->UICount; ++i)
7010 CARLA_SAFE_ASSERT_CONTINUE(fRdfDescriptor->UIs[i].URI != nullptr);
7012 const int ii(static_cast<int>(i));
7014 switch (fRdfDescriptor->UIs[i].Type)
7016 case LV2_UI_QT4:
7017 if (isUiBridgeable(i))
7018 eQt4 = ii;
7019 break;
7020 case LV2_UI_QT5:
7021 if (isUiBridgeable(i))
7022 eQt5 = ii;
7023 break;
7024 case LV2_UI_GTK2:
7025 if (isUiBridgeable(i))
7026 eGtk2 = ii;
7027 break;
7028 case LV2_UI_GTK3:
7029 if (isUiBridgeable(i))
7030 eGtk3 = ii;
7031 break;
7032 #ifdef CARLA_OS_MAC
7033 case LV2_UI_COCOA:
7034 if (isUiBridgeable(i) && preferUiBridges)
7035 eCocoa = ii;
7036 iCocoa = ii;
7037 break;
7038 #endif
7039 #ifdef CARLA_OS_WIN
7040 case LV2_UI_WINDOWS:
7041 if (isUiBridgeable(i) && preferUiBridges)
7042 eWindows = ii;
7043 iWindows = ii;
7044 break;
7045 #endif
7046 case LV2_UI_X11:
7047 if (isUiBridgeable(i) && preferUiBridges)
7048 eX11 = ii;
7049 iX11 = ii;
7050 break;
7051 case LV2_UI_EXTERNAL:
7052 case LV2_UI_OLD_EXTERNAL:
7053 iExt = ii;
7054 break;
7055 case LV2_UI_MOD:
7056 eMod = ii;
7057 break;
7058 default:
7059 break;
7063 /**/ if (eQt4 >= 0)
7064 iFinal = eQt4;
7065 else if (eQt5 >= 0)
7066 iFinal = eQt5;
7067 else if (eGtk2 >= 0)
7068 iFinal = eGtk2;
7069 else if (eGtk3 >= 0)
7070 iFinal = eGtk3;
7071 #ifdef CARLA_OS_MAC
7072 else if (eCocoa >= 0)
7073 iFinal = eCocoa;
7074 #endif
7075 #ifdef CARLA_OS_WIN
7076 else if (eWindows >= 0)
7077 iFinal = eWindows;
7078 #endif
7079 #ifdef HAVE_X11
7080 else if (eX11 >= 0)
7081 iFinal = eX11;
7082 #endif
7083 #ifndef LV2_UIS_ONLY_BRIDGES
7084 # ifdef CARLA_OS_MAC
7085 else if (iCocoa >= 0)
7086 iFinal = iCocoa;
7087 # endif
7088 # ifdef CARLA_OS_WIN
7089 else if (iWindows >= 0)
7090 iFinal = iWindows;
7091 # endif
7092 # ifdef HAVE_X11
7093 else if (iX11 >= 0)
7094 iFinal = iX11;
7095 # endif
7096 #endif
7097 else if (iExt >= 0)
7098 iFinal = iExt;
7100 #ifndef BUILD_BRIDGE
7101 if (iFinal < 0)
7102 #endif
7104 // no suitable UI found, see if there's one which supports ui:showInterface
7105 for (uint32_t i=0; i < fRdfDescriptor->UICount && ! hasShowInterface; ++i)
7107 LV2_RDF_UI* const ui(&fRdfDescriptor->UIs[i]);
7109 for (uint32_t j=0; j < ui->ExtensionCount; ++j)
7111 CARLA_SAFE_ASSERT_CONTINUE(ui->Extensions[j] != nullptr);
7113 if (std::strcmp(ui->Extensions[j], LV2_UI__showInterface) != 0)
7114 continue;
7116 iFinal = static_cast<int>(i);
7117 hasShowInterface = true;
7118 break;
7122 if (iFinal < 0)
7124 if (eMod < 0)
7126 carla_stderr("Failed to find an appropriate LV2 UI for this plugin");
7127 return;
7130 // use MODGUI as last resort
7131 iFinal = eMod;
7135 fUI.rdfDescriptor = &fRdfDescriptor->UIs[iFinal];
7137 // ---------------------------------------------------------------
7138 // check supported ui features
7140 bool canContinue = true;
7141 bool canDelete = true;
7143 for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
7145 const char* const uri(fUI.rdfDescriptor->Features[i].URI);
7146 CARLA_SAFE_ASSERT_CONTINUE(uri != nullptr && uri[0] != '\0');
7148 if (! is_lv2_ui_feature_supported(uri))
7150 if (fUI.rdfDescriptor->Features[i].Required)
7152 carla_stderr("Plugin UI requires a feature that is not supported:\n%s", uri);
7153 canContinue = false;
7154 break;
7157 carla_stderr("Plugin UI wants a feature that is not supported (ignored):\n%s", uri);
7160 if (std::strcmp(uri, LV2_UI__makeResident) == 0 || std::strcmp(uri, LV2_UI__makeSONameResident) == 0)
7161 canDelete = false;
7162 else if (std::strcmp(uri, LV2_UI__requestValue) == 0)
7163 pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
7166 if (! canContinue)
7168 fUI.rdfDescriptor = nullptr;
7169 return;
7172 // ---------------------------------------------------------------
7173 // initialize ui according to type
7175 const LV2_Property uiType = fUI.rdfDescriptor->Type;
7177 #ifndef LV2_UIS_ONLY_INPROCESS
7178 if (
7179 (iFinal == eQt4 ||
7180 iFinal == eQt5 ||
7181 iFinal == eGtk2 ||
7182 iFinal == eGtk3 ||
7183 iFinal == eCocoa ||
7184 iFinal == eWindows ||
7185 iFinal == eX11 ||
7186 iFinal == eMod)
7187 #ifdef BUILD_BRIDGE
7188 && ! hasShowInterface
7189 #endif
7192 // -----------------------------------------------------------
7193 // initialize ui-bridge
7195 if (const char* const bridgeBinary = getUiBridgeBinary(uiType))
7197 carla_stdout("Will use UI-Bridge for '%s', binary: \"%s\"", pData->name, bridgeBinary);
7199 CarlaString uiTitle;
7201 if (pData->uiTitle.isNotEmpty())
7203 uiTitle = pData->uiTitle;
7205 else
7207 uiTitle = pData->name;
7208 uiTitle += " (GUI)";
7211 fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
7213 fUI.type = UI::TYPE_BRIDGE;
7214 fPipeServer.setData(bridgeBinary, fRdfDescriptor->URI, fUI.rdfDescriptor->URI);
7216 delete[] bridgeBinary;
7217 return;
7220 if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || iFinal == eMod)
7222 carla_stderr2("Failed to find UI bridge binary for '%s', cannot use UI", pData->name);
7223 fUI.rdfDescriptor = nullptr;
7224 return;
7227 #endif
7229 #ifdef LV2_UIS_ONLY_BRIDGES
7230 carla_stderr2("Failed to get an UI working, canBridge:%s", bool2str(isUiBridgeable(static_cast<uint32_t>(iFinal))));
7231 fUI.rdfDescriptor = nullptr;
7232 return;
7233 #endif
7235 // ---------------------------------------------------------------
7236 // open UI DLL
7238 #ifdef CARLA_OS_MAC
7239 // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
7240 removeFileFromQuarantine(fUI.rdfDescriptor->Binary);
7241 #endif
7243 if (! pData->uiLibOpen(fUI.rdfDescriptor->Binary, canDelete))
7245 carla_stderr2("Could not load UI library, error was:\n%s", pData->libError(fUI.rdfDescriptor->Binary));
7246 fUI.rdfDescriptor = nullptr;
7247 return;
7250 // ---------------------------------------------------------------
7251 // get UI DLL main entry
7253 LV2UI_DescriptorFunction uiDescFn = pData->uiLibSymbol<LV2UI_DescriptorFunction>("lv2ui_descriptor");
7255 if (uiDescFn == nullptr)
7257 carla_stderr2("Could not find the LV2UI Descriptor in the UI library");
7258 pData->uiLibClose();
7259 fUI.rdfDescriptor = nullptr;
7260 return;
7263 // ---------------------------------------------------------------
7264 // get UI descriptor that matches UI URI
7266 uint32_t i = 0;
7267 while ((fUI.descriptor = uiDescFn(i++)))
7269 if (std::strcmp(fUI.descriptor->URI, fUI.rdfDescriptor->URI) == 0)
7270 break;
7273 if (fUI.descriptor == nullptr)
7275 carla_stderr2("Could not find the requested GUI in the plugin UI library");
7276 pData->uiLibClose();
7277 fUI.rdfDescriptor = nullptr;
7278 return;
7281 // ---------------------------------------------------------------
7282 // check if ui is usable
7284 switch (uiType)
7286 case LV2_UI_NONE:
7287 carla_stdout("Will use LV2 Show Interface for '%s'", pData->name);
7288 fUI.type = UI::TYPE_EMBED;
7289 break;
7290 case LV2_UI_QT4:
7291 carla_stdout("Will use LV2 Qt4 UI for '%s', NOT!", pData->name);
7292 fUI.type = UI::TYPE_EMBED;
7293 break;
7294 case LV2_UI_QT5:
7295 carla_stdout("Will use LV2 Qt5 UI for '%s', NOT!", pData->name);
7296 fUI.type = UI::TYPE_EMBED;
7297 break;
7298 case LV2_UI_GTK2:
7299 carla_stdout("Will use LV2 Gtk2 UI for '%s', NOT!", pData->name);
7300 fUI.type = UI::TYPE_EMBED;
7301 break;
7302 case LV2_UI_GTK3:
7303 carla_stdout("Will use LV2 Gtk3 UI for '%s', NOT!", pData->name);
7304 fUI.type = UI::TYPE_EMBED;
7305 break;
7306 #ifdef CARLA_OS_MAC
7307 case LV2_UI_COCOA:
7308 carla_stdout("Will use LV2 Cocoa UI for '%s'", pData->name);
7309 fUI.type = UI::TYPE_EMBED;
7310 break;
7311 #endif
7312 #ifdef CARLA_OS_WIN
7313 case LV2_UI_WINDOWS:
7314 carla_stdout("Will use LV2 Windows UI for '%s'", pData->name);
7315 fUI.type = UI::TYPE_EMBED;
7316 break;
7317 #endif
7318 case LV2_UI_X11:
7319 #ifdef HAVE_X11
7320 carla_stdout("Will use LV2 X11 UI for '%s'", pData->name);
7321 #else
7322 carla_stdout("Will use LV2 X11 UI for '%s', NOT!", pData->name);
7323 #endif
7324 fUI.type = UI::TYPE_EMBED;
7325 break;
7326 case LV2_UI_EXTERNAL:
7327 case LV2_UI_OLD_EXTERNAL:
7328 carla_stdout("Will use LV2 External UI for '%s'", pData->name);
7329 fUI.type = UI::TYPE_EXTERNAL;
7330 break;
7333 if (fUI.type == UI::TYPE_NULL)
7335 pData->uiLibClose();
7336 fUI.descriptor = nullptr;
7337 fUI.rdfDescriptor = nullptr;
7338 return;
7341 // ---------------------------------------------------------------
7342 // initialize ui data
7345 CarlaString uiTitle;
7347 if (pData->uiTitle.isNotEmpty())
7349 uiTitle = pData->uiTitle;
7351 else
7353 uiTitle = pData->name;
7354 uiTitle += " (GUI)";
7357 fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
7360 fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size = (uint32_t)std::strlen(fLv2Options.windowTitle);
7361 fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
7363 // ---------------------------------------------------------------
7364 // initialize ui features (part 1)
7366 LV2_Extension_Data_Feature* const uiDataFt = new LV2_Extension_Data_Feature;
7367 uiDataFt->data_access = fDescriptor->extension_data;
7369 LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
7370 uiPortMapFt->handle = this;
7371 uiPortMapFt->port_index = carla_lv2_ui_port_map;
7373 LV2UI_Request_Value* const uiRequestValueFt = new LV2UI_Request_Value;
7374 uiRequestValueFt->handle = this;
7375 uiRequestValueFt->request = carla_lv2_ui_request_value;
7377 LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
7378 uiResizeFt->handle = this;
7379 uiResizeFt->ui_resize = carla_lv2_ui_resize;
7381 LV2UI_Touch* const uiTouchFt = new LV2UI_Touch;
7382 uiTouchFt->handle = this;
7383 uiTouchFt->touch = carla_lv2_ui_touch;
7385 LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host;
7386 uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed;
7387 uiExternalHostFt->plugin_human_id = fLv2Options.windowTitle;
7389 // ---------------------------------------------------------------
7390 // initialize ui features (part 2)
7392 for (uint32_t j=kFeatureCountPlugin; j < kFeatureCountAll; ++j)
7393 fFeatures[j] = new LV2_Feature;
7395 fFeatures[kFeatureIdUiDataAccess]->URI = LV2_DATA_ACCESS_URI;
7396 fFeatures[kFeatureIdUiDataAccess]->data = uiDataFt;
7398 fFeatures[kFeatureIdUiInstanceAccess]->URI = LV2_INSTANCE_ACCESS_URI;
7399 fFeatures[kFeatureIdUiInstanceAccess]->data = fHandle;
7401 fFeatures[kFeatureIdUiIdleInterface]->URI = LV2_UI__idleInterface;
7402 fFeatures[kFeatureIdUiIdleInterface]->data = nullptr;
7404 fFeatures[kFeatureIdUiFixedSize]->URI = LV2_UI__fixedSize;
7405 fFeatures[kFeatureIdUiFixedSize]->data = nullptr;
7407 fFeatures[kFeatureIdUiMakeResident]->URI = LV2_UI__makeResident;
7408 fFeatures[kFeatureIdUiMakeResident]->data = nullptr;
7410 fFeatures[kFeatureIdUiMakeResident2]->URI = LV2_UI__makeSONameResident;
7411 fFeatures[kFeatureIdUiMakeResident2]->data = nullptr;
7413 fFeatures[kFeatureIdUiNoUserResize]->URI = LV2_UI__noUserResize;
7414 fFeatures[kFeatureIdUiNoUserResize]->data = nullptr;
7416 fFeatures[kFeatureIdUiParent]->URI = LV2_UI__parent;
7417 fFeatures[kFeatureIdUiParent]->data = nullptr;
7419 fFeatures[kFeatureIdUiPortMap]->URI = LV2_UI__portMap;
7420 fFeatures[kFeatureIdUiPortMap]->data = uiPortMapFt;
7422 fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe;
7423 fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr;
7425 fFeatures[kFeatureIdUiRequestValue]->URI = LV2_UI__requestValue;
7426 fFeatures[kFeatureIdUiRequestValue]->data = uiRequestValueFt;
7428 fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize;
7429 fFeatures[kFeatureIdUiResize]->data = uiResizeFt;
7431 fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch;
7432 fFeatures[kFeatureIdUiTouch]->data = uiTouchFt;
7434 fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host;
7435 fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt;
7437 fFeatures[kFeatureIdExternalUiOld]->URI = LV2_EXTERNAL_UI_DEPRECATED_URI;
7438 fFeatures[kFeatureIdExternalUiOld]->data = uiExternalHostFt;
7440 // ---------------------------------------------------------------
7441 // initialize ui extensions
7443 if (fUI.descriptor->extension_data == nullptr)
7444 return;
7446 fExt.uiidle = (const LV2UI_Idle_Interface*)fUI.descriptor->extension_data(LV2_UI__idleInterface);
7447 fExt.uishow = (const LV2UI_Show_Interface*)fUI.descriptor->extension_data(LV2_UI__showInterface);
7448 fExt.uiresize = (const LV2UI_Resize*)fUI.descriptor->extension_data(LV2_UI__resize);
7449 fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface);
7451 // check if invalid
7452 if (fExt.uiidle != nullptr && fExt.uiidle->idle == nullptr)
7453 fExt.uiidle = nullptr;
7455 if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr))
7456 fExt.uishow = nullptr;
7458 if (fExt.uiresize != nullptr && fExt.uiresize->ui_resize == nullptr)
7459 fExt.uiresize = nullptr;
7461 if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr)
7462 fExt.uiprograms = nullptr;
7464 // don't use uiidle if external
7465 if (fUI.type == UI::TYPE_EXTERNAL)
7466 fExt.uiidle = nullptr;
7469 // -------------------------------------------------------------------
7471 void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom)
7473 CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
7474 carla_debug("CarlaPluginLV2::handleTransferAtom(%i, %p)", portIndex, atom);
7476 fAtomBufferEvIn.put(atom, portIndex);
7479 void handleUridMap(const LV2_URID urid, const char* const uri)
7481 CARLA_SAFE_ASSERT_RETURN(urid != kUridNull,);
7482 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
7483 carla_debug("CarlaPluginLV2::handleUridMap(%i v " P_SIZE ", \"%s\")", urid, fCustomURIDs.size()-1, uri);
7485 const std::size_t uriCount(fCustomURIDs.size());
7487 if (urid < uriCount)
7489 const char* const ourURI(carla_lv2_urid_unmap(this, urid));
7490 CARLA_SAFE_ASSERT_RETURN(ourURI != nullptr && ourURI != kUnmapFallback,);
7492 if (std::strcmp(ourURI, uri) != 0)
7494 carla_stderr2("PLUGIN :: wrong URI '%s' vs '%s'", ourURI, uri);
7497 else
7499 CARLA_SAFE_ASSERT_RETURN(urid == uriCount,);
7500 fCustomURIDs.push_back(uri);
7504 // -------------------------------------------------------------------
7506 void writeAtomPath(const char* const path, const LV2_URID urid)
7508 uint8_t atomBuf[4096];
7509 LV2_Atom_Forge atomForge;
7510 initAtomForge(atomForge);
7511 lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
7513 LV2_Atom_Forge_Frame forgeFrame;
7514 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
7516 lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
7517 lv2_atom_forge_bool(&atomForge, true);
7519 lv2_atom_forge_key(&atomForge, kUridPatchProperty);
7520 lv2_atom_forge_urid(&atomForge, urid);
7522 lv2_atom_forge_key(&atomForge, kUridPatchValue);
7523 lv2_atom_forge_path(&atomForge, path, static_cast<uint32_t>(std::strlen(path))+1);
7525 lv2_atom_forge_pop(&atomForge, &forgeFrame);
7527 LV2_Atom* const atom((LV2_Atom*)atomBuf);
7528 CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
7530 fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
7533 // -------------------------------------------------------------------
7535 private:
7536 LV2_Handle fHandle;
7537 LV2_Handle fHandle2;
7538 LV2_Feature* fFeatures[kFeatureCountAll+1];
7539 LV2_Feature* fStateFeatures[kStateFeatureCountAll+1];
7540 const LV2_Descriptor* fDescriptor;
7541 const LV2_RDF_Descriptor* fRdfDescriptor;
7543 float** fAudioInBuffers;
7544 float** fAudioOutBuffers;
7545 float** fCvInBuffers;
7546 float** fCvOutBuffers;
7547 float* fParamBuffers;
7549 bool fHasLoadDefaultState : 1;
7550 bool fHasThreadSafeRestore : 1;
7551 bool fNeedsFixedBuffers : 1;
7552 bool fNeedsUiClose : 1;
7553 bool fInlineDisplayNeedsRedraw : 1;
7554 int64_t fInlineDisplayLastRedrawTime;
7555 int32_t fLatencyIndex; // -1 if invalid
7556 int fStrictBounds; // -1 unsupported, 0 optional, 1 required
7558 Lv2AtomRingBuffer fAtomBufferEvIn;
7559 Lv2AtomRingBuffer fAtomBufferUiOut;
7560 Lv2AtomRingBuffer fAtomBufferWorkerIn;
7561 Lv2AtomRingBuffer fAtomBufferWorkerResp;
7562 uint8_t* fAtomBufferUiOutTmpData;
7563 uint8_t* fAtomBufferWorkerInTmpData;
7564 LV2_Atom* fAtomBufferRealtime;
7565 uint32_t fAtomBufferRealtimeSize;
7567 CarlaPluginLV2EventData fEventsIn;
7568 CarlaPluginLV2EventData fEventsOut;
7569 CarlaPluginLV2Options fLv2Options;
7570 #ifndef LV2_UIS_ONLY_INPROCESS
7571 CarlaPipeServerLV2 fPipeServer;
7572 #endif
7574 std::vector<std::string> fCustomURIDs;
7576 bool fFirstActive; // first process() call after activate()
7577 void* fLastStateChunk;
7578 EngineTimeInfo fLastTimeInfo;
7580 // if plugin provides path parameter, use it as fake "gui"
7581 CarlaString fFilePathURI;
7583 struct Extensions {
7584 const LV2_Options_Interface* options;
7585 const LV2_State_Interface* state;
7586 const LV2_Worker_Interface* worker;
7587 const LV2_Inline_Display_Interface* inlineDisplay;
7588 const LV2_Midnam_Interface* midnam;
7589 const LV2_Programs_Interface* programs;
7590 const LV2UI_Idle_Interface* uiidle;
7591 const LV2UI_Show_Interface* uishow;
7592 const LV2UI_Resize* uiresize;
7593 const LV2_Programs_UI_Interface* uiprograms;
7595 Extensions()
7596 : options(nullptr),
7597 state(nullptr),
7598 worker(nullptr),
7599 inlineDisplay(nullptr),
7600 midnam(nullptr),
7601 programs(nullptr),
7602 uiidle(nullptr),
7603 uishow(nullptr),
7604 uiresize(nullptr),
7605 uiprograms(nullptr) {}
7607 CARLA_DECLARE_NON_COPYABLE(Extensions);
7608 } fExt;
7610 struct UI {
7611 enum Type {
7612 TYPE_NULL = 0,
7613 #ifndef LV2_UIS_ONLY_INPROCESS
7614 TYPE_BRIDGE,
7615 #endif
7616 TYPE_EMBED,
7617 TYPE_EXTERNAL
7620 Type type;
7621 LV2UI_Handle handle;
7622 LV2UI_Widget widget;
7623 const LV2UI_Descriptor* descriptor;
7624 const LV2_RDF_UI* rdfDescriptor;
7626 bool embedded;
7627 bool fileBrowserOpen;
7628 const char* fileNeededForURI;
7629 CarlaPluginUI* window;
7631 UI()
7632 : type(TYPE_NULL),
7633 handle(nullptr),
7634 widget(nullptr),
7635 descriptor(nullptr),
7636 rdfDescriptor(nullptr),
7637 embedded(false),
7638 fileBrowserOpen(false),
7639 fileNeededForURI(nullptr),
7640 window(nullptr) {}
7642 ~UI()
7644 CARLA_SAFE_ASSERT(handle == nullptr);
7645 CARLA_SAFE_ASSERT(widget == nullptr);
7646 CARLA_SAFE_ASSERT(descriptor == nullptr);
7647 CARLA_SAFE_ASSERT(rdfDescriptor == nullptr);
7648 CARLA_SAFE_ASSERT(! fileBrowserOpen);
7649 CARLA_SAFE_ASSERT(fileNeededForURI == nullptr);
7650 CARLA_SAFE_ASSERT(window == nullptr);
7653 CARLA_DECLARE_NON_COPYABLE(UI);
7654 } fUI;
7656 // -------------------------------------------------------------------
7657 // Event Feature
7659 static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
7661 CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
7662 CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
7663 carla_debug("carla_lv2_event_ref(%p, %p)", callback_data, event);
7665 return 0;
7668 static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
7670 CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
7671 CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
7672 carla_debug("carla_lv2_event_unref(%p, %p)", callback_data, event);
7674 return 0;
7677 // -------------------------------------------------------------------
7678 // Logs Feature
7680 static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
7682 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
7683 CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
7684 CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
7686 #ifndef DEBUG
7687 if (type == kUridLogTrace)
7688 return 0;
7689 #endif
7691 va_list args;
7692 va_start(args, fmt);
7693 const int ret(carla_lv2_log_vprintf(handle, type, fmt, args));
7694 va_end(args);
7696 return ret;
7699 static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
7701 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
7702 CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
7703 CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
7705 int ret = 0;
7707 switch (type)
7709 case kUridLogError:
7710 std::fprintf(stderr, "\x1b[31m");
7711 ret = std::vfprintf(stderr, fmt, ap);
7712 std::fprintf(stderr, "\x1b[0m");
7713 break;
7715 case kUridLogNote:
7716 ret = std::vfprintf(stdout, fmt, ap);
7717 break;
7719 case kUridLogTrace:
7720 #ifdef DEBUG
7721 std::fprintf(stdout, "\x1b[30;1m");
7722 ret = std::vfprintf(stdout, fmt, ap);
7723 std::fprintf(stdout, "\x1b[0m");
7724 #endif
7725 break;
7727 case kUridLogWarning:
7728 ret = std::vfprintf(stderr, fmt, ap);
7729 break;
7731 default:
7732 break;
7735 return ret;
7738 // -------------------------------------------------------------------
7739 // Programs Feature
7741 static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
7743 CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7744 carla_debug("carla_lv2_program_changed(%p, %i)", handle, index);
7746 ((CarlaPluginLV2*)handle)->handleProgramChanged(index);
7749 // -------------------------------------------------------------------
7750 // Resize Port Feature
7752 static LV2_Resize_Port_Status carla_lv2_resize_port(LV2_Resize_Port_Feature_Data data, uint32_t index, size_t size)
7754 CARLA_SAFE_ASSERT_RETURN(data != nullptr, LV2_RESIZE_PORT_ERR_UNKNOWN);
7755 carla_debug("carla_lv2_program_changed(%p, %i, " P_SIZE ")", data, index, size);
7757 return ((CarlaPluginLV2*)data)->handleResizePort(index, size);
7760 // -------------------------------------------------------------------
7761 // State Feature
7763 static void carla_lv2_state_free_path(LV2_State_Free_Path_Handle handle, char* const path)
7765 CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7766 carla_debug("carla_lv2_state_free_path(%p, \"%s\")", handle, path);
7768 std::free(path);
7771 static char* carla_lv2_state_make_path_real(LV2_State_Make_Path_Handle handle, const char* path)
7773 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7774 CARLA_SAFE_ASSERT_RETURN(path != nullptr, nullptr);
7775 carla_debug("carla_lv2_state_make_path_real(%p, \"%s\")", handle, path);
7777 // allow empty paths to mean "current dir"
7778 if (path[0] == '\0')
7779 path = ".";
7781 const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, false, path));
7782 return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7785 static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle, const char* path)
7787 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7788 CARLA_SAFE_ASSERT_RETURN(path != nullptr, nullptr);
7789 carla_debug("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle, path);
7791 // allow empty paths to mean "current dir"
7792 if (path[0] == '\0')
7793 path = ".";
7795 const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, true, path));
7796 return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7799 static char* carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
7801 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7802 CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr, nullptr);
7803 carla_debug("carla_lv2_state_map_to_abstract_path_real(%p, \"%s\")", handle, absolute_path);
7805 // handle invalid empty paths the same way as lilv
7806 if (absolute_path[0] == '\0')
7807 return strdup("");
7809 return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(false, absolute_path);
7812 static char* carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
7814 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7815 CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr, nullptr);
7816 carla_debug("carla_lv2_state_map_to_abstract_path_tmp(%p, \"%s\")", handle, absolute_path);
7818 // handle invalid empty paths the same way as lilv
7819 if (absolute_path[0] == '\0')
7820 return strdup("");
7822 return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(true, absolute_path);
7825 static char* carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle, const char* abstract_path)
7827 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7828 CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr, nullptr);
7829 carla_debug("carla_lv2_state_map_to_absolute_path_real(%p, \"%s\")", handle, abstract_path);
7831 // allow empty paths to mean "current dir"
7832 if (abstract_path[0] == '\0')
7833 abstract_path = ".";
7835 const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, false, abstract_path));
7836 return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7839 static char* carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle, const char* abstract_path)
7841 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7842 CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr, nullptr);
7843 carla_debug("carla_lv2_state_map_to_absolute_path_tmp(%p, \"%s\")", handle, abstract_path);
7845 // allow empty paths to mean "current dir"
7846 if (abstract_path[0] == '\0')
7847 abstract_path = ".";
7849 const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, true, abstract_path));
7850 return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7853 static LV2_State_Status carla_lv2_state_store(LV2_State_Handle handle, uint32_t key, const void* value, size_t size, uint32_t type, uint32_t flags)
7855 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_STATE_ERR_UNKNOWN);
7856 carla_debug("carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i)", handle, key, value, size, type, flags);
7858 return ((CarlaPluginLV2*)handle)->handleStateStore(key, value, size, type, flags);
7861 static const void* carla_lv2_state_retrieve(LV2_State_Handle handle, uint32_t key, size_t* size, uint32_t* type, uint32_t* flags)
7863 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7864 carla_debug("carla_lv2_state_retrieve(%p, %i, %p, %p, %p)", handle, key, size, type, flags);
7866 return ((CarlaPluginLV2*)handle)->handleStateRetrieve(key, size, type, flags);
7869 // -------------------------------------------------------------------
7870 // URI-Map Feature
7872 static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
7874 carla_debug("carla_lv2_uri_to_id(%p, \"%s\", \"%s\")", data, map, uri);
7875 return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
7877 // unused
7878 (void)map;
7881 // -------------------------------------------------------------------
7882 // URID Feature
7884 static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
7886 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, kUridNull);
7887 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
7888 carla_debug("carla_lv2_urid_map(%p, \"%s\")", handle, uri);
7890 // Atom types
7891 if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
7892 return kUridAtomBlank;
7893 if (std::strcmp(uri, LV2_ATOM__Bool) == 0)
7894 return kUridAtomBool;
7895 if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
7896 return kUridAtomChunk;
7897 if (std::strcmp(uri, LV2_ATOM__Double) == 0)
7898 return kUridAtomDouble;
7899 if (std::strcmp(uri, LV2_ATOM__Event) == 0)
7900 return kUridAtomEvent;
7901 if (std::strcmp(uri, LV2_ATOM__Float) == 0)
7902 return kUridAtomFloat;
7903 if (std::strcmp(uri, LV2_ATOM__Int) == 0)
7904 return kUridAtomInt;
7905 if (std::strcmp(uri, LV2_ATOM__Literal) == 0)
7906 return kUridAtomLiteral;
7907 if (std::strcmp(uri, LV2_ATOM__Long) == 0)
7908 return kUridAtomLong;
7909 if (std::strcmp(uri, LV2_ATOM__Number) == 0)
7910 return kUridAtomNumber;
7911 if (std::strcmp(uri, LV2_ATOM__Object) == 0)
7912 return kUridAtomObject;
7913 if (std::strcmp(uri, LV2_ATOM__Path) == 0)
7914 return kUridAtomPath;
7915 if (std::strcmp(uri, LV2_ATOM__Property) == 0)
7916 return kUridAtomProperty;
7917 if (std::strcmp(uri, LV2_ATOM__Resource) == 0)
7918 return kUridAtomResource;
7919 if (std::strcmp(uri, LV2_ATOM__Sequence) == 0)
7920 return kUridAtomSequence;
7921 if (std::strcmp(uri, LV2_ATOM__Sound) == 0)
7922 return kUridAtomSound;
7923 if (std::strcmp(uri, LV2_ATOM__String) == 0)
7924 return kUridAtomString;
7925 if (std::strcmp(uri, LV2_ATOM__Tuple) == 0)
7926 return kUridAtomTuple;
7927 if (std::strcmp(uri, LV2_ATOM__URI) == 0)
7928 return kUridAtomURI;
7929 if (std::strcmp(uri, LV2_ATOM__URID) == 0)
7930 return kUridAtomURID;
7931 if (std::strcmp(uri, LV2_ATOM__Vector) == 0)
7932 return kUridAtomVector;
7933 if (std::strcmp(uri, LV2_ATOM__atomTransfer) == 0)
7934 return kUridAtomTransferAtom;
7935 if (std::strcmp(uri, LV2_ATOM__eventTransfer) == 0)
7936 return kUridAtomTransferEvent;
7938 // BufSize types
7939 if (std::strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
7940 return kUridBufMaxLength;
7941 if (std::strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
7942 return kUridBufMinLength;
7943 if (std::strcmp(uri, LV2_BUF_SIZE__nominalBlockLength) == 0)
7944 return kUridBufNominalLength;
7945 if (std::strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
7946 return kUridBufSequenceSize;
7948 // Log types
7949 if (std::strcmp(uri, LV2_LOG__Error) == 0)
7950 return kUridLogError;
7951 if (std::strcmp(uri, LV2_LOG__Note) == 0)
7952 return kUridLogNote;
7953 if (std::strcmp(uri, LV2_LOG__Trace) == 0)
7954 return kUridLogTrace;
7955 if (std::strcmp(uri, LV2_LOG__Warning) == 0)
7956 return kUridLogWarning;
7958 // Patch types
7959 if (std::strcmp(uri, LV2_PATCH__Set) == 0)
7960 return kUridPatchSet;
7961 if (std::strcmp(uri, LV2_PATCH__property) == 0)
7962 return kUridPatchProperty;
7963 if (std::strcmp(uri, LV2_PATCH__subject) == 0)
7964 return kUridPatchSubject;
7965 if (std::strcmp(uri, LV2_PATCH__value) == 0)
7966 return kUridPatchValue;
7968 // Time types
7969 if (std::strcmp(uri, LV2_TIME__Position) == 0)
7970 return kUridTimePosition;
7971 if (std::strcmp(uri, LV2_TIME__bar) == 0)
7972 return kUridTimeBar;
7973 if (std::strcmp(uri, LV2_TIME__barBeat) == 0)
7974 return kUridTimeBarBeat;
7975 if (std::strcmp(uri, LV2_TIME__beat) == 0)
7976 return kUridTimeBeat;
7977 if (std::strcmp(uri, LV2_TIME__beatUnit) == 0)
7978 return kUridTimeBeatUnit;
7979 if (std::strcmp(uri, LV2_TIME__beatsPerBar) == 0)
7980 return kUridTimeBeatsPerBar;
7981 if (std::strcmp(uri, LV2_TIME__beatsPerMinute) == 0)
7982 return kUridTimeBeatsPerMinute;
7983 if (std::strcmp(uri, LV2_TIME__frame) == 0)
7984 return kUridTimeFrame;
7985 if (std::strcmp(uri, LV2_TIME__framesPerSecond) == 0)
7986 return kUridTimeFramesPerSecond;
7987 if (std::strcmp(uri, LV2_TIME__speed) == 0)
7988 return kUridTimeSpeed;
7989 if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0)
7990 return kUridTimeTicksPerBeat;
7992 // Others
7993 if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0)
7994 return kUridMidiEvent;
7995 if (std::strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
7996 return kUridParamSampleRate;
7997 if (std::strcmp(uri, LV2_UI__backgroundColor) == 0)
7998 return kUridBackgroundColor;
7999 if (std::strcmp(uri, LV2_UI__foregroundColor) == 0)
8000 return kUridForegroundColor;
8001 #ifndef CARLA_OS_MAC
8002 if (std::strcmp(uri, LV2_UI__scaleFactor) == 0)
8003 return kUridScaleFactor;
8004 #endif
8005 if (std::strcmp(uri, LV2_UI__windowTitle) == 0)
8006 return kUridWindowTitle;
8008 // Custom Carla types
8009 if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_IN) == 0)
8010 return kUridCarlaAtomWorkerIn;
8011 if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_RESP) == 0)
8012 return kUridCarlaAtomWorkerResp;
8013 if (std::strcmp(uri, URI_CARLA_PARAMETER_CHANGE) == 0)
8014 return kUridCarlaParameterChange;
8015 if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TransientWindowId) == 0)
8016 return kUridCarlaTransientWindowId;
8018 // Custom plugin types
8019 return ((CarlaPluginLV2*)handle)->getCustomURID(uri);
8022 static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
8024 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
8025 CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, nullptr);
8026 carla_debug("carla_lv2_urid_unmap(%p, %i)", handle, urid);
8028 switch (urid)
8030 // Atom types
8031 case kUridAtomBlank:
8032 return LV2_ATOM__Blank;
8033 case kUridAtomBool:
8034 return LV2_ATOM__Bool;
8035 case kUridAtomChunk:
8036 return LV2_ATOM__Chunk;
8037 case kUridAtomDouble:
8038 return LV2_ATOM__Double;
8039 case kUridAtomEvent:
8040 return LV2_ATOM__Event;
8041 case kUridAtomFloat:
8042 return LV2_ATOM__Float;
8043 case kUridAtomInt:
8044 return LV2_ATOM__Int;
8045 case kUridAtomLiteral:
8046 return LV2_ATOM__Literal;
8047 case kUridAtomLong:
8048 return LV2_ATOM__Long;
8049 case kUridAtomNumber:
8050 return LV2_ATOM__Number;
8051 case kUridAtomObject:
8052 return LV2_ATOM__Object;
8053 case kUridAtomPath:
8054 return LV2_ATOM__Path;
8055 case kUridAtomProperty:
8056 return LV2_ATOM__Property;
8057 case kUridAtomResource:
8058 return LV2_ATOM__Resource;
8059 case kUridAtomSequence:
8060 return LV2_ATOM__Sequence;
8061 case kUridAtomSound:
8062 return LV2_ATOM__Sound;
8063 case kUridAtomString:
8064 return LV2_ATOM__String;
8065 case kUridAtomTuple:
8066 return LV2_ATOM__Tuple;
8067 case kUridAtomURI:
8068 return LV2_ATOM__URI;
8069 case kUridAtomURID:
8070 return LV2_ATOM__URID;
8071 case kUridAtomVector:
8072 return LV2_ATOM__Vector;
8073 case kUridAtomTransferAtom:
8074 return LV2_ATOM__atomTransfer;
8075 case kUridAtomTransferEvent:
8076 return LV2_ATOM__eventTransfer;
8078 // BufSize types
8079 case kUridBufMaxLength:
8080 return LV2_BUF_SIZE__maxBlockLength;
8081 case kUridBufMinLength:
8082 return LV2_BUF_SIZE__minBlockLength;
8083 case kUridBufNominalLength:
8084 return LV2_BUF_SIZE__nominalBlockLength;
8085 case kUridBufSequenceSize:
8086 return LV2_BUF_SIZE__sequenceSize;
8088 // Log types
8089 case kUridLogError:
8090 return LV2_LOG__Error;
8091 case kUridLogNote:
8092 return LV2_LOG__Note;
8093 case kUridLogTrace:
8094 return LV2_LOG__Trace;
8095 case kUridLogWarning:
8096 return LV2_LOG__Warning;
8098 // Patch types
8099 case kUridPatchSet:
8100 return LV2_PATCH__Set;
8101 case kUridPatchProperty:
8102 return LV2_PATCH__property;
8103 case kUridPatchSubject:
8104 return LV2_PATCH__subject;
8105 case kUridPatchValue:
8106 return LV2_PATCH__value;
8108 // Time types
8109 case kUridTimePosition:
8110 return LV2_TIME__Position;
8111 case kUridTimeBar:
8112 return LV2_TIME__bar;
8113 case kUridTimeBarBeat:
8114 return LV2_TIME__barBeat;
8115 case kUridTimeBeat:
8116 return LV2_TIME__beat;
8117 case kUridTimeBeatUnit:
8118 return LV2_TIME__beatUnit;
8119 case kUridTimeBeatsPerBar:
8120 return LV2_TIME__beatsPerBar;
8121 case kUridTimeBeatsPerMinute:
8122 return LV2_TIME__beatsPerMinute;
8123 case kUridTimeFrame:
8124 return LV2_TIME__frame;
8125 case kUridTimeFramesPerSecond:
8126 return LV2_TIME__framesPerSecond;
8127 case kUridTimeSpeed:
8128 return LV2_TIME__speed;
8129 case kUridTimeTicksPerBeat:
8130 return LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat;
8132 // Others
8133 case kUridMidiEvent:
8134 return LV2_MIDI__MidiEvent;
8135 case kUridParamSampleRate:
8136 return LV2_PARAMETERS__sampleRate;
8137 case kUridBackgroundColor:
8138 return LV2_UI__backgroundColor;
8139 case kUridForegroundColor:
8140 return LV2_UI__foregroundColor;
8141 #ifndef CARLA_OS_MAC
8142 case kUridScaleFactor:
8143 return LV2_UI__scaleFactor;
8144 #endif
8145 case kUridWindowTitle:
8146 return LV2_UI__windowTitle;
8148 // Custom Carla types
8149 case kUridCarlaAtomWorkerIn:
8150 return URI_CARLA_ATOM_WORKER_IN;
8151 case kUridCarlaAtomWorkerResp:
8152 return URI_CARLA_ATOM_WORKER_RESP;
8153 case kUridCarlaParameterChange:
8154 return URI_CARLA_PARAMETER_CHANGE;
8155 case kUridCarlaTransientWindowId:
8156 return LV2_KXSTUDIO_PROPERTIES__TransientWindowId;
8159 // Custom plugin types
8160 return ((CarlaPluginLV2*)handle)->getCustomURIDString(urid);
8163 // -------------------------------------------------------------------
8164 // Worker Feature
8166 static LV2_Worker_Status carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data)
8168 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
8169 carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle, size, data);
8171 return ((CarlaPluginLV2*)handle)->handleWorkerSchedule(size, data);
8174 static LV2_Worker_Status carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void* data)
8176 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
8177 carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle, size, data);
8179 return ((CarlaPluginLV2*)handle)->handleWorkerRespond(size, data);
8182 // -------------------------------------------------------------------
8183 // Inline Display Feature
8185 static void carla_lv2_inline_display_queue_draw(LV2_Inline_Display_Handle handle)
8187 CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
8188 // carla_debug("carla_lv2_inline_display_queue_draw(%p)", handle);
8190 ((CarlaPluginLV2*)handle)->handleInlineDisplayQueueRedraw();
8193 // -------------------------------------------------------------------
8194 // Midnam Feature
8196 static void carla_lv2_midnam_update(LV2_Midnam_Handle handle)
8198 CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
8199 carla_stdout("carla_lv2_midnam_update(%p)", handle);
8201 ((CarlaPluginLV2*)handle)->handleMidnamUpdate();
8204 // -------------------------------------------------------------------
8205 // ControlInputPort change request Feature
8207 static LV2_ControlInputPort_Change_Status carla_lv2_ctrl_in_port_change_req(
8208 LV2_ControlInputPort_Change_Request_Handle handle, uint32_t index, float value)
8210 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_CONTROL_INPUT_PORT_CHANGE_ERR_UNKNOWN);
8211 carla_stdout("carla_lv2_ctrl_in_port_change_req(%p, %u, %f)", handle, index, value);
8213 return ((CarlaPluginLV2*)handle)->handleCtrlInPortChangeReq(index, value);
8216 // -------------------------------------------------------------------
8217 // External UI Feature
8219 static void carla_lv2_external_ui_closed(LV2UI_Controller controller)
8221 CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
8222 carla_debug("carla_lv2_external_ui_closed(%p)", controller);
8224 ((CarlaPluginLV2*)controller)->handleExternalUIClosed();
8227 // -------------------------------------------------------------------
8228 // UI Port-Map Feature
8230 static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
8232 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_INVALID_PORT_INDEX);
8233 carla_debug("carla_lv2_ui_port_map(%p, \"%s\")", handle, symbol);
8235 return ((CarlaPluginLV2*)handle)->handleUIPortMap(symbol);
8238 // ----------------------------------------------------------------------------------------------------------------
8239 // UI Request Parameter Feature
8241 static LV2UI_Request_Value_Status carla_lv2_ui_request_value(LV2UI_Feature_Handle handle,
8242 LV2_URID key,
8243 LV2_URID type,
8244 const LV2_Feature* const* features)
8246 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
8247 carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle, key, type, features);
8249 return ((CarlaPluginLV2*)handle)->handleUIRequestValue(key, type, features);
8252 // -------------------------------------------------------------------
8253 // UI Resize Feature
8255 static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
8257 CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1);
8258 carla_debug("carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
8260 return ((CarlaPluginLV2*)handle)->handleUIResize(width, height);
8263 // -------------------------------------------------------------------
8264 // UI Touch Feature
8266 static void carla_lv2_ui_touch(LV2UI_Feature_Handle handle, uint32_t port_index, bool touch)
8268 CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
8269 carla_debug("carla_lv2_ui_touch(%p, %u, %s)", handle, port_index, bool2str(touch));
8271 ((CarlaPluginLV2*)handle)->handleUITouch(port_index, touch);
8274 // -------------------------------------------------------------------
8275 // UI Extension
8277 static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
8279 CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
8280 carla_debug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
8282 ((CarlaPluginLV2*)controller)->handleUIWrite(port_index, buffer_size, format, buffer);
8285 // -------------------------------------------------------------------
8286 // Lilv State
8288 static void carla_lilv_set_port_value(const char* port_symbol, void* user_data, const void* value, uint32_t size, uint32_t type)
8290 CARLA_SAFE_ASSERT_RETURN(user_data != nullptr,);
8291 carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i", port_symbol, user_data, value, size, type);
8293 ((CarlaPluginLV2*)user_data)->handleLilvSetPortValue(port_symbol, value, size, type);
8296 // -------------------------------------------------------------------
8298 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginLV2)
8301 // -------------------------------------------------------------------------------------------------------------------
8303 #ifndef LV2_UIS_ONLY_INPROCESS
8304 bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept
8306 if (std::strcmp(msg, "exiting") == 0)
8308 closePipeServer();
8309 fUiState = UiHide;
8310 return true;
8313 if (std::strcmp(msg, "control") == 0)
8315 uint32_t index;
8316 float value;
8318 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8319 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
8321 try {
8322 kPlugin->handleUIWrite(index, sizeof(float), kUridNull, &value);
8323 } CARLA_SAFE_EXCEPTION("magReceived control");
8325 return true;
8328 if (std::strcmp(msg, "pcontrol") == 0)
8330 const char* uri;
8331 float value;
8333 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, true), true);
8334 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
8336 try {
8337 kPlugin->handleUIBridgeParameter(uri, value);
8338 } CARLA_SAFE_EXCEPTION("magReceived pcontrol");
8340 return true;
8343 if (std::strcmp(msg, "atom") == 0)
8345 uint32_t index, atomTotalSize, base64Size;
8346 const char* base64atom;
8348 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8349 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(atomTotalSize), true);
8350 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size), true);
8351 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom, false, base64Size), true);
8353 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(base64atom));
8354 CARLA_SAFE_ASSERT_UINT2_RETURN(chunk.size() >= sizeof(LV2_Atom), chunk.size(), sizeof(LV2_Atom), true);
8356 #ifdef CARLA_PROPER_CPP11_SUPPORT
8357 const LV2_Atom* const atom((const LV2_Atom*)chunk.data());
8358 #else
8359 const LV2_Atom* const atom((const LV2_Atom*)&chunk.front());
8360 #endif
8361 CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom) == chunk.size(), true);
8363 try {
8364 kPlugin->handleUIWrite(index, lv2_atom_total_size(atom), kUridAtomTransferEvent, atom);
8365 } CARLA_SAFE_EXCEPTION("magReceived atom");
8367 return true;
8370 if (std::strcmp(msg, "program") == 0)
8372 uint32_t index;
8374 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8376 try {
8377 kPlugin->setMidiProgram(static_cast<int32_t>(index), false, true, true, false);
8378 } CARLA_SAFE_EXCEPTION("msgReceived program");
8380 return true;
8383 if (std::strcmp(msg, "urid") == 0)
8385 uint32_t urid, size;
8386 const char* uri;
8388 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(urid), true);
8389 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(size), true);
8390 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, false, size), true);
8392 if (urid != 0)
8394 try {
8395 kPlugin->handleUridMap(urid, uri);
8396 } CARLA_SAFE_EXCEPTION("msgReceived urid");
8399 return true;
8402 if (std::strcmp(msg, "reloadprograms") == 0)
8404 int32_t index;
8406 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
8408 try {
8409 kPlugin->handleProgramChanged(index);
8410 } CARLA_SAFE_EXCEPTION("handleProgramChanged");
8412 return true;
8415 if (std::strcmp(msg, "requestvalue") == 0)
8417 uint32_t key, type;
8419 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(key), true);
8420 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(type), true);
8422 if (key != 0)
8424 try {
8425 kPlugin->handleUIRequestValue(key, type, nullptr);
8426 } CARLA_SAFE_EXCEPTION("msgReceived requestvalue");
8429 return true;
8432 return false;
8434 #endif
8436 // -------------------------------------------------------------------------------------------------------------------
8438 CarlaPluginPtr CarlaPlugin::newLV2(const Initializer& init)
8440 carla_debug("CarlaPlugin::newLV2({%p, \"%s\", \"%s\"})", init.engine, init.name, init.label);
8442 std::shared_ptr<CarlaPluginLV2> plugin(new CarlaPluginLV2(init.engine, init.id));
8444 const char* needsArchBridge = nullptr;
8445 if (plugin->init(plugin, init.name, init.label, init.options, needsArchBridge))
8446 return plugin;
8448 #ifndef CARLA_OS_WASM
8449 if (needsArchBridge != nullptr)
8451 CarlaString bridgeBinary(init.engine->getOptions().binaryDir);
8452 bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-native";
8454 return CarlaPlugin::newBridge(init, BINARY_NATIVE, PLUGIN_LV2, needsArchBridge, bridgeBinary);
8456 #endif
8458 return nullptr;
8461 // used in CarlaStandalone.cpp
8462 const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height);
8464 const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height)
8466 const std::shared_ptr<CarlaPluginLV2>& lv2Plugin((const std::shared_ptr<CarlaPluginLV2>&)plugin);
8468 return lv2Plugin->renderInlineDisplay(width, height);
8471 // -------------------------------------------------------------------------------------------------------------------
8473 CARLA_BACKEND_END_NAMESPACE