1 /*
2  * Carla LV2 Plugin
3  * Copyright (C) 2011-2021 Filipe Coelho <falktx@falktx.com>
4  *
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.
9  *
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.
14  *
15  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
16  */
17 
18 // testing macros
19 // #define LV2_UIS_ONLY_BRIDGES
20 // #define LV2_UIS_ONLY_INPROCESS
21 
22 #include "CarlaPluginInternal.hpp"
23 #include "CarlaEngine.hpp"
24 
25 #include "CarlaLv2Utils.hpp"
26 
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"
34 
35 #include "../modules/lilv/config/lilv_config.h"
36 
37 extern "C" {
38 #include "rtmempool/rtmempool-lv2.h"
39 }
40 
41 #include "water/files/File.h"
42 #include "water/misc/Time.h"
43 
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
51 
52 #include <string>
53 #include <vector>
54 
55 using water::File;
56 
57 #define URI_CARLA_ATOM_WORKER_IN   "http://kxstudio.sf.net/ns/carla/atomWorkerIn"
58 #define URI_CARLA_ATOM_WORKER_RESP "http://kxstudio.sf.net/ns/carla/atomWorkerResp"
59 #define URI_CARLA_PARAMETER_CHANGE "http://kxstudio.sf.net/ns/carla/parameterChange"
60 
61 CARLA_BACKEND_START_NAMESPACE
62 
63 // -------------------------------------------------------------------------------------------------------------------
64 // Fallback data
65 
66 static const CustomData       kCustomDataFallback       = { nullptr, nullptr, nullptr };
67 static /* */ CustomData       kCustomDataFallbackNC     = { nullptr, nullptr, nullptr };
68 static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
69 static const char* const      kUnmapFallback            = "urn:null";
70 
71 // -------------------------------------------------------------------------------------------------------------------
72 
73 // Maximum default buffer size
74 const uint MAX_DEFAULT_BUFFER_SIZE = 8192; // 0x2000
75 
76 // Extra Plugin Hints
77 const uint PLUGIN_HAS_EXTENSION_OPTIONS        = 0x01000;
78 const uint PLUGIN_HAS_EXTENSION_PROGRAMS       = 0x02000;
79 const uint PLUGIN_HAS_EXTENSION_STATE          = 0x04000;
80 const uint PLUGIN_HAS_EXTENSION_WORKER         = 0x08000;
81 const uint PLUGIN_HAS_EXTENSION_INLINE_DISPLAY = 0x10000;
82 const uint PLUGIN_HAS_EXTENSION_MIDNAM         = 0x20000;
83 
84 // LV2 Event Data/Types
85 const uint CARLA_EVENT_DATA_ATOM    = 0x01;
86 const uint CARLA_EVENT_DATA_EVENT   = 0x02;
87 const uint CARLA_EVENT_DATA_MIDI_LL = 0x04;
88 const uint CARLA_EVENT_TYPE_MESSAGE = 0x10; // unused
89 const uint CARLA_EVENT_TYPE_MIDI    = 0x20;
90 const uint CARLA_EVENT_TYPE_TIME    = 0x40;
91 
92 // LV2 URI Map Ids
93 enum CarlaLv2URIDs {
94     kUridNull = 0,
95     kUridAtomBlank,
96     kUridAtomBool,
97     kUridAtomChunk,
98     kUridAtomDouble,
99     kUridAtomEvent,
100     kUridAtomFloat,
101     kUridAtomInt,
102     kUridAtomLiteral,
103     kUridAtomLong,
104     kUridAtomNumber,
105     kUridAtomObject,
106     kUridAtomPath,
107     kUridAtomProperty,
108     kUridAtomResource,
109     kUridAtomSequence,
110     kUridAtomSound,
111     kUridAtomString,
112     kUridAtomTuple,
113     kUridAtomURI,
114     kUridAtomURID,
115     kUridAtomVector,
116     kUridAtomTransferAtom,
117     kUridAtomTransferEvent,
118     kUridBufMaxLength,
119     kUridBufMinLength,
120     kUridBufNominalLength,
121     kUridBufSequenceSize,
122     kUridLogError,
123     kUridLogNote,
124     kUridLogTrace,
125     kUridLogWarning,
126     kUridPatchSet,
127     kUridPatchProperty,
128     kUridPatchSubject,
129     kUridPatchValue,
130     // time base type
131     kUridTimePosition,
132      // time values
133     kUridTimeBar,
134     kUridTimeBarBeat,
135     kUridTimeBeat,
136     kUridTimeBeatUnit,
137     kUridTimeBeatsPerBar,
138     kUridTimeBeatsPerMinute,
139     kUridTimeFrame,
140     kUridTimeFramesPerSecond,
141     kUridTimeSpeed,
142     kUridTimeTicksPerBeat,
143     kUridMidiEvent,
144     kUridParamSampleRate,
145     // ui stuff
146     kUridBackgroundColor,
147     kUridForegroundColor,
148     kUridScaleFactor,
149     kUridWindowTitle,
150     // custom carla props
151     kUridCarlaAtomWorkerIn,
152     kUridCarlaAtomWorkerResp,
153     kUridCarlaParameterChange,
154     kUridCarlaTransientWindowId,
155     // count
156     kUridCount
157 };
158 
159 // LV2 Feature Ids
160 enum CarlaLv2Features {
161     // DSP features
162     kFeatureIdBufSizeBounded = 0,
163     kFeatureIdBufSizeFixed,
164     kFeatureIdBufSizePowerOf2,
165     kFeatureIdEvent,
166     kFeatureIdHardRtCapable,
167     kFeatureIdInPlaceBroken,
168     kFeatureIdIsLive,
169     kFeatureIdLogs,
170     kFeatureIdOptions,
171     kFeatureIdPrograms,
172     kFeatureIdResizePort,
173     kFeatureIdRtMemPool,
174     kFeatureIdRtMemPoolOld,
175     kFeatureIdStateFreePath,
176     kFeatureIdStateMakePath,
177     kFeatureIdStateMapPath,
178     kFeatureIdStrictBounds,
179     kFeatureIdUriMap,
180     kFeatureIdUridMap,
181     kFeatureIdUridUnmap,
182     kFeatureIdWorker,
183     kFeatureIdInlineDisplay,
184     kFeatureIdMidnam,
185     kFeatureCountPlugin,
186     // UI features
187     kFeatureIdUiDataAccess = kFeatureCountPlugin,
188     kFeatureIdUiInstanceAccess,
189     kFeatureIdUiIdleInterface,
190     kFeatureIdUiFixedSize,
191     kFeatureIdUiMakeResident,
192     kFeatureIdUiMakeResident2,
193     kFeatureIdUiNoUserResize,
194     kFeatureIdUiParent,
195     kFeatureIdUiPortMap,
196     kFeatureIdUiPortSubscribe,
197     kFeatureIdUiResize,
198     kFeatureIdUiRequestValue,
199     kFeatureIdUiTouch,
200     kFeatureIdExternalUi,
201     kFeatureIdExternalUiOld,
202     kFeatureCountAll
203 };
204 
205 // LV2 Feature Ids (special state handlers)
206 enum CarlaLv2StateFeatures {
207     kStateFeatureIdFreePath,
208     kStateFeatureIdMakePath,
209     kStateFeatureIdMapPath,
210     kStateFeatureIdWorker,
211     kStateFeatureCountAll
212 };
213 
214 // -------------------------------------------------------------------------------------------------------------------
215 
216 struct Lv2EventData {
217     uint32_t type;
218     uint32_t rindex;
219     CarlaEngineEventPort* port;
220 
221     union {
222         LV2_Atom_Buffer* atom;
223         LV2_Event_Buffer* event;
224         LV2_MIDI midi;
225     };
226 
Lv2EventDataLv2EventData227     Lv2EventData() noexcept
228         : type(0x0),
229           rindex(0),
230           port(nullptr) {}
231 
~Lv2EventDataLv2EventData232     ~Lv2EventData() noexcept
233     {
234         if (port != nullptr)
235         {
236             delete port;
237             port = nullptr;
238         }
239 
240         const uint32_t rtype(type);
241         type = 0x0;
242 
243         if (rtype & CARLA_EVENT_DATA_ATOM)
244         {
245             CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
246 
247             std::free(atom);
248             atom = nullptr;
249         }
250         else if (rtype & CARLA_EVENT_DATA_EVENT)
251         {
252             CARLA_SAFE_ASSERT_RETURN(event != nullptr,);
253 
254             std::free(event);
255             event = nullptr;
256         }
257         else if (rtype & CARLA_EVENT_DATA_MIDI_LL)
258         {
259             CARLA_SAFE_ASSERT_RETURN(midi.data != nullptr,);
260 
261             delete[] midi.data;
262             midi.data = nullptr;
263         }
264     }
265 
266     CARLA_DECLARE_NON_COPY_STRUCT(Lv2EventData)
267 };
268 
269 struct CarlaPluginLV2EventData {
270     uint32_t count;
271     Lv2EventData* data;
272     Lv2EventData* ctrl; // default port, either this->data[x] or pData->portIn/Out
273     uint32_t ctrlIndex;
274 
CarlaPluginLV2EventDataCarlaPluginLV2EventData275     CarlaPluginLV2EventData() noexcept
276         : count(0),
277           data(nullptr),
278           ctrl(nullptr),
279           ctrlIndex(0) {}
280 
~CarlaPluginLV2EventDataCarlaPluginLV2EventData281     ~CarlaPluginLV2EventData() noexcept
282     {
283         CARLA_SAFE_ASSERT_INT(count == 0, count);
284         CARLA_SAFE_ASSERT(data == nullptr);
285         CARLA_SAFE_ASSERT(ctrl == nullptr);
286         CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
287     }
288 
createNewCarlaPluginLV2EventData289     void createNew(const uint32_t newCount)
290     {
291         CARLA_SAFE_ASSERT_INT(count == 0, count);
292         CARLA_SAFE_ASSERT_INT(ctrlIndex == 0, ctrlIndex);
293         CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
294         CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,);
295         CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
296 
297         data  = new Lv2EventData[newCount];
298         count = newCount;
299 
300         ctrl      = nullptr;
301         ctrlIndex = 0;
302     }
303 
clearCarlaPluginLV2EventData304     void clear(CarlaEngineEventPort* const portToIgnore) noexcept
305     {
306         if (data != nullptr)
307         {
308             for (uint32_t i=0; i < count; ++i)
309             {
310                 if (data[i].port != nullptr)
311                 {
312                     if (data[i].port != portToIgnore)
313                         delete data[i].port;
314                     data[i].port = nullptr;
315                 }
316             }
317 
318             delete[] data;
319             data = nullptr;
320         }
321 
322         count = 0;
323 
324         ctrl      = nullptr;
325         ctrlIndex = 0;
326     }
327 
initBuffersCarlaPluginLV2EventData328     void initBuffers() const noexcept
329     {
330         for (uint32_t i=0; i < count; ++i)
331         {
332             if (data[i].port != nullptr && (ctrl == nullptr || data[i].port != ctrl->port))
333                 data[i].port->initBuffer();
334         }
335     }
336 
337     CARLA_DECLARE_NON_COPY_STRUCT(CarlaPluginLV2EventData)
338 };
339 
340 // -------------------------------------------------------------------------------------------------------------------
341 
342 struct CarlaPluginLV2Options {
343     enum OptIndex {
344         MaxBlockLenth = 0,
345         MinBlockLenth,
346         NominalBlockLenth,
347         SequenceSize,
348         SampleRate,
349         TransientWinId,
350         BackgroundColor,
351         ForegroundColor,
352         ScaleFactor,
353         WindowTitle,
354         Null,
355         Count
356     };
357 
358     int maxBufferSize;
359     int minBufferSize;
360     int nominalBufferSize;
361     int sequenceSize;
362     float sampleRate;
363     int64_t transientWinId;
364     uint32_t bgColor;
365     uint32_t fgColor;
366     float uiScale;
367     const char* windowTitle;
368     LV2_Options_Option opts[Count];
369 
CarlaPluginLV2OptionsCarlaPluginLV2Options370     CarlaPluginLV2Options() noexcept
371         : maxBufferSize(0),
372           minBufferSize(0),
373           nominalBufferSize(0),
374           sequenceSize(MAX_DEFAULT_BUFFER_SIZE),
375           sampleRate(0.0),
376           transientWinId(0),
377           bgColor(0x000000ff),
378           fgColor(0xffffffff),
379           uiScale(1.0f),
380           windowTitle(nullptr)
381     {
382         LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]);
383         optMaxBlockLenth.context = LV2_OPTIONS_INSTANCE;
384         optMaxBlockLenth.subject = 0;
385         optMaxBlockLenth.key     = kUridBufMaxLength;
386         optMaxBlockLenth.size    = sizeof(int);
387         optMaxBlockLenth.type    = kUridAtomInt;
388         optMaxBlockLenth.value   = &maxBufferSize;
389 
390         LV2_Options_Option& optMinBlockLenth(opts[MinBlockLenth]);
391         optMinBlockLenth.context = LV2_OPTIONS_INSTANCE;
392         optMinBlockLenth.subject = 0;
393         optMinBlockLenth.key     = kUridBufMinLength;
394         optMinBlockLenth.size    = sizeof(int);
395         optMinBlockLenth.type    = kUridAtomInt;
396         optMinBlockLenth.value   = &minBufferSize;
397 
398         LV2_Options_Option& optNominalBlockLenth(opts[NominalBlockLenth]);
399         optNominalBlockLenth.context = LV2_OPTIONS_INSTANCE;
400         optNominalBlockLenth.subject = 0;
401         optNominalBlockLenth.key     = kUridBufNominalLength;
402         optNominalBlockLenth.size    = sizeof(int);
403         optNominalBlockLenth.type    = kUridAtomInt;
404         optNominalBlockLenth.value   = &nominalBufferSize;
405 
406         LV2_Options_Option& optSequenceSize(opts[SequenceSize]);
407         optSequenceSize.context = LV2_OPTIONS_INSTANCE;
408         optSequenceSize.subject = 0;
409         optSequenceSize.key     = kUridBufSequenceSize;
410         optSequenceSize.size    = sizeof(int);
411         optSequenceSize.type    = kUridAtomInt;
412         optSequenceSize.value   = &sequenceSize;
413 
414         LV2_Options_Option& optBackgroundColor(opts[BackgroundColor]);
415         optBackgroundColor.context = LV2_OPTIONS_INSTANCE;
416         optBackgroundColor.subject = 0;
417         optBackgroundColor.key     = kUridBackgroundColor;
418         optBackgroundColor.size    = sizeof(int32_t);
419         optBackgroundColor.type    = kUridAtomInt;
420         optBackgroundColor.value   = &bgColor;
421 
422         LV2_Options_Option& optForegroundColor(opts[ForegroundColor]);
423         optForegroundColor.context = LV2_OPTIONS_INSTANCE;
424         optForegroundColor.subject = 0;
425         optForegroundColor.key     = kUridForegroundColor;
426         optForegroundColor.size    = sizeof(int32_t);
427         optForegroundColor.type    = kUridAtomInt;
428         optForegroundColor.value   = &fgColor;
429 
430         LV2_Options_Option& optScaleFactor(opts[ScaleFactor]);
431         optScaleFactor.context = LV2_OPTIONS_INSTANCE;
432         optScaleFactor.subject = 0;
433         optScaleFactor.key     = kUridScaleFactor;
434         optScaleFactor.size    = sizeof(float);
435         optScaleFactor.type    = kUridAtomFloat;
436         optScaleFactor.value   = &uiScale;
437 
438         LV2_Options_Option& optSampleRate(opts[SampleRate]);
439         optSampleRate.context = LV2_OPTIONS_INSTANCE;
440         optSampleRate.subject = 0;
441         optSampleRate.key     = kUridParamSampleRate;
442         optSampleRate.size    = sizeof(float);
443         optSampleRate.type    = kUridAtomFloat;
444         optSampleRate.value   = &sampleRate;
445 
446         LV2_Options_Option& optTransientWinId(opts[TransientWinId]);
447         optTransientWinId.context = LV2_OPTIONS_INSTANCE;
448         optTransientWinId.subject = 0;
449         optTransientWinId.key     = kUridCarlaTransientWindowId;
450         optTransientWinId.size    = sizeof(int64_t);
451         optTransientWinId.type    = kUridAtomLong;
452         optTransientWinId.value   = &transientWinId;
453 
454         LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
455         optWindowTitle.context = LV2_OPTIONS_INSTANCE;
456         optWindowTitle.subject = 0;
457         optWindowTitle.key     = kUridWindowTitle;
458         optWindowTitle.size    = 0;
459         optWindowTitle.type    = kUridAtomString;
460         optWindowTitle.value   = nullptr;
461 
462         LV2_Options_Option& optNull(opts[Null]);
463         optNull.context = LV2_OPTIONS_INSTANCE;
464         optNull.subject = 0;
465         optNull.key     = kUridNull;
466         optNull.size    = 0;
467         optNull.type    = kUridNull;
468         optNull.value   = nullptr;
469     }
470 
~CarlaPluginLV2OptionsCarlaPluginLV2Options471     ~CarlaPluginLV2Options() noexcept
472     {
473         LV2_Options_Option& optWindowTitle(opts[WindowTitle]);
474 
475         optWindowTitle.size  = 0;
476         optWindowTitle.value = nullptr;
477 
478         if (windowTitle != nullptr)
479         {
480             std::free(const_cast<char*>(windowTitle));
481             windowTitle = nullptr;
482         }
483     }
484 
485     CARLA_DECLARE_NON_COPY_STRUCT(CarlaPluginLV2Options);
486 };
487 
488 // -------------------------------------------------------------------------------------------------------------------
489 
490 class CarlaPluginLV2;
491 
492 class CarlaPipeServerLV2 : public CarlaPipeServer
493 {
494 public:
495     enum UiState {
496         UiNone = 0,
497         UiHide,
498         UiShow,
499         UiCrashed
500     };
501 
CarlaPipeServerLV2(CarlaEngine * const engine,CarlaPluginLV2 * const plugin)502     CarlaPipeServerLV2(CarlaEngine* const engine, CarlaPluginLV2* const plugin)
503         : kEngine(engine),
504           kPlugin(plugin),
505           fFilename(),
506           fPluginURI(),
507           fUiURI(),
508           fUiState(UiNone) {}
509 
~CarlaPipeServerLV2()510     ~CarlaPipeServerLV2() noexcept override
511     {
512         CARLA_SAFE_ASSERT_INT(fUiState == UiNone, fUiState);
513     }
514 
getAndResetUiState()515     UiState getAndResetUiState() noexcept
516     {
517         const UiState uiState(fUiState);
518         fUiState = UiNone;
519         return uiState;
520     }
521 
setData(const char * const filename,const char * const pluginURI,const char * const uiURI)522     void setData(const char* const filename, const char* const pluginURI, const char* const uiURI) noexcept
523     {
524         fFilename  = filename;
525         fPluginURI = pluginURI;
526         fUiURI     = uiURI;
527     }
528 
startPipeServer(const int size)529     bool startPipeServer(const int size) noexcept
530     {
531         char sampleRateStr[32];
532         {
533             const CarlaScopedLocale csl;
534             std::snprintf(sampleRateStr, 31, "%.12g", kEngine->getSampleRate());
535         }
536         sampleRateStr[31] = '\0';
537 
538         const ScopedEngineEnvironmentLocker _seel(kEngine);
539         const CarlaScopedEnvVar _sev1("LV2_PATH", kEngine->getOptions().pathLV2);
540 #ifdef CARLA_OS_LINUX
541         const CarlaScopedEnvVar _sev2("LD_PRELOAD", nullptr);
542 #endif
543         carla_setenv("CARLA_SAMPLE_RATE", sampleRateStr);
544 
545         return CarlaPipeServer::startPipeServer(fFilename, fPluginURI, fUiURI, size);
546     }
547 
writeUiTitleMessage(const char * const title) const548     void writeUiTitleMessage(const char* const title) const noexcept
549     {
550         CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
551 
552         const CarlaMutexLocker cml(getPipeLock());
553 
554         if (! _writeMsgBuffer("uiTitle\n", 8))
555             return;
556         if (! writeAndFixMessage(title))
557             return;
558 
559         flushMessages();
560     }
561 
562 protected:
563     // returns true if msg was handled
564     bool msgReceived(const char* const msg) noexcept override;
565 
566 private:
567     CarlaEngine*    const kEngine;
568     CarlaPluginLV2* const kPlugin;
569 
570     CarlaString fFilename;
571     CarlaString fPluginURI;
572     CarlaString fUiURI;
573     UiState     fUiState;
574 
575     CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServerLV2)
576 };
577 
578 // -------------------------------------------------------------------------------------------------------------------
579 
initAtomForge(LV2_Atom_Forge & atomForge)580 static void initAtomForge(LV2_Atom_Forge& atomForge) noexcept
581 {
582     carla_zeroStruct(atomForge);
583 
584     atomForge.Bool     = kUridAtomBool;
585     atomForge.Chunk    = kUridAtomChunk;
586     atomForge.Double   = kUridAtomDouble;
587     atomForge.Float    = kUridAtomFloat;
588     atomForge.Int      = kUridAtomInt;
589     atomForge.Literal  = kUridAtomLiteral;
590     atomForge.Long     = kUridAtomLong;
591     atomForge.Object   = kUridAtomObject;
592     atomForge.Path     = kUridAtomPath;
593     atomForge.Property = kUridAtomProperty;
594     atomForge.Sequence = kUridAtomSequence;
595     atomForge.String   = kUridAtomString;
596     atomForge.Tuple    = kUridAtomTuple;
597     atomForge.URI      = kUridAtomURI;
598     atomForge.URID     = kUridAtomURID;
599     atomForge.Vector   = kUridAtomVector;
600 
601 #if defined(__clang__)
602 # pragma clang diagnostic push
603 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
604 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
605 # pragma GCC diagnostic push
606 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
607 #endif
608     atomForge.Blank    = kUridAtomBlank;
609     atomForge.Resource = kUridAtomResource;
610 #if defined(__clang__)
611 # pragma clang diagnostic pop
612 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
613 # pragma GCC diagnostic pop
614 #endif
615 }
616 
617 // -------------------------------------------------------------------------------------------------------------------
618 
619 class CarlaPluginLV2 : public CarlaPlugin,
620                        private CarlaPluginUI::Callback
621 {
622 public:
CarlaPluginLV2(CarlaEngine * const engine,const uint id)623     CarlaPluginLV2(CarlaEngine* const engine, const uint id)
624         : CarlaPlugin(engine, id),
625           fHandle(nullptr),
626           fHandle2(nullptr),
627           fDescriptor(nullptr),
628           fRdfDescriptor(nullptr),
629           fAudioInBuffers(nullptr),
630           fAudioOutBuffers(nullptr),
631           fCvInBuffers(nullptr),
632           fCvOutBuffers(nullptr),
633           fParamBuffers(nullptr),
634           fHasLoadDefaultState(false),
635           fHasThreadSafeRestore(false),
636           fNeedsFixedBuffers(false),
637           fNeedsUiClose(false),
638           fInlineDisplayNeedsRedraw(false),
639           fInlineDisplayLastRedrawTime(0),
640           fLatencyIndex(-1),
641           fStrictBounds(-1),
642           fAtomBufferEvIn(),
643           fAtomBufferUiOut(),
644           fAtomBufferWorkerIn(),
645           fAtomBufferWorkerResp(),
646           fAtomBufferUiOutTmpData(nullptr),
647           fAtomBufferWorkerInTmpData(nullptr),
648           fEventsIn(),
649           fEventsOut(),
650           fLv2Options(),
651           fPipeServer(engine, this),
652           fCustomURIDs(kUridCount, std::string("urn:null")),
653           fFirstActive(true),
654           fLastStateChunk(nullptr),
655           fLastTimeInfo(),
656           fFilePathURI(),
657           fExt(),
658           fUI()
659     {
660         carla_debug("CarlaPluginLV2::CarlaPluginLV2(%p, %i)", engine, id);
661         CARLA_SAFE_ASSERT(fCustomURIDs.size() == kUridCount);
662 
663         carla_zeroPointers(fFeatures, kFeatureCountAll+1);
664         carla_zeroPointers(fStateFeatures, kStateFeatureCountAll+1);
665     }
666 
~CarlaPluginLV2()667     ~CarlaPluginLV2() override
668     {
669         carla_debug("CarlaPluginLV2::~CarlaPluginLV2()");
670 
671         fInlineDisplayNeedsRedraw = false;
672 
673         // close UI
674         if (fUI.type != UI::TYPE_NULL)
675         {
676             showCustomUI(false);
677 
678             if (fUI.type == UI::TYPE_BRIDGE)
679             {
680                 fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
681             }
682             else
683             {
684                 if (fFeatures[kFeatureIdUiDataAccess] != nullptr && fFeatures[kFeatureIdUiDataAccess]->data != nullptr)
685                     delete (LV2_Extension_Data_Feature*)fFeatures[kFeatureIdUiDataAccess]->data;
686 
687                 if (fFeatures[kFeatureIdUiPortMap] != nullptr && fFeatures[kFeatureIdUiPortMap]->data != nullptr)
688                     delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data;
689 
690                 if (fFeatures[kFeatureIdUiRequestValue] != nullptr && fFeatures[kFeatureIdUiRequestValue]->data != nullptr)
691                     delete (LV2UI_Request_Value*)fFeatures[kFeatureIdUiRequestValue]->data;
692 
693                 if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr)
694                     delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data;
695 
696                 if (fFeatures[kFeatureIdUiTouch] != nullptr && fFeatures[kFeatureIdUiTouch]->data != nullptr)
697                     delete (LV2UI_Touch*)fFeatures[kFeatureIdUiTouch]->data;
698 
699                 if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
700                     delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data;
701 
702                 fUI.descriptor = nullptr;
703                 pData->uiLibClose();
704             }
705 
706 #ifndef LV2_UIS_ONLY_BRIDGES
707             if (fUI.window != nullptr)
708             {
709                 delete fUI.window;
710                 fUI.window = nullptr;
711             }
712 #endif
713 
714             fUI.rdfDescriptor = nullptr;
715         }
716 
717         pData->singleMutex.lock();
718         pData->masterMutex.lock();
719 
720         if (pData->client != nullptr && pData->client->isActive())
721             pData->client->deactivate(true);
722 
723         if (pData->active)
724         {
725             deactivate();
726             pData->active = false;
727         }
728 
729         if (fExt.state != nullptr)
730         {
731             const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
732 
733             if (tmpDir.exists())
734                 tmpDir.deleteRecursively();
735         }
736 
737         if (fDescriptor != nullptr)
738         {
739             if (fDescriptor->cleanup != nullptr)
740             {
741                 if (fHandle != nullptr)
742                     fDescriptor->cleanup(fHandle);
743                 if (fHandle2 != nullptr)
744                     fDescriptor->cleanup(fHandle2);
745             }
746 
747             fHandle  = nullptr;
748             fHandle2 = nullptr;
749             fDescriptor = nullptr;
750         }
751 
752         if (fRdfDescriptor != nullptr)
753         {
754             delete fRdfDescriptor;
755             fRdfDescriptor = nullptr;
756         }
757 
758         if (fFeatures[kFeatureIdEvent] != nullptr && fFeatures[kFeatureIdEvent]->data != nullptr)
759             delete (LV2_Event_Feature*)fFeatures[kFeatureIdEvent]->data;
760 
761         if (fFeatures[kFeatureIdLogs] != nullptr && fFeatures[kFeatureIdLogs]->data != nullptr)
762             delete (LV2_Log_Log*)fFeatures[kFeatureIdLogs]->data;
763 
764         if (fFeatures[kFeatureIdStateFreePath] != nullptr && fFeatures[kFeatureIdStateFreePath]->data != nullptr)
765             delete (LV2_State_Free_Path*)fFeatures[kFeatureIdStateFreePath]->data;
766 
767         if (fFeatures[kFeatureIdStateMakePath] != nullptr && fFeatures[kFeatureIdStateMakePath]->data != nullptr)
768             delete (LV2_State_Make_Path*)fFeatures[kFeatureIdStateMakePath]->data;
769 
770         if (fFeatures[kFeatureIdStateMapPath] != nullptr && fFeatures[kFeatureIdStateMapPath]->data != nullptr)
771             delete (LV2_State_Map_Path*)fFeatures[kFeatureIdStateMapPath]->data;
772 
773         if (fFeatures[kFeatureIdPrograms] != nullptr && fFeatures[kFeatureIdPrograms]->data != nullptr)
774             delete (LV2_Programs_Host*)fFeatures[kFeatureIdPrograms]->data;
775 
776         if (fFeatures[kFeatureIdResizePort] != nullptr && fFeatures[kFeatureIdResizePort]->data != nullptr)
777             delete (LV2_Resize_Port_Resize*)fFeatures[kFeatureIdResizePort]->data;
778 
779         if (fFeatures[kFeatureIdRtMemPool] != nullptr && fFeatures[kFeatureIdRtMemPool]->data != nullptr)
780             delete (LV2_RtMemPool_Pool*)fFeatures[kFeatureIdRtMemPool]->data;
781 
782         if (fFeatures[kFeatureIdRtMemPoolOld] != nullptr && fFeatures[kFeatureIdRtMemPoolOld]->data != nullptr)
783             delete (LV2_RtMemPool_Pool_Deprecated*)fFeatures[kFeatureIdRtMemPoolOld]->data;
784 
785         if (fFeatures[kFeatureIdUriMap] != nullptr && fFeatures[kFeatureIdUriMap]->data != nullptr)
786             delete (LV2_URI_Map_Feature*)fFeatures[kFeatureIdUriMap]->data;
787 
788         if (fFeatures[kFeatureIdUridMap] != nullptr && fFeatures[kFeatureIdUridMap]->data != nullptr)
789             delete (LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
790 
791         if (fFeatures[kFeatureIdUridUnmap] != nullptr && fFeatures[kFeatureIdUridUnmap]->data != nullptr)
792             delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data;
793 
794         if (fFeatures[kFeatureIdWorker] != nullptr && fFeatures[kFeatureIdWorker]->data != nullptr)
795             delete (LV2_Worker_Schedule*)fFeatures[kFeatureIdWorker]->data;
796 
797         if (fFeatures[kFeatureIdInlineDisplay] != nullptr && fFeatures[kFeatureIdInlineDisplay]->data != nullptr)
798             delete (LV2_Inline_Display*)fFeatures[kFeatureIdInlineDisplay]->data;
799 
800         if (fFeatures[kFeatureIdMidnam] != nullptr && fFeatures[kFeatureIdMidnam]->data != nullptr)
801             delete (LV2_Midnam*)fFeatures[kFeatureIdMidnam]->data;
802 
803         for (uint32_t i=0; i < kFeatureCountAll; ++i)
804         {
805             if (fFeatures[i] != nullptr)
806             {
807                 delete fFeatures[i];
808                 fFeatures[i] = nullptr;
809             }
810         }
811 
812         if (fStateFeatures[kStateFeatureIdMakePath] != nullptr && fStateFeatures[kStateFeatureIdMakePath]->data != nullptr)
813             delete (LV2_State_Make_Path*)fStateFeatures[kStateFeatureIdMakePath]->data;
814 
815         if (fStateFeatures[kStateFeatureIdMapPath] != nullptr && fStateFeatures[kStateFeatureIdMapPath]->data != nullptr)
816             delete (LV2_State_Map_Path*)fStateFeatures[kStateFeatureIdMapPath]->data;
817 
818         for (uint32_t i=0; i < kStateFeatureCountAll; ++i)
819         {
820             if (fStateFeatures[i] != nullptr)
821             {
822                 delete fStateFeatures[i];
823                 fStateFeatures[i] = nullptr;
824             }
825         }
826 
827         if (fLastStateChunk != nullptr)
828         {
829             std::free(fLastStateChunk);
830             fLastStateChunk = nullptr;
831         }
832 
833         if (fAtomBufferUiOutTmpData != nullptr)
834         {
835             delete[] fAtomBufferUiOutTmpData;
836             fAtomBufferUiOutTmpData = nullptr;
837         }
838 
839         if (fAtomBufferWorkerInTmpData != nullptr)
840         {
841             delete[] fAtomBufferWorkerInTmpData;
842             fAtomBufferWorkerInTmpData = nullptr;
843         }
844 
845         clearBuffers();
846     }
847 
848     // -------------------------------------------------------------------
849     // Information (base)
850 
getType() const851     PluginType getType() const noexcept override
852     {
853         return PLUGIN_LV2;
854     }
855 
getCategory() const856     PluginCategory getCategory() const noexcept override
857     {
858         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, CarlaPlugin::getCategory());
859 
860         const LV2_Property cat1(fRdfDescriptor->Type[0]);
861         const LV2_Property cat2(fRdfDescriptor->Type[1]);
862 
863         if (LV2_IS_DELAY(cat1, cat2))
864             return PLUGIN_CATEGORY_DELAY;
865         if (LV2_IS_DISTORTION(cat1, cat2))
866             return PLUGIN_CATEGORY_OTHER;
867         if (LV2_IS_DYNAMICS(cat1, cat2))
868             return PLUGIN_CATEGORY_DYNAMICS;
869         if (LV2_IS_EQ(cat1, cat2))
870             return PLUGIN_CATEGORY_EQ;
871         if (LV2_IS_FILTER(cat1, cat2))
872             return PLUGIN_CATEGORY_FILTER;
873         if (LV2_IS_GENERATOR(cat1, cat2))
874             return PLUGIN_CATEGORY_SYNTH;
875         if (LV2_IS_MODULATOR(cat1, cat2))
876             return PLUGIN_CATEGORY_MODULATOR;
877         if (LV2_IS_REVERB(cat1, cat2))
878             return PLUGIN_CATEGORY_DELAY;
879         if (LV2_IS_SIMULATOR(cat1, cat2))
880             return PLUGIN_CATEGORY_OTHER;
881         if (LV2_IS_SPATIAL(cat1, cat2))
882             return PLUGIN_CATEGORY_OTHER;
883         if (LV2_IS_SPECTRAL(cat1, cat2))
884             return PLUGIN_CATEGORY_UTILITY;
885         if (LV2_IS_UTILITY(cat1, cat2))
886             return PLUGIN_CATEGORY_UTILITY;
887 
888         return CarlaPlugin::getCategory();
889     }
890 
getLatencyInFrames() const891     uint32_t getLatencyInFrames() const noexcept override
892     {
893         if (fLatencyIndex < 0 || fParamBuffers == nullptr)
894             return 0;
895 
896         const float latency(fParamBuffers[fLatencyIndex]);
897         CARLA_SAFE_ASSERT_RETURN(latency >= 0.0f, 0);
898 
899         return static_cast<uint32_t>(latency);
900     }
901 
902     // -------------------------------------------------------------------
903     // Information (count)
904 
getMidiInCount() const905     uint32_t getMidiInCount() const noexcept override
906     {
907         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
908 
909         uint32_t count = 0;
910 
911         for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
912         {
913             const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
914 
915             if (LV2_IS_PORT_INPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
916                 ++count;
917         }
918 
919         return count;
920     }
921 
getMidiOutCount() const922     uint32_t getMidiOutCount() const noexcept override
923     {
924         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
925 
926         uint32_t count = 0;
927 
928         for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
929         {
930             const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
931 
932             if (LV2_IS_PORT_OUTPUT(portTypes) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes))
933                 ++count;
934         }
935 
936         return count;
937     }
938 
getParameterScalePointCount(const uint32_t parameterId) const939     uint32_t getParameterScalePointCount(const uint32_t parameterId) const noexcept override
940     {
941         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0);
942         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0);
943 
944         const int32_t rindex(pData->param.data[parameterId].rindex);
945 
946         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
947         {
948             const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
949             return port->ScalePointCount;
950         }
951 
952         return 0;
953     }
954 
955     // -------------------------------------------------------------------
956     // Information (current data)
957 
958     // nothing
959 
960     // -------------------------------------------------------------------
961     // Information (per-plugin data)
962 
getOptionsAvailable() const963     uint getOptionsAvailable() const noexcept override
964     {
965         uint options = 0x0;
966 
967         // can't disable fixed buffers if using latency or MIDI output
968         if (fLatencyIndex == -1 && getMidiOutCount() == 0 && ! fNeedsFixedBuffers)
969             options |= PLUGIN_OPTION_FIXED_BUFFERS;
970 
971         // can't disable forced stereo if enabled in the engine
972         if (pData->engine->getOptions().forceStereo)
973             pass();
974         // if there are event outputs, we can't force stereo
975         else if (fEventsOut.count != 0)
976             pass();
977         // if inputs or outputs are just 1, then yes we can force stereo
978         else if ((pData->audioIn.count == 1 || pData->audioOut.count == 1) || fHandle2 != nullptr)
979             options |= PLUGIN_OPTION_FORCE_STEREO;
980 
981         if (fExt.programs != nullptr)
982             options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
983 
984         if (getMidiInCount() != 0)
985         {
986             options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
987             options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
988             options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
989             options |= PLUGIN_OPTION_SEND_PITCHBEND;
990             options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
991             options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
992             options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
993         }
994 
995         return options;
996     }
997 
getParameterValue(const uint32_t parameterId) const998     float getParameterValue(const uint32_t parameterId) const noexcept override
999     {
1000         CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr, 0.0f);
1001         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
1002 
1003         if (pData->param.data[parameterId].type == PARAMETER_INPUT)
1004         {
1005             if (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS)
1006                 pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
1007         }
1008         else
1009         {
1010             if (fStrictBounds >= 0 && (pData->param.data[parameterId].hints & PARAMETER_IS_STRICT_BOUNDS) == 0)
1011                 pData->param.ranges[parameterId].fixValue(fParamBuffers[parameterId]);
1012         }
1013 
1014         return fParamBuffers[parameterId];
1015     }
1016 
getParameterScalePointValue(const uint32_t parameterId,const uint32_t scalePointId) const1017     float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept override
1018     {
1019         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0.0f);
1020         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
1021 
1022         const int32_t rindex(pData->param.data[parameterId].rindex);
1023 
1024         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1025         {
1026             const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
1027             CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, 0.0f);
1028 
1029             const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
1030             return portScalePoint->Value;
1031         }
1032 
1033         return 0.0f;
1034     }
1035 
getLabel(char * const strBuf) const1036     bool getLabel(char* const strBuf) const noexcept override
1037     {
1038         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1039         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor->URI != nullptr, false);
1040 
1041         std::strncpy(strBuf, fRdfDescriptor->URI, STR_MAX);
1042         return true;
1043     }
1044 
getMaker(char * const strBuf) const1045     bool getMaker(char* const strBuf) const noexcept override
1046     {
1047         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1048 
1049         if (fRdfDescriptor->Author != nullptr)
1050         {
1051             std::strncpy(strBuf, fRdfDescriptor->Author, STR_MAX);
1052             return true;
1053         }
1054 
1055         return false;
1056     }
1057 
getCopyright(char * const strBuf) const1058     bool getCopyright(char* const strBuf) const noexcept override
1059     {
1060         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1061 
1062         if (fRdfDescriptor->License != nullptr)
1063         {
1064             std::strncpy(strBuf, fRdfDescriptor->License, STR_MAX);
1065             return true;
1066         }
1067 
1068         return false;
1069     }
1070 
getRealName(char * const strBuf) const1071     bool getRealName(char* const strBuf) const noexcept override
1072     {
1073         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1074 
1075         if (fRdfDescriptor->Name != nullptr)
1076         {
1077             std::strncpy(strBuf, fRdfDescriptor->Name, STR_MAX);
1078             return true;
1079         }
1080 
1081         return false;
1082     }
1083 
getParameterName(const uint32_t parameterId,char * const strBuf) const1084     bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
1085     {
1086         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1087         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1088 
1089         int32_t rindex = pData->param.data[parameterId].rindex;
1090         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1091 
1092         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1093         {
1094             std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Name, STR_MAX);
1095             return true;
1096         }
1097 
1098         rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1099 
1100         if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1101         {
1102             std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].Label, STR_MAX);
1103             return true;
1104         }
1105 
1106         return CarlaPlugin::getParameterName(parameterId, strBuf);
1107     }
1108 
getParameterSymbol(const uint32_t parameterId,char * const strBuf) const1109     bool getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept override
1110     {
1111         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1112         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1113 
1114         int32_t rindex = pData->param.data[parameterId].rindex;
1115         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1116 
1117         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1118         {
1119             std::strncpy(strBuf, fRdfDescriptor->Ports[rindex].Symbol, STR_MAX);
1120             return true;
1121         }
1122 
1123         rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1124 
1125         if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1126         {
1127             std::strncpy(strBuf, fRdfDescriptor->Parameters[rindex].URI, STR_MAX);
1128             return true;
1129         }
1130 
1131         return CarlaPlugin::getParameterSymbol(parameterId, strBuf);
1132     }
1133 
getParameterUnit(const uint32_t parameterId,char * const strBuf) const1134     bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
1135     {
1136         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1137         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1138 
1139         LV2_RDF_PortUnit* portUnit = nullptr;
1140 
1141         int32_t rindex = pData->param.data[parameterId].rindex;
1142         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1143 
1144         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1145         {
1146             portUnit = &fRdfDescriptor->Ports[rindex].Unit;
1147         }
1148         else
1149         {
1150             rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1151 
1152             if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1153             {
1154                 portUnit = &fRdfDescriptor->Parameters[rindex].Unit;
1155             }
1156         }
1157 
1158         if (portUnit != nullptr)
1159         {
1160             if (LV2_HAVE_PORT_UNIT_SYMBOL(portUnit->Hints) && portUnit->Symbol != nullptr)
1161             {
1162                 std::strncpy(strBuf, portUnit->Symbol, STR_MAX);
1163                 return true;
1164             }
1165 
1166             if (LV2_HAVE_PORT_UNIT_UNIT(portUnit->Hints))
1167             {
1168                 switch (portUnit->Unit)
1169                 {
1170                 case LV2_PORT_UNIT_BAR:
1171                     std::strncpy(strBuf, "bars", STR_MAX);
1172                     return true;
1173                 case LV2_PORT_UNIT_BEAT:
1174                     std::strncpy(strBuf, "beats", STR_MAX);
1175                     return true;
1176                 case LV2_PORT_UNIT_BPM:
1177                     std::strncpy(strBuf, "BPM", STR_MAX);
1178                     return true;
1179                 case LV2_PORT_UNIT_CENT:
1180                     std::strncpy(strBuf, "ct", STR_MAX);
1181                     return true;
1182                 case LV2_PORT_UNIT_CM:
1183                     std::strncpy(strBuf, "cm", STR_MAX);
1184                     return true;
1185                 case LV2_PORT_UNIT_COEF:
1186                     std::strncpy(strBuf, "(coef)", STR_MAX);
1187                     return true;
1188                 case LV2_PORT_UNIT_DB:
1189                     std::strncpy(strBuf, "dB", STR_MAX);
1190                     return true;
1191                 case LV2_PORT_UNIT_DEGREE:
1192                     std::strncpy(strBuf, "deg", STR_MAX);
1193                     return true;
1194                 case LV2_PORT_UNIT_FRAME:
1195                     std::strncpy(strBuf, "frames", STR_MAX);
1196                     return true;
1197                 case LV2_PORT_UNIT_HZ:
1198                     std::strncpy(strBuf, "Hz", STR_MAX);
1199                     return true;
1200                 case LV2_PORT_UNIT_INCH:
1201                     std::strncpy(strBuf, "in", STR_MAX);
1202                     return true;
1203                 case LV2_PORT_UNIT_KHZ:
1204                     std::strncpy(strBuf, "kHz", STR_MAX);
1205                     return true;
1206                 case LV2_PORT_UNIT_KM:
1207                     std::strncpy(strBuf, "km", STR_MAX);
1208                     return true;
1209                 case LV2_PORT_UNIT_M:
1210                     std::strncpy(strBuf, "m", STR_MAX);
1211                     return true;
1212                 case LV2_PORT_UNIT_MHZ:
1213                     std::strncpy(strBuf, "MHz", STR_MAX);
1214                     return true;
1215                 case LV2_PORT_UNIT_MIDINOTE:
1216                     std::strncpy(strBuf, "note", STR_MAX);
1217                     return true;
1218                 case LV2_PORT_UNIT_MILE:
1219                     std::strncpy(strBuf, "mi", STR_MAX);
1220                     return true;
1221                 case LV2_PORT_UNIT_MIN:
1222                     std::strncpy(strBuf, "min", STR_MAX);
1223                     return true;
1224                 case LV2_PORT_UNIT_MM:
1225                     std::strncpy(strBuf, "mm", STR_MAX);
1226                     return true;
1227                 case LV2_PORT_UNIT_MS:
1228                     std::strncpy(strBuf, "ms", STR_MAX);
1229                     return true;
1230                 case LV2_PORT_UNIT_OCT:
1231                     std::strncpy(strBuf, "oct", STR_MAX);
1232                     return true;
1233                 case LV2_PORT_UNIT_PC:
1234                     std::strncpy(strBuf, "%", STR_MAX);
1235                     return true;
1236                 case LV2_PORT_UNIT_S:
1237                     std::strncpy(strBuf, "s", STR_MAX);
1238                     return true;
1239                 case LV2_PORT_UNIT_SEMITONE:
1240                     std::strncpy(strBuf, "semi", STR_MAX);
1241                     return true;
1242                 }
1243             }
1244         }
1245 
1246         return CarlaPlugin::getParameterUnit(parameterId, strBuf);
1247     }
1248 
getParameterComment(const uint32_t parameterId,char * const strBuf) const1249     bool getParameterComment(const uint32_t parameterId, char* const strBuf) const noexcept override
1250     {
1251         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1252         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1253 
1254         int32_t rindex = pData->param.data[parameterId].rindex;
1255         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1256 
1257         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1258         {
1259             if (const char* const comment = fRdfDescriptor->Ports[rindex].Comment)
1260             {
1261                 std::strncpy(strBuf, comment, STR_MAX);
1262                 return true;
1263             }
1264             return false;
1265         }
1266 
1267         rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1268 
1269         if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1270         {
1271             if (const char* const comment = fRdfDescriptor->Parameters[rindex].Comment)
1272             {
1273                 std::strncpy(strBuf, comment, STR_MAX);
1274                 return true;
1275             }
1276             return false;
1277         }
1278 
1279         return CarlaPlugin::getParameterComment(parameterId, strBuf);
1280     }
1281 
getParameterGroupName(const uint32_t parameterId,char * const strBuf) const1282     bool getParameterGroupName(const uint32_t parameterId, char* const strBuf) const noexcept override
1283     {
1284         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1285         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1286 
1287         int32_t rindex = pData->param.data[parameterId].rindex;
1288         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1289 
1290         const char* uri = nullptr;
1291 
1292         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1293         {
1294             uri = fRdfDescriptor->Ports[rindex].GroupURI;
1295         }
1296         else
1297         {
1298             rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1299 
1300             if (rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount))
1301                 uri = fRdfDescriptor->Parameters[rindex].GroupURI;
1302         }
1303 
1304         if (uri == nullptr)
1305             return false;
1306 
1307         for (uint32_t i=0; i<fRdfDescriptor->PortGroupCount; ++i)
1308         {
1309             if (std::strcmp(fRdfDescriptor->PortGroups[i].URI, uri) == 0)
1310             {
1311                 const char* const name   = fRdfDescriptor->PortGroups[i].Name;
1312                 const char* const symbol = fRdfDescriptor->PortGroups[i].Symbol;
1313 
1314                 if (name != nullptr && symbol != nullptr)
1315                 {
1316                     std::snprintf(strBuf, STR_MAX, "%s:%s", symbol, name);
1317                     return true;
1318                 }
1319                 return false;
1320             }
1321         }
1322 
1323         return false;
1324     }
1325 
getParameterScalePointLabel(const uint32_t parameterId,const uint32_t scalePointId,char * const strBuf) const1326     bool getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept override
1327     {
1328         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
1329         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
1330 
1331         const int32_t rindex(pData->param.data[parameterId].rindex);
1332         CARLA_SAFE_ASSERT_RETURN(rindex >= 0, false);
1333 
1334         if (rindex < static_cast<int32_t>(fRdfDescriptor->PortCount))
1335         {
1336             const LV2_RDF_Port* const port(&fRdfDescriptor->Ports[rindex]);
1337             CARLA_SAFE_ASSERT_RETURN(scalePointId < port->ScalePointCount, false);
1338 
1339             const LV2_RDF_PortScalePoint* const portScalePoint(&port->ScalePoints[scalePointId]);
1340 
1341             if (portScalePoint->Label != nullptr)
1342             {
1343                 std::strncpy(strBuf, portScalePoint->Label, STR_MAX);
1344                 return true;
1345             }
1346         }
1347 
1348         return CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
1349     }
1350 
1351     // -------------------------------------------------------------------
1352     // Set data (state)
1353 
prepareForSave(const bool temporary)1354     void prepareForSave(const bool temporary) override
1355     {
1356         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1357 
1358         if (fExt.state != nullptr && fExt.state->save != nullptr)
1359         {
1360             // move temporary stuff to main state dir on full save
1361             if (! temporary)
1362             {
1363                 const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
1364 
1365                 if (tmpDir.exists())
1366                 {
1367                     const File stateDir(handleStateMapToAbsolutePath(true, false, false, "."));
1368 
1369                     if (stateDir.isNotNull())
1370                         tmpDir.moveFileTo(stateDir);
1371                 }
1372             }
1373 
1374             fExt.state->save(fHandle, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
1375 
1376             if (fHandle2 != nullptr)
1377                 fExt.state->save(fHandle2, carla_lv2_state_store, this, LV2_STATE_IS_POD, fStateFeatures);
1378         }
1379     }
1380 
1381     // -------------------------------------------------------------------
1382     // Set data (internal stuff)
1383 
setName(const char * const newName)1384     void setName(const char* const newName) override
1385     {
1386         const File tmpDir1(handleStateMapToAbsolutePath(false, false, true, "."));
1387 
1388         CarlaPlugin::setName(newName);
1389 
1390         if (tmpDir1.exists())
1391         {
1392             const File tmpDir2(handleStateMapToAbsolutePath(false, false, true, "."));
1393 
1394             carla_stdout("dir1 %s, dir2 %s",
1395                          tmpDir1.getFullPathName().toRawUTF8(),
1396                          tmpDir2.getFullPathName().toRawUTF8());
1397 
1398             if (tmpDir2.isNotNull())
1399             {
1400                 if (tmpDir2.exists())
1401                     tmpDir2.deleteRecursively();
1402 
1403                 tmpDir1.moveFileTo(tmpDir2);
1404             }
1405         }
1406 
1407         if (fLv2Options.windowTitle != nullptr && pData->uiTitle.isEmpty())
1408             setWindowTitle(nullptr);
1409     }
1410 
setWindowTitle(const char * const title)1411     void setWindowTitle(const char* const title) noexcept
1412     {
1413         CarlaString uiTitle;
1414 
1415         if (title != nullptr)
1416         {
1417             uiTitle = title;
1418         }
1419         else
1420         {
1421             uiTitle  = pData->name;
1422             uiTitle += " (GUI)";
1423         }
1424 
1425         std::free(const_cast<char*>(fLv2Options.windowTitle));
1426         fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
1427 
1428         fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size  = (uint32_t)std::strlen(fLv2Options.windowTitle);
1429         fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
1430 
1431         if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr)
1432             ((LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data)->plugin_human_id = fLv2Options.windowTitle;
1433 
1434         if (fPipeServer.isPipeRunning())
1435             fPipeServer.writeUiTitleMessage(fLv2Options.windowTitle);
1436 
1437 #ifndef LV2_UIS_ONLY_BRIDGES
1438         if (fUI.window != nullptr)
1439         {
1440             try {
1441                 fUI.window->setTitle(fLv2Options.windowTitle);
1442             } CARLA_SAFE_EXCEPTION("set custom title");
1443         }
1444 #endif
1445     }
1446 
1447     // -------------------------------------------------------------------
1448     // Set data (plugin-specific stuff)
1449 
setParamterValueCommon(const uint32_t parameterId,const float value)1450     float setParamterValueCommon(const uint32_t parameterId, const float value) noexcept
1451     {
1452         const float fixedValue(pData->param.getFixedValue(parameterId, value));
1453         fParamBuffers[parameterId] = fixedValue;
1454 
1455         if (pData->param.data[parameterId].rindex >= static_cast<int32_t>(fRdfDescriptor->PortCount))
1456         {
1457             const uint32_t rparamId = static_cast<uint32_t>(pData->param.data[parameterId].rindex) - fRdfDescriptor->PortCount;
1458             CARLA_SAFE_ASSERT_UINT2_RETURN(rparamId < fRdfDescriptor->ParameterCount,
1459                                            rparamId, fRdfDescriptor->PortCount, fixedValue);
1460 
1461             uint8_t atomBuf[256];
1462             LV2_Atom_Forge atomForge;
1463             initAtomForge(atomForge);
1464             lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
1465 
1466             LV2_Atom_Forge_Frame forgeFrame;
1467             lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
1468 
1469             lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
1470             lv2_atom_forge_bool(&atomForge, true);
1471 
1472             lv2_atom_forge_key(&atomForge, kUridPatchProperty);
1473             lv2_atom_forge_urid(&atomForge, getCustomURID(fRdfDescriptor->Parameters[rparamId].URI));
1474 
1475             lv2_atom_forge_key(&atomForge, kUridPatchValue);
1476 
1477             switch (fRdfDescriptor->Parameters[rparamId].Type)
1478             {
1479             case LV2_PARAMETER_TYPE_BOOL:
1480                 lv2_atom_forge_bool(&atomForge, fixedValue > 0.5f);
1481                 break;
1482             case LV2_PARAMETER_TYPE_INT:
1483                 lv2_atom_forge_int(&atomForge, static_cast<int32_t>(fixedValue + 0.5f));
1484                 break;
1485             case LV2_PARAMETER_TYPE_LONG:
1486                 lv2_atom_forge_long(&atomForge, static_cast<int64_t>(fixedValue + 0.5f));
1487                 break;
1488             case LV2_PARAMETER_TYPE_FLOAT:
1489                 lv2_atom_forge_float(&atomForge, fixedValue);
1490                 break;
1491             case LV2_PARAMETER_TYPE_DOUBLE:
1492                 lv2_atom_forge_double(&atomForge, fixedValue);
1493                 break;
1494             default:
1495                 carla_stderr2("setParameterValue called for invalid parameter, expect issues!");
1496                 break;
1497             }
1498 
1499             lv2_atom_forge_pop(&atomForge, &forgeFrame);
1500 
1501             LV2_Atom* const atom((LV2_Atom*)atomBuf);
1502             CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
1503 
1504             fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
1505         }
1506 
1507         return fixedValue;
1508     }
1509 
setParameterValue(const uint32_t parameterId,const float value,const bool sendGui,const bool sendOsc,const bool sendCallback)1510     void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
1511     {
1512         CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
1513         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
1514 
1515         const float fixedValue = setParamterValueCommon(parameterId, value);
1516 
1517         CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
1518     }
1519 
setParameterValueRT(const uint32_t parameterId,const float value,const bool sendCallbackLater)1520     void setParameterValueRT(const uint32_t parameterId, const float value, const bool sendCallbackLater) noexcept override
1521     {
1522         CARLA_SAFE_ASSERT_RETURN(fParamBuffers != nullptr,);
1523         CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
1524 
1525         const float fixedValue = setParamterValueCommon(parameterId, value);
1526 
1527         CarlaPlugin::setParameterValueRT(parameterId, fixedValue, sendCallbackLater);
1528     }
1529 
setCustomData(const char * const type,const char * const key,const char * const value,const bool sendGui)1530     void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
1531     {
1532         CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
1533         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1534         CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
1535         CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
1536         CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
1537         carla_debug("CarlaPluginLV2::setCustomData(%s, %s, %s, %s)", type, key, value, bool2str(sendGui));
1538 
1539         if (std::strcmp(type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
1540             return CarlaPlugin::setCustomData(type, key, value, sendGui);
1541 
1542         // See if this key is from a parameter exposed by carla, apply value if yes
1543         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
1544         {
1545             const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
1546 
1547             if (std::strcmp(rdfParam.URI, key) == 0)
1548             {
1549                 uint32_t parameterId = UINT32_MAX;
1550                 const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
1551 
1552                 switch (rdfParam.Type)
1553                 {
1554                 case LV2_PARAMETER_TYPE_BOOL:
1555                 case LV2_PARAMETER_TYPE_INT:
1556                 // case LV2_PARAMETER_TYPE_LONG:
1557                 case LV2_PARAMETER_TYPE_FLOAT:
1558                 case LV2_PARAMETER_TYPE_DOUBLE:
1559                     for (uint32_t j=0; j < pData->param.count; ++j)
1560                     {
1561                         if (pData->param.data[j].rindex == rindex)
1562                         {
1563                             parameterId = j;
1564                             break;
1565                         }
1566                     }
1567                     break;
1568                 }
1569 
1570                 if (parameterId == UINT32_MAX)
1571                     break;
1572 
1573                 std::vector<uint8_t> chunk(carla_getChunkFromBase64String(value));
1574                 CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0,);
1575 
1576 #ifdef CARLA_PROPER_CPP11_SUPPORT
1577                 const uint8_t* const valueptr = chunk.data();
1578 #else
1579                 const uint8_t* const valueptr = &chunk.front();
1580 #endif
1581                 float rvalue;
1582 
1583                 switch (rdfParam.Type)
1584                 {
1585                 case LV2_PARAMETER_TYPE_BOOL:
1586                     rvalue = *(const int32_t*)valueptr != 0 ? 1.0f : 0.0f;
1587                     break;
1588                 case LV2_PARAMETER_TYPE_INT:
1589                     rvalue = static_cast<float>(*(const int32_t*)valueptr);
1590                     break;
1591                 case LV2_PARAMETER_TYPE_FLOAT:
1592                     rvalue = *(const float*)valueptr;
1593                     break;
1594                 case LV2_PARAMETER_TYPE_DOUBLE:
1595                     rvalue = static_cast<float>(*(const double*)valueptr);
1596                     break;
1597                 default:
1598                     // making compilers happy
1599                     rvalue = pData->param.ranges[parameterId].def;
1600                     break;
1601                 }
1602 
1603                 fParamBuffers[parameterId] = pData->param.getFixedValue(parameterId, rvalue);
1604                 break;
1605             }
1606         }
1607 
1608         CarlaPlugin::setCustomData(type, key, value, sendGui);
1609     }
1610 
setProgram(const int32_t index,const bool sendGui,const bool sendOsc,const bool sendCallback,const bool doingInit)1611     void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
1612     {
1613         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1614         CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
1615         CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);
1616 
1617         if (index >= 0 && index < static_cast<int32_t>(fRdfDescriptor->PresetCount))
1618         {
1619             const LV2_URID_Map* const uridMap = (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
1620 
1621             LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fRdfDescriptor->Presets[index].URI,
1622                                                                                   uridMap);
1623             CARLA_SAFE_ASSERT_RETURN(state != nullptr,);
1624 
1625             // invalidate midi-program selection
1626             CarlaPlugin::setMidiProgram(-1, false, false, sendCallback, false);
1627 
1628             if (fExt.state != nullptr)
1629             {
1630                 const bool block = (sendGui || sendOsc || sendCallback) && !fHasThreadSafeRestore;
1631                 const ScopedSingleProcessLocker spl(this, block);
1632 
1633                 lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
1634 
1635                 if (fHandle2 != nullptr)
1636                     lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
1637             }
1638             else
1639             {
1640                 lilv_state_emit_port_values(state, carla_lilv_set_port_value, this);
1641             }
1642 
1643             lilv_state_free(state);
1644         }
1645 
1646         CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
1647     }
1648 
setMidiProgram(const int32_t index,const bool sendGui,const bool sendOsc,const bool sendCallback,const bool doingInit)1649     void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
1650     {
1651         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1652         CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
1653         CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
1654 
1655         if (index >= 0 && fExt.programs != nullptr && fExt.programs->select_program != nullptr)
1656         {
1657             const uint32_t bank(pData->midiprog.data[index].bank);
1658             const uint32_t program(pData->midiprog.data[index].program);
1659 
1660             const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
1661 
1662             try {
1663                 fExt.programs->select_program(fHandle, bank, program);
1664             } CARLA_SAFE_EXCEPTION("select program");
1665 
1666             if (fHandle2 != nullptr)
1667             {
1668                 try {
1669                     fExt.programs->select_program(fHandle2, bank, program);
1670                 } CARLA_SAFE_EXCEPTION("select program 2");
1671             }
1672         }
1673 
1674         CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, doingInit);
1675     }
1676 
setMidiProgramRT(const uint32_t uindex,const bool sendCallbackLater)1677     void setMidiProgramRT(const uint32_t uindex, const bool sendCallbackLater) noexcept override
1678     {
1679         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
1680         CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
1681 
1682         if (fExt.programs != nullptr && fExt.programs->select_program != nullptr)
1683         {
1684             const uint32_t bank(pData->midiprog.data[uindex].bank);
1685             const uint32_t program(pData->midiprog.data[uindex].program);
1686 
1687             try {
1688                 fExt.programs->select_program(fHandle, bank, program);
1689             } CARLA_SAFE_EXCEPTION("select program RT");
1690 
1691             if (fHandle2 != nullptr)
1692             {
1693                 try {
1694                     fExt.programs->select_program(fHandle2, bank, program);
1695                 } CARLA_SAFE_EXCEPTION("select program RT 2");
1696             }
1697         }
1698 
1699         CarlaPlugin::setMidiProgramRT(uindex, sendCallbackLater);
1700     }
1701 
1702     // -------------------------------------------------------------------
1703     // Set ui stuff
1704 
setCustomUITitle(const char * const title)1705     void setCustomUITitle(const char* const title) noexcept override
1706     {
1707         setWindowTitle(title);
1708         CarlaPlugin::setCustomUITitle(title);
1709     }
1710 
showCustomUI(const bool yesNo)1711     void showCustomUI(const bool yesNo) override
1712     {
1713         if (fUI.type == UI::TYPE_NULL)
1714         {
1715             if (yesNo && fFilePathURI.isNotEmpty())
1716             {
1717                 const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN, false, "Open File", "");
1718 
1719                 if (path != nullptr && path[0] != '\0')
1720                 {
1721                     carla_stdout("LV2 file path to send: '%s'", path);
1722                     writeAtomPath(path, getCustomURID(fFilePathURI));
1723                 }
1724             }
1725             else
1726             {
1727                 CARLA_SAFE_ASSERT(!yesNo);
1728             }
1729             pData->engine->callback(true, true,
1730                                     ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
1731             return;
1732         }
1733 
1734         const uintptr_t frontendWinId = pData->engine->getOptions().frontendWinId;
1735 
1736 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
1737         if (! yesNo)
1738             pData->transientTryCounter = 0;
1739 #endif
1740 
1741         if (fUI.type == UI::TYPE_BRIDGE)
1742         {
1743             if (yesNo)
1744             {
1745                 if (fPipeServer.isPipeRunning())
1746                 {
1747                     fPipeServer.writeFocusMessage();
1748                     return;
1749                 }
1750 
1751                 if (! fPipeServer.startPipeServer(std::min(fLv2Options.sequenceSize, 819200)))
1752                 {
1753                     pData->engine->callback(true, true,
1754                                             ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0, 0.0f, nullptr);
1755                     return;
1756                 }
1757 
1758                 // manually write messages so we can take the lock for ourselves
1759                 {
1760                     char tmpBuf[0xff];
1761                     tmpBuf[0xfe] = '\0';
1762 
1763                     const CarlaMutexLocker cml(fPipeServer.getPipeLock());
1764                     const CarlaScopedLocale csl;
1765 
1766                     // write URI mappings
1767                     uint32_t u = 0;
1768                     for (std::vector<std::string>::iterator it=fCustomURIDs.begin(), end=fCustomURIDs.end(); it != end; ++it, ++u)
1769                     {
1770                         if (u < kUridCount)
1771                             continue;
1772                         const std::string& uri(*it);
1773 
1774                         if (! fPipeServer.writeMessage("urid\n", 5))
1775                             return;
1776 
1777                         std::snprintf(tmpBuf, 0xfe, "%u\n", u);
1778                         if (! fPipeServer.writeMessage(tmpBuf))
1779                             return;
1780 
1781                         std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(uri.length()));
1782                         if (! fPipeServer.writeMessage(tmpBuf))
1783                             return;
1784 
1785                         if (! fPipeServer.writeAndFixMessage(uri.c_str()))
1786                             return;
1787                     }
1788 
1789                     // write UI options
1790                     if (! fPipeServer.writeMessage("uiOptions\n", 10))
1791                         return;
1792 
1793                     const EngineOptions& opts(pData->engine->getOptions());
1794 
1795                     std::snprintf(tmpBuf, 0xff, "%g\n", pData->engine->getSampleRate());
1796                     if (! fPipeServer.writeMessage(tmpBuf))
1797                         return;
1798 
1799                     std::snprintf(tmpBuf, 0xff, "%u\n", opts.bgColor);
1800                     if (! fPipeServer.writeMessage(tmpBuf))
1801                         return;
1802 
1803                     std::snprintf(tmpBuf, 0xff, "%u\n", opts.fgColor);
1804                     if (! fPipeServer.writeMessage(tmpBuf))
1805                         return;
1806 
1807                     std::snprintf(tmpBuf, 0xff, "%.12g\n", static_cast<double>(opts.uiScale));
1808                     if (! fPipeServer.writeMessage(tmpBuf))
1809                         return;
1810 
1811                     std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useTheme
1812                     if (! fPipeServer.writeMessage(tmpBuf))
1813                         return;
1814 
1815                     std::snprintf(tmpBuf, 0xff, "%s\n", bool2str(true)); // useThemeColors
1816                     if (! fPipeServer.writeMessage(tmpBuf))
1817                         return;
1818 
1819                     if (! fPipeServer.writeAndFixMessage(fLv2Options.windowTitle != nullptr
1820                                                          ? fLv2Options.windowTitle
1821                                                          : ""))
1822                         return;
1823 
1824                     std::snprintf(tmpBuf, 0xff, P_INTPTR "\n", frontendWinId);
1825                     if (! fPipeServer.writeMessage(tmpBuf))
1826                         return;
1827 
1828                     // write parameter values
1829                     for (uint32_t i=0; i < pData->param.count; ++i)
1830                     {
1831                         ParameterData& pdata(pData->param.data[i]);
1832 
1833                         if (pdata.hints & PARAMETER_IS_NOT_SAVED)
1834                         {
1835                             int32_t rindex = pdata.rindex;
1836                             CARLA_SAFE_ASSERT_CONTINUE(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0);
1837 
1838                             rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
1839                             CARLA_SAFE_ASSERT_CONTINUE(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount));
1840 
1841                             if (! fPipeServer.writeLv2ParameterMessage(fRdfDescriptor->Parameters[rindex].URI,
1842                                                                        getParameterValue(i), false))
1843                                 return;
1844                         }
1845                         else
1846                         {
1847                             if (! fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[i].rindex),
1848                                                                   getParameterValue(i), false))
1849                                 return;
1850                         }
1851                     }
1852 
1853                     // ready to show
1854                     if (! fPipeServer.writeMessage("show\n", 5))
1855                         return;
1856 
1857                     fPipeServer.flushMessages();
1858                 }
1859 
1860 #ifndef BUILD_BRIDGE
1861                 if (fUI.rdfDescriptor->Type == LV2_UI_MOD)
1862                     pData->tryTransient();
1863 #endif
1864             }
1865             else
1866             {
1867                 fPipeServer.stopPipeServer(pData->engine->getOptions().uiBridgesTimeout);
1868             }
1869             return;
1870         }
1871 
1872         // take some precautions
1873         CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
1874         CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr,);
1875 
1876         if (yesNo)
1877         {
1878             CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr,);
1879             CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr,);
1880         }
1881         else
1882         {
1883             if (fUI.handle == nullptr)
1884                 return;
1885         }
1886 
1887         if (yesNo)
1888         {
1889             if (fUI.handle == nullptr)
1890             {
1891 #ifndef LV2_UIS_ONLY_BRIDGES
1892                 if (fUI.type == UI::TYPE_EMBED && fUI.rdfDescriptor->Type != LV2_UI_NONE && fUI.window == nullptr)
1893                 {
1894                     const char* msg = nullptr;
1895                     const bool isStandalone = pData->engine->getOptions().pluginsAreStandalone;
1896 
1897                     switch (fUI.rdfDescriptor->Type)
1898                     {
1899                     case LV2_UI_GTK2:
1900                     case LV2_UI_GTK3:
1901                     case LV2_UI_QT4:
1902                     case LV2_UI_QT5:
1903                     case LV2_UI_EXTERNAL:
1904                     case LV2_UI_OLD_EXTERNAL:
1905                         msg = "Invalid UI type";
1906                         break;
1907 
1908                     case LV2_UI_COCOA:
1909 # ifdef CARLA_OS_MAC
1910                         fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId, isStandalone, isUiResizable());
1911 # else
1912                         msg = "UI is for MacOS only";
1913 # endif
1914                         break;
1915 
1916                     case LV2_UI_WINDOWS:
1917 # ifdef CARLA_OS_WIN
1918                         fUI.window = CarlaPluginUI::newWindows(this, frontendWinId, isStandalone, isUiResizable());
1919 # else
1920                         msg = "UI is for Windows only";
1921 # endif
1922                         break;
1923 
1924                     case LV2_UI_X11:
1925 # ifdef HAVE_X11
1926                         fUI.window = CarlaPluginUI::newX11(this, frontendWinId, isStandalone, isUiResizable(), true);
1927 # else
1928                         msg = "UI is only for systems with X11";
1929 # endif
1930                         break;
1931 
1932                     default:
1933                         msg = "Unknown UI type";
1934                         break;
1935                     }
1936 
1937                     if (fUI.window == nullptr && fExt.uishow == nullptr)
1938                         return pData->engine->callback(true, true,
1939                                                        ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0, 0.0f, msg);
1940 
1941                     if (fUI.window != nullptr)
1942                         fFeatures[kFeatureIdUiParent]->data = fUI.window->getPtr();
1943                 }
1944 #endif
1945                 fUI.widget = nullptr;
1946                 fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
1947                                                          carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
1948 
1949                 if (fUI.window != nullptr)
1950                 {
1951                     if (fUI.widget != nullptr)
1952                         fUI.window->setChildWindow(fUI.widget);
1953                     fUI.window->setTitle(fLv2Options.windowTitle);
1954                 }
1955             }
1956 
1957             CARLA_SAFE_ASSERT(fUI.handle != nullptr);
1958             CARLA_SAFE_ASSERT(fUI.type != UI::TYPE_EXTERNAL || fUI.widget != nullptr);
1959 
1960             if (fUI.handle == nullptr || (fUI.type == UI::TYPE_EXTERNAL && fUI.widget == nullptr))
1961             {
1962                 fUI.widget = nullptr;
1963 
1964                 if (fUI.handle != nullptr)
1965                 {
1966                     fUI.descriptor->cleanup(fUI.handle);
1967                     fUI.handle = nullptr;
1968                 }
1969 
1970                 return pData->engine->callback(true, true,
1971                                                ENGINE_CALLBACK_UI_STATE_CHANGED,
1972                                                pData->id,
1973                                                -1,
1974                                                0, 0, 0.0f,
1975                                                "Plugin refused to open its own UI");
1976             }
1977 
1978             updateUi();
1979 
1980 #ifndef LV2_UIS_ONLY_BRIDGES
1981             if (fUI.type == UI::TYPE_EMBED)
1982             {
1983                 if (fUI.window != nullptr)
1984                 {
1985                     fUI.window->show();
1986                 }
1987                 else if (fExt.uishow != nullptr)
1988                 {
1989                     fExt.uishow->show(fUI.handle);
1990 # ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
1991                     pData->tryTransient();
1992 # endif
1993                 }
1994             }
1995             else
1996 #endif
1997             {
1998                 LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUI.widget);
1999 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2000                 pData->tryTransient();
2001 #endif
2002             }
2003         }
2004         else
2005         {
2006 #ifndef LV2_UIS_ONLY_BRIDGES
2007             if (fUI.type == UI::TYPE_EMBED)
2008             {
2009                 if (fUI.window != nullptr)
2010                     fUI.window->hide();
2011                 else if (fExt.uishow != nullptr)
2012                     fExt.uishow->hide(fUI.handle);
2013             }
2014             else
2015 #endif
2016             {
2017                 CARLA_SAFE_ASSERT(fUI.widget != nullptr);
2018 
2019                 if (fUI.widget != nullptr)
2020                     LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget*)fUI.widget);
2021             }
2022 
2023             fUI.descriptor->cleanup(fUI.handle);
2024             fUI.handle = nullptr;
2025             fUI.widget = nullptr;
2026 
2027             if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
2028             {
2029                 delete fUI.window;
2030                 fUI.window = nullptr;
2031             }
2032         }
2033     }
2034 
2035 #ifndef LV2_UIS_ONLY_BRIDGES
embedCustomUI(void * const ptr)2036     void* embedCustomUI(void* const ptr) override
2037     {
2038         CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED, nullptr);
2039         CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr, nullptr);
2040         CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->instantiate != nullptr, nullptr);
2041         CARLA_SAFE_ASSERT_RETURN(fUI.descriptor->cleanup != nullptr, nullptr);
2042         CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor->Type != LV2_UI_NONE, nullptr);
2043         CARLA_SAFE_ASSERT_RETURN(fUI.window == nullptr, nullptr);
2044 
2045         fFeatures[kFeatureIdUiParent]->data = ptr;
2046 
2047         fUI.embedded = true;
2048         fUI.widget = nullptr;
2049         fUI.handle = fUI.descriptor->instantiate(fUI.descriptor, fRdfDescriptor->URI, fUI.rdfDescriptor->Bundle,
2050                                                  carla_lv2_ui_write_function, this, &fUI.widget, fFeatures);
2051 
2052         updateUi();
2053 
2054         return fUI.widget;
2055     }
2056 #endif
2057 
idle()2058     void idle() override
2059     {
2060         if (fAtomBufferWorkerIn.isDataAvailableForReading())
2061         {
2062             Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferWorkerIn, fAtomBufferWorkerInTmpData);
2063             CARLA_SAFE_ASSERT_RETURN(tmpRingBuffer.isDataAvailableForReading(),);
2064             CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr,);
2065 
2066             uint32_t portIndex;
2067             const LV2_Atom* atom;
2068 
2069             for (; tmpRingBuffer.get(atom, portIndex);)
2070             {
2071                 CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerIn);
2072                 fExt.worker->work(fHandle, carla_lv2_worker_respond, this, atom->size, LV2_ATOM_BODY_CONST(atom));
2073             }
2074         }
2075 
2076         if (fInlineDisplayNeedsRedraw)
2077         {
2078             // TESTING
2079             CARLA_SAFE_ASSERT(pData->enabled)
2080             CARLA_SAFE_ASSERT(!pData->engine->isAboutToClose());
2081             CARLA_SAFE_ASSERT(pData->client->isActive());
2082 
2083             if (pData->enabled && !pData->engine->isAboutToClose() && pData->client->isActive())
2084             {
2085                 const int64_t timeNow = water::Time::currentTimeMillis();
2086 
2087                 if (timeNow - fInlineDisplayLastRedrawTime > (1000 / 30))
2088                 {
2089                     fInlineDisplayNeedsRedraw = false;
2090                     fInlineDisplayLastRedrawTime = timeNow;
2091                     pData->engine->callback(true, true,
2092                                             ENGINE_CALLBACK_INLINE_DISPLAY_REDRAW,
2093                                             pData->id,
2094                                             0, 0, 0, 0.0f, nullptr);
2095                 }
2096             }
2097             else
2098             {
2099                 fInlineDisplayNeedsRedraw = false;
2100             }
2101         }
2102 
2103         CarlaPlugin::idle();
2104     }
2105 
uiIdle()2106     void uiIdle() override
2107     {
2108         if (const char* const fileNeededForURI = fUI.fileNeededForURI)
2109         {
2110             fUI.fileBrowserOpen = true;
2111             fUI.fileNeededForURI = nullptr;
2112 
2113             const char* const path = pData->engine->runFileCallback(FILE_CALLBACK_OPEN,
2114                                                                     /* isDir   */ false,
2115                                                                     /* title   */ "File open",
2116                                                                     /* filters */ "");
2117 
2118             fUI.fileBrowserOpen = false;
2119 
2120             if (path != nullptr)
2121             {
2122                 carla_stdout("LV2 requested path to send: '%s'", path);
2123                 writeAtomPath(path, getCustomURID(fileNeededForURI));
2124             }
2125 
2126             // this function will be called recursively, stop here
2127             return;
2128         }
2129 
2130         if (fAtomBufferUiOut.isDataAvailableForReading())
2131         {
2132             Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferUiOut, fAtomBufferUiOutTmpData);
2133             CARLA_SAFE_ASSERT(tmpRingBuffer.isDataAvailableForReading());
2134 
2135             uint32_t portIndex;
2136             const LV2_Atom* atom;
2137             const bool hasPortEvent(fUI.handle != nullptr &&
2138                                     fUI.descriptor != nullptr &&
2139                                     fUI.descriptor->port_event != nullptr);
2140 
2141             for (; tmpRingBuffer.get(atom, portIndex);)
2142             {
2143                 if (fUI.type == UI::TYPE_BRIDGE)
2144                 {
2145                     if (fPipeServer.isPipeRunning())
2146                         fPipeServer.writeLv2AtomMessage(portIndex, atom);
2147                 }
2148                 else
2149                 {
2150                     if (hasPortEvent && ! fNeedsUiClose)
2151                         fUI.descriptor->port_event(fUI.handle, portIndex, lv2_atom_total_size(atom), kUridAtomTransferEvent, atom);
2152                 }
2153 
2154                 inspectAtomForParameterChange(atom);
2155             }
2156         }
2157 
2158         if (fPipeServer.isPipeRunning())
2159         {
2160             fPipeServer.idlePipe();
2161 
2162             switch (fPipeServer.getAndResetUiState())
2163             {
2164             case CarlaPipeServerLV2::UiNone:
2165             case CarlaPipeServerLV2::UiShow:
2166                 break;
2167             case CarlaPipeServerLV2::UiHide:
2168                 fPipeServer.stopPipeServer(2000);
2169                 // fall through
2170             case CarlaPipeServerLV2::UiCrashed:
2171 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2172                 pData->transientTryCounter = 0;
2173 #endif
2174                 pData->engine->callback(true, true,
2175                                         ENGINE_CALLBACK_UI_STATE_CHANGED,
2176                                         pData->id,
2177                                         0,
2178                                         0, 0, 0.0f, nullptr);
2179                 break;
2180             }
2181         }
2182         else
2183         {
2184             // TODO - detect if ui-bridge crashed
2185         }
2186 
2187         if (fNeedsUiClose)
2188         {
2189             fNeedsUiClose = false;
2190             showCustomUI(false);
2191             pData->engine->callback(true, true,
2192                                     ENGINE_CALLBACK_UI_STATE_CHANGED,
2193                                     pData->id,
2194                                     0,
2195                                     0, 0, 0.0f, nullptr);
2196         }
2197         else if (fUI.handle != nullptr && fUI.descriptor != nullptr)
2198         {
2199             if (fUI.type == UI::TYPE_EXTERNAL && fUI.widget != nullptr)
2200                 LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUI.widget);
2201 #ifndef LV2_UIS_ONLY_BRIDGES
2202             else if (fUI.type == UI::TYPE_EMBED && fUI.window != nullptr)
2203                 fUI.window->idle();
2204 
2205             // note: UI might have been closed by window idle
2206             if (fNeedsUiClose)
2207             {
2208                 pass();
2209             }
2210             else if (fUI.handle != nullptr && fExt.uiidle != nullptr && fExt.uiidle->idle(fUI.handle) != 0)
2211             {
2212                 showCustomUI(false);
2213                 pData->engine->callback(true, true,
2214                                         ENGINE_CALLBACK_UI_STATE_CHANGED,
2215                                         pData->id,
2216                                         0,
2217                                         0, 0, 0.0f, nullptr);
2218                 CARLA_SAFE_ASSERT(fUI.handle == nullptr);
2219             }
2220 #endif
2221         }
2222 
2223         CarlaPlugin::uiIdle();
2224     }
2225 
2226     // -------------------------------------------------------------------
2227     // Plugin state
2228 
reload()2229     void reload() override
2230     {
2231         CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
2232         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
2233         CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
2234         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
2235         carla_debug("CarlaPluginLV2::reload() - start");
2236 
2237         const EngineProcessMode processMode(pData->engine->getProccessMode());
2238 
2239         // Safely disable plugin for reload
2240         const ScopedDisabler sd(this);
2241 
2242         if (pData->active)
2243             deactivate();
2244 
2245         clearBuffers();
2246 
2247         const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
2248         const uint32_t portCount(fRdfDescriptor->PortCount);
2249 
2250         uint32_t aIns, aOuts, cvIns, cvOuts, params;
2251         aIns = aOuts = cvIns = cvOuts = params = 0;
2252         LinkedList<uint> evIns, evOuts;
2253 
2254         const uint32_t eventBufferSize = static_cast<uint32_t>(fLv2Options.sequenceSize) + 0xff;
2255 
2256         bool forcedStereoIn, forcedStereoOut;
2257         forcedStereoIn = forcedStereoOut = false;
2258 
2259         bool needsCtrlIn, needsCtrlOut, hasPatchParameterOutputs;
2260         needsCtrlIn = needsCtrlOut = hasPatchParameterOutputs = false;
2261 
2262         for (uint32_t i=0; i < portCount; ++i)
2263         {
2264             const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
2265 
2266             if (LV2_IS_PORT_AUDIO(portTypes))
2267             {
2268                 if (LV2_IS_PORT_INPUT(portTypes))
2269                     aIns += 1;
2270                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2271                     aOuts += 1;
2272             }
2273             else if (LV2_IS_PORT_CV(portTypes))
2274             {
2275                 if (LV2_IS_PORT_INPUT(portTypes))
2276                     cvIns += 1;
2277                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2278                     cvOuts += 1;
2279             }
2280             else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
2281             {
2282                 if (LV2_IS_PORT_INPUT(portTypes))
2283                     evIns.append(CARLA_EVENT_DATA_ATOM);
2284                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2285                     evOuts.append(CARLA_EVENT_DATA_ATOM);
2286             }
2287             else if (LV2_IS_PORT_EVENT(portTypes))
2288             {
2289                 if (LV2_IS_PORT_INPUT(portTypes))
2290                     evIns.append(CARLA_EVENT_DATA_EVENT);
2291                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2292                     evOuts.append(CARLA_EVENT_DATA_EVENT);
2293             }
2294             else if (LV2_IS_PORT_MIDI_LL(portTypes))
2295             {
2296                 if (LV2_IS_PORT_INPUT(portTypes))
2297                     evIns.append(CARLA_EVENT_DATA_MIDI_LL);
2298                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2299                     evOuts.append(CARLA_EVENT_DATA_MIDI_LL);
2300             }
2301             else if (LV2_IS_PORT_CONTROL(portTypes))
2302                 params += 1;
2303         }
2304 
2305         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
2306         {
2307             switch (fRdfDescriptor->Parameters[i].Type)
2308             {
2309             case LV2_PARAMETER_TYPE_BOOL:
2310             case LV2_PARAMETER_TYPE_INT:
2311             // case LV2_PARAMETER_TYPE_LONG:
2312             case LV2_PARAMETER_TYPE_FLOAT:
2313             case LV2_PARAMETER_TYPE_DOUBLE:
2314                 params += 1;
2315                 break;
2316             case LV2_PARAMETER_TYPE_PATH:
2317                 if (fFilePathURI.isEmpty())
2318                     fFilePathURI = fRdfDescriptor->Parameters[i].URI;
2319                 break;
2320             }
2321         }
2322 
2323         if ((pData->options & PLUGIN_OPTION_FORCE_STEREO) != 0 && aIns <= 1 && aOuts <= 1 && evOuts.count() == 0 && fExt.state == nullptr && fExt.worker == nullptr)
2324         {
2325             if (fHandle2 == nullptr)
2326             {
2327                 try {
2328                     fHandle2 = fDescriptor->instantiate(fDescriptor, sampleRate, fRdfDescriptor->Bundle, fFeatures);
2329                 } catch(...) {}
2330             }
2331 
2332             if (fHandle2 != nullptr)
2333             {
2334                 if (aIns == 1)
2335                 {
2336                     aIns = 2;
2337                     forcedStereoIn = true;
2338                 }
2339 
2340                 if (aOuts == 1)
2341                 {
2342                     aOuts = 2;
2343                     forcedStereoOut = true;
2344                 }
2345             }
2346         }
2347 
2348         if (aIns > 0)
2349         {
2350             pData->audioIn.createNew(aIns);
2351             fAudioInBuffers = new float*[aIns];
2352 
2353             for (uint32_t i=0; i < aIns; ++i)
2354                 fAudioInBuffers[i] = nullptr;
2355         }
2356 
2357         if (aOuts > 0)
2358         {
2359             pData->audioOut.createNew(aOuts);
2360             fAudioOutBuffers = new float*[aOuts];
2361             needsCtrlIn = true;
2362 
2363             for (uint32_t i=0; i < aOuts; ++i)
2364                 fAudioOutBuffers[i] = nullptr;
2365         }
2366 
2367         if (cvIns > 0)
2368         {
2369             pData->cvIn.createNew(cvIns);
2370             fCvInBuffers = new float*[cvIns];
2371 
2372             for (uint32_t i=0; i < cvIns; ++i)
2373                 fCvInBuffers[i] = nullptr;
2374         }
2375 
2376         if (cvOuts > 0)
2377         {
2378             pData->cvOut.createNew(cvOuts);
2379             fCvOutBuffers = new float*[cvOuts];
2380 
2381             for (uint32_t i=0; i < cvOuts; ++i)
2382                 fCvOutBuffers[i] = nullptr;
2383         }
2384 
2385         if (params > 0)
2386         {
2387             pData->param.createNew(params, true);
2388             fParamBuffers = new float[params];
2389             carla_zeroFloats(fParamBuffers, params);
2390         }
2391 
2392         if (const uint32_t count = static_cast<uint32_t>(evIns.count()))
2393         {
2394             fEventsIn.createNew(count);
2395 
2396             for (uint32_t i=0; i < count; ++i)
2397             {
2398                 const uint32_t& type(evIns.getAt(i, 0x0));
2399 
2400                 if (type == CARLA_EVENT_DATA_ATOM)
2401                 {
2402                     fEventsIn.data[i].type = CARLA_EVENT_DATA_ATOM;
2403                     fEventsIn.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, true);
2404                 }
2405                 else if (type == CARLA_EVENT_DATA_EVENT)
2406                 {
2407                     fEventsIn.data[i].type  = CARLA_EVENT_DATA_EVENT;
2408                     fEventsIn.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
2409                 }
2410                 else if (type == CARLA_EVENT_DATA_MIDI_LL)
2411                 {
2412                     fEventsIn.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
2413                     fEventsIn.data[i].midi.capacity = eventBufferSize;
2414                     fEventsIn.data[i].midi.data     = new uchar[eventBufferSize];
2415                 }
2416             }
2417         }
2418         else
2419         {
2420             fEventsIn.createNew(1);
2421             fEventsIn.ctrl = &fEventsIn.data[0];
2422         }
2423 
2424         if (const uint32_t count = static_cast<uint32_t>(evOuts.count()))
2425         {
2426             fEventsOut.createNew(count);
2427 
2428             for (uint32_t i=0; i < count; ++i)
2429             {
2430                 const uint32_t& type(evOuts.getAt(i, 0x0));
2431 
2432                 if (type == CARLA_EVENT_DATA_ATOM)
2433                 {
2434                     fEventsOut.data[i].type = CARLA_EVENT_DATA_ATOM;
2435                     fEventsOut.data[i].atom = lv2_atom_buffer_new(eventBufferSize, kUridNull, kUridAtomSequence, false);
2436                 }
2437                 else if (type == CARLA_EVENT_DATA_EVENT)
2438                 {
2439                     fEventsOut.data[i].type  = CARLA_EVENT_DATA_EVENT;
2440                     fEventsOut.data[i].event = lv2_event_buffer_new(eventBufferSize, LV2_EVENT_AUDIO_STAMP);
2441                 }
2442                 else if (type == CARLA_EVENT_DATA_MIDI_LL)
2443                 {
2444                     fEventsOut.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
2445                     fEventsOut.data[i].midi.capacity = eventBufferSize;
2446                     fEventsOut.data[i].midi.data     = new uchar[eventBufferSize];
2447                 }
2448             }
2449         }
2450 
2451         const uint portNameSize(pData->engine->getMaxPortNameSize());
2452         CarlaString portName;
2453         uint32_t iCtrl = 0;
2454 
2455         for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCvIn=0, iCvOut=0, iEvIn=0, iEvOut=0; i < portCount; ++i)
2456         {
2457             const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
2458 
2459             portName.clear();
2460 
2461             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))
2462             {
2463                 if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
2464                 {
2465                     portName  = pData->name;
2466                     portName += ":";
2467                 }
2468 
2469                 portName += fRdfDescriptor->Ports[i].Name;
2470                 portName.truncate(portNameSize);
2471             }
2472 
2473             if (LV2_IS_PORT_AUDIO(portTypes))
2474             {
2475                 if (LV2_IS_PORT_INPUT(portTypes))
2476                 {
2477                     const uint32_t j = iAudioIn++;
2478                     pData->audioIn.ports[j].port   = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
2479                     pData->audioIn.ports[j].rindex = i;
2480 
2481                     if (forcedStereoIn)
2482                     {
2483                         portName += "_2";
2484                         pData->audioIn.ports[1].port   = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, 1);
2485                         pData->audioIn.ports[1].rindex = i;
2486                     }
2487                 }
2488                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2489                 {
2490                     const uint32_t j = iAudioOut++;
2491                     pData->audioOut.ports[j].port   = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
2492                     pData->audioOut.ports[j].rindex = i;
2493 
2494                     if (forcedStereoOut)
2495                     {
2496                         portName += "_2";
2497                         pData->audioOut.ports[1].port   = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, 1);
2498                         pData->audioOut.ports[1].rindex = i;
2499                     }
2500                 }
2501                 else
2502                     carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
2503             }
2504             else if (LV2_IS_PORT_CV(portTypes))
2505             {
2506                 const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
2507                 float min, max;
2508 
2509                 // min value
2510                 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
2511                     min = portPoints.Minimum;
2512                 else
2513                     min = -1.0f;
2514 
2515                 // max value
2516                 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
2517                     max = portPoints.Maximum;
2518                 else
2519                     max = 1.0f;
2520 
2521                 if (LV2_IS_PORT_INPUT(portTypes))
2522                 {
2523                     const uint32_t j = iCvIn++;
2524                     pData->cvIn.ports[j].port   = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j);
2525                     pData->cvIn.ports[j].rindex = i;
2526                     pData->cvIn.ports[j].port->setRange(min, max);
2527                 }
2528                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2529                 {
2530                     const uint32_t j = iCvOut++;
2531                     pData->cvOut.ports[j].port   = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j);
2532                     pData->cvOut.ports[j].rindex = i;
2533                     pData->cvOut.ports[j].port->setRange(min, max);
2534                 }
2535                 else
2536                     carla_stderr("WARNING - Got a broken Port (CV, but not input or output)");
2537             }
2538             else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
2539             {
2540                 if (LV2_IS_PORT_INPUT(portTypes))
2541                 {
2542                     const uint32_t j = iEvIn++;
2543 
2544                     fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].atom->atoms);
2545 
2546                     if (fHandle2 != nullptr)
2547                         fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].atom->atoms);
2548 
2549                     fEventsIn.data[j].rindex = i;
2550 
2551                     if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2552                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2553                     if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2554                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2555                     if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2556                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
2557 
2558                     if (evIns.count() == 1)
2559                     {
2560                         fEventsIn.ctrl = &fEventsIn.data[j];
2561                         fEventsIn.ctrlIndex = j;
2562 
2563                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2564                             needsCtrlIn = true;
2565                     }
2566                     else
2567                     {
2568                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2569                             fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2570 
2571                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2572                         {
2573                             fEventsIn.ctrl = &fEventsIn.data[j];
2574                             fEventsIn.ctrlIndex = j;
2575                         }
2576                     }
2577                 }
2578                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2579                 {
2580                     const uint32_t j = iEvOut++;
2581 
2582                     fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].atom->atoms);
2583 
2584                     if (fHandle2 != nullptr)
2585                         fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].atom->atoms);
2586 
2587                     fEventsOut.data[j].rindex = i;
2588 
2589                     if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2590                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2591                     if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2592                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2593                     if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2594                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
2595 
2596                     if (evOuts.count() == 1)
2597                     {
2598                         fEventsOut.ctrl = &fEventsOut.data[j];
2599                         fEventsOut.ctrlIndex = j;
2600 
2601                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2602                             needsCtrlOut = true;
2603                     }
2604                     else
2605                     {
2606                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2607                             fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2608 
2609                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2610                         {
2611                             fEventsOut.ctrl = &fEventsOut.data[j];
2612                             fEventsOut.ctrlIndex = j;
2613                         }
2614                     }
2615                 }
2616                 else
2617                     carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
2618             }
2619             else if (LV2_IS_PORT_EVENT(portTypes))
2620             {
2621                 if (LV2_IS_PORT_INPUT(portTypes))
2622                 {
2623                     const uint32_t j = iEvIn++;
2624 
2625                     fDescriptor->connect_port(fHandle, i, fEventsIn.data[j].event);
2626 
2627                     if (fHandle2 != nullptr)
2628                         fDescriptor->connect_port(fHandle2, i, fEventsIn.data[j].event);
2629 
2630                     fEventsIn.data[j].rindex = i;
2631 
2632                     if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2633                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2634                     if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2635                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2636                     if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2637                         fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
2638 
2639                     if (evIns.count() == 1)
2640                     {
2641                         fEventsIn.ctrl = &fEventsIn.data[j];
2642                         fEventsIn.ctrlIndex = j;
2643 
2644                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2645                             needsCtrlIn = true;
2646                     }
2647                     else
2648                     {
2649                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2650                             fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2651 
2652                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2653                         {
2654                             fEventsIn.ctrl = &fEventsIn.data[j];
2655                             fEventsIn.ctrlIndex = j;
2656                         }
2657                     }
2658                 }
2659                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2660                 {
2661                     const uint32_t j = iEvOut++;
2662 
2663                     fDescriptor->connect_port(fHandle, i, fEventsOut.data[j].event);
2664 
2665                     if (fHandle2 != nullptr)
2666                         fDescriptor->connect_port(fHandle2, i, fEventsOut.data[j].event);
2667 
2668                     fEventsOut.data[j].rindex = i;
2669 
2670                     if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2671                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
2672                     if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
2673                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
2674                     if (portTypes & LV2_PORT_DATA_TIME_POSITION)
2675                         fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
2676 
2677                     if (evOuts.count() == 1)
2678                     {
2679                         fEventsOut.ctrl = &fEventsOut.data[j];
2680                         fEventsOut.ctrlIndex = j;
2681 
2682                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2683                             needsCtrlOut = true;
2684                     }
2685                     else
2686                     {
2687                         if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
2688                             fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2689 
2690                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2691                         {
2692                             fEventsOut.ctrl = &fEventsOut.data[j];
2693                             fEventsOut.ctrlIndex = j;
2694                         }
2695                     }
2696                 }
2697                 else
2698                     carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
2699             }
2700             else if (LV2_IS_PORT_MIDI_LL(portTypes))
2701             {
2702                 if (LV2_IS_PORT_INPUT(portTypes))
2703                 {
2704                     const uint32_t j = iEvIn++;
2705 
2706                     fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].midi);
2707 
2708                     if (fHandle2 != nullptr)
2709                         fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].midi);
2710 
2711                     fEventsIn.data[j].type  |= CARLA_EVENT_TYPE_MIDI;
2712                     fEventsIn.data[j].rindex = i;
2713 
2714                     if (evIns.count() == 1)
2715                     {
2716                         needsCtrlIn = true;
2717                         fEventsIn.ctrl = &fEventsIn.data[j];
2718                         fEventsIn.ctrlIndex = j;
2719                     }
2720                     else
2721                     {
2722                         fEventsIn.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, j);
2723 
2724                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2725                         {
2726                             fEventsIn.ctrl = &fEventsIn.data[j];
2727                             fEventsIn.ctrlIndex = j;
2728                         }
2729                     }
2730                 }
2731                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2732                 {
2733                     const uint32_t j = iEvOut++;
2734 
2735                     fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].midi);
2736 
2737                     if (fHandle2 != nullptr)
2738                         fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].midi);
2739 
2740                     fEventsOut.data[j].type  |= CARLA_EVENT_TYPE_MIDI;
2741                     fEventsOut.data[j].rindex = i;
2742 
2743                     if (evOuts.count() == 1)
2744                     {
2745                         needsCtrlOut = true;
2746                         fEventsOut.ctrl = &fEventsOut.data[j];
2747                         fEventsOut.ctrlIndex = j;
2748                     }
2749                     else
2750                     {
2751                         fEventsOut.data[j].port = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, j);
2752 
2753                         if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
2754                         {
2755                             fEventsOut.ctrl = &fEventsOut.data[j];
2756                             fEventsOut.ctrlIndex = j;
2757                         }
2758                     }
2759                 }
2760                 else
2761                     carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
2762             }
2763             else if (LV2_IS_PORT_CONTROL(portTypes))
2764             {
2765                 const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties);
2766                 const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
2767                 const LV2_RDF_PortPoints portPoints(fRdfDescriptor->Ports[i].Points);
2768 
2769                 const uint32_t j = iCtrl++;
2770                 pData->param.data[j].index  = static_cast<int32_t>(j);
2771                 pData->param.data[j].rindex = static_cast<int32_t>(i);
2772 
2773                 float min, max, def, step, stepSmall, stepLarge;
2774 
2775                 // min value
2776                 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
2777                     min = portPoints.Minimum;
2778                 else
2779                     min = 0.0f;
2780 
2781                 // max value
2782                 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
2783                     max = portPoints.Maximum;
2784                 else
2785                     max = 1.0f;
2786 
2787                 if (LV2_IS_PORT_SAMPLE_RATE(portProps))
2788                 {
2789                     min *= sampleRate;
2790                     max *= sampleRate;
2791                     pData->param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
2792                 }
2793 
2794                 // stupid hack for ir.lv2 (broken plugin)
2795                 if (std::strcmp(fRdfDescriptor->URI, "http://factorial.hu/plugins/lv2/ir") == 0 && std::strncmp(fRdfDescriptor->Ports[i].Name, "FileHash", 8) == 0)
2796                 {
2797                     min = 0.0f;
2798                     max = (float)0xffffff;
2799                 }
2800 
2801                 if (min >= max)
2802                 {
2803                     carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", fRdfDescriptor->Ports[i].Name);
2804                     max = min + 0.1f;
2805                 }
2806 
2807                 // default value
2808                 if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
2809                 {
2810                     def = portPoints.Default;
2811                 }
2812                 else
2813                 {
2814                     // no default value
2815                     if (min < 0.0f && max > 0.0f)
2816                         def = 0.0f;
2817                     else
2818                         def = min;
2819                 }
2820 
2821                 if (def < min)
2822                     def = min;
2823                 else if (def > max)
2824                     def = max;
2825 
2826                 if (LV2_IS_PORT_TOGGLED(portProps))
2827                 {
2828                     step = max - min;
2829                     stepSmall = step;
2830                     stepLarge = step;
2831                     pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
2832                 }
2833                 else if (LV2_IS_PORT_INTEGER(portProps))
2834                 {
2835                     step = 1.0f;
2836                     stepSmall = 1.0f;
2837                     stepLarge = 10.0f;
2838                     pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
2839                 }
2840                 else
2841                 {
2842                     float range = max - min;
2843                     step = range/100.0f;
2844                     stepSmall = range/1000.0f;
2845                     stepLarge = range/10.0f;
2846                 }
2847 
2848                 if (LV2_IS_PORT_INPUT(portTypes))
2849                 {
2850                     pData->param.data[j].type = PARAMETER_INPUT;
2851 
2852                     if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
2853                     {
2854                         carla_stderr("Plugin has latency input port, this should not happen!");
2855                     }
2856                     else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
2857                     {
2858                         def = sampleRate;
2859                         step = 1.0f;
2860                         stepSmall = 1.0f;
2861                         stepLarge = 1.0f;
2862                         pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
2863                     }
2864                     else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
2865                     {
2866                         pData->param.special[j] = PARAMETER_SPECIAL_FREEWHEEL;
2867                     }
2868                     else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
2869                     {
2870                         pData->param.special[j] = PARAMETER_SPECIAL_TIME;
2871                     }
2872                     else
2873                     {
2874                         pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
2875                         pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
2876                         needsCtrlIn = true;
2877 
2878                         if (! LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) &&
2879                             ! LV2_IS_PORT_ENUMERATION(portProps) &&
2880                             ! LV2_IS_PORT_EXPENSIVE(portProps) &&
2881                             ! LV2_IS_PORT_NOT_AUTOMATIC(portProps) &&
2882                             ! LV2_IS_PORT_NOT_ON_GUI(portProps) &&
2883                             ! LV2_IS_PORT_TRIGGER(portProps))
2884                         {
2885                             pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED;
2886                         }
2887                     }
2888 
2889                     // MIDI CC value
2890                     const LV2_RDF_PortMidiMap& portMidiMap(fRdfDescriptor->Ports[i].MidiMap);
2891 
2892                     if (LV2_IS_PORT_MIDI_MAP_CC(portMidiMap.Type))
2893                     {
2894                         if (portMidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(portMidiMap.Number))
2895                             pData->param.data[j].mappedControlIndex = static_cast<int16_t>(portMidiMap.Number);
2896                     }
2897                 }
2898                 else if (LV2_IS_PORT_OUTPUT(portTypes))
2899                 {
2900                     pData->param.data[j].type = PARAMETER_OUTPUT;
2901 
2902                     if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
2903                     {
2904                         min = 0.0f;
2905                         max = sampleRate;
2906                         def = 0.0f;
2907                         step = 1.0f;
2908                         stepSmall = 1.0f;
2909                         stepLarge = 1.0f;
2910                         pData->param.special[j] = PARAMETER_SPECIAL_LATENCY;
2911                         CARLA_SAFE_ASSERT_INT2(fLatencyIndex == static_cast<int32_t>(j), fLatencyIndex, j);
2912                     }
2913                     else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation))
2914                     {
2915                         def = sampleRate;
2916                         step = 1.0f;
2917                         stepSmall = 1.0f;
2918                         stepLarge = 1.0f;
2919                         pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE;
2920                     }
2921                     else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation))
2922                     {
2923                         carla_stderr("Plugin has freewheeling output port, this should not happen!");
2924                     }
2925                     else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation))
2926                     {
2927                         pData->param.special[j] = PARAMETER_SPECIAL_TIME;
2928                     }
2929                     else
2930                     {
2931                         pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
2932                         pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
2933                         needsCtrlOut = true;
2934                     }
2935                 }
2936                 else
2937                 {
2938                     pData->param.data[j].type = PARAMETER_UNKNOWN;
2939                     carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)");
2940                 }
2941 
2942                 // extra parameter hints
2943                 if (LV2_IS_PORT_LOGARITHMIC(portProps))
2944                     pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
2945 
2946                 if (LV2_IS_PORT_TRIGGER(portProps))
2947                     pData->param.data[j].hints |= PARAMETER_IS_TRIGGER;
2948 
2949                 if (LV2_IS_PORT_STRICT_BOUNDS(portProps))
2950                     pData->param.data[j].hints |= PARAMETER_IS_STRICT_BOUNDS;
2951 
2952                 if (LV2_IS_PORT_ENUMERATION(portProps))
2953                     pData->param.data[j].hints |= PARAMETER_USES_SCALEPOINTS;
2954 
2955                 // check if parameter is not enabled or automable
2956                 if (LV2_IS_PORT_NOT_ON_GUI(portProps))
2957                     pData->param.data[j].hints &= ~(PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE);
2958                 else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) || LV2_IS_PORT_EXPENSIVE(portProps))
2959                     pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMABLE;
2960                 else if (LV2_IS_PORT_NOT_AUTOMATIC(portProps) || LV2_IS_PORT_NON_AUTOMABLE(portProps))
2961                     pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMABLE;
2962 
2963                 pData->param.ranges[j].min = min;
2964                 pData->param.ranges[j].max = max;
2965                 pData->param.ranges[j].def = def;
2966                 pData->param.ranges[j].step = step;
2967                 pData->param.ranges[j].stepSmall = stepSmall;
2968                 pData->param.ranges[j].stepLarge = stepLarge;
2969 
2970                 // Start parameters in their default values (except freewheel, which is off by default)
2971                 if (pData->param.data[j].type == PARAMETER_INPUT && pData->param.special[j] == PARAMETER_SPECIAL_FREEWHEEL)
2972                     fParamBuffers[j] = min;
2973                 else
2974                     fParamBuffers[j] = def;
2975 
2976                 fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);
2977 
2978                 if (fHandle2 != nullptr)
2979                     fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
2980             }
2981             else
2982             {
2983                 // Port Type not supported, but it's optional anyway
2984                 fDescriptor->connect_port(fHandle, i, nullptr);
2985 
2986                 if (fHandle2 != nullptr)
2987                     fDescriptor->connect_port(fHandle2, i, nullptr);
2988             }
2989         }
2990 
2991         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
2992         {
2993             const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
2994 
2995             switch (rdfParam.Type)
2996             {
2997             case LV2_PARAMETER_TYPE_BOOL:
2998             case LV2_PARAMETER_TYPE_INT:
2999             // case LV2_PARAMETER_TYPE_LONG:
3000             case LV2_PARAMETER_TYPE_FLOAT:
3001             case LV2_PARAMETER_TYPE_DOUBLE:
3002                 break;
3003             default:
3004                 continue;
3005             }
3006 
3007             const LV2_RDF_PortPoints& portPoints(rdfParam.Points);
3008 
3009             const uint32_t j = iCtrl++;
3010             pData->param.data[j].index  = static_cast<int32_t>(j);
3011             pData->param.data[j].rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
3012 
3013             float min, max, def, step, stepSmall, stepLarge;
3014 
3015             // min value
3016             if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints.Hints))
3017                 min = portPoints.Minimum;
3018             else
3019                 min = 0.0f;
3020 
3021             // max value
3022             if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints.Hints))
3023                 max = portPoints.Maximum;
3024             else
3025                 max = 1.0f;
3026 
3027             if (min >= max)
3028             {
3029                 carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", rdfParam.Label);
3030                 max = min + 0.1f;
3031             }
3032 
3033             // default value
3034             if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints.Hints))
3035             {
3036                 def = portPoints.Default;
3037             }
3038             else
3039             {
3040                 // no default value
3041                 if (min < 0.0f && max > 0.0f)
3042                     def = 0.0f;
3043                 else
3044                     def = min;
3045             }
3046 
3047             if (def < min)
3048                 def = min;
3049             else if (def > max)
3050                 def = max;
3051 
3052             switch (rdfParam.Type)
3053             {
3054             case LV2_PARAMETER_TYPE_BOOL:
3055                 step = max - min;
3056                 stepSmall = step;
3057                 stepLarge = step;
3058                 pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
3059                 break;
3060 
3061             case LV2_PARAMETER_TYPE_INT:
3062             case LV2_PARAMETER_TYPE_LONG:
3063                 step = 1.0f;
3064                 stepSmall = 1.0f;
3065                 stepLarge = 10.0f;
3066                 pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
3067                 break;
3068 
3069             default:
3070                 const float range = max - min;
3071                 step = range/100.0f;
3072                 stepSmall = range/1000.0f;
3073                 stepLarge = range/10.0f;
3074                 break;
3075             }
3076 
3077             if (rdfParam.Flags & LV2_PARAMETER_FLAG_INPUT)
3078             {
3079                 pData->param.data[j].type   = PARAMETER_INPUT;
3080                 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
3081                 pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
3082                 pData->param.data[j].hints |= PARAMETER_IS_NOT_SAVED;
3083                 needsCtrlIn = true;
3084 
3085                 if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
3086                     hasPatchParameterOutputs = true;
3087 
3088                 if (LV2_IS_PORT_MIDI_MAP_CC(rdfParam.MidiMap.Type))
3089                 {
3090                     if (rdfParam.MidiMap.Number < MAX_MIDI_CONTROL && ! MIDI_IS_CONTROL_BANK_SELECT(rdfParam.MidiMap.Number))
3091                         pData->param.data[j].mappedControlIndex = static_cast<int16_t>(rdfParam.MidiMap.Number);
3092                 }
3093             }
3094             else if (rdfParam.Flags & LV2_PARAMETER_FLAG_OUTPUT)
3095             {
3096                 pData->param.data[j].type   = PARAMETER_OUTPUT;
3097                 pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
3098                 pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
3099                 needsCtrlOut = true;
3100                 hasPatchParameterOutputs = true;
3101             }
3102 
3103             pData->param.ranges[j].min = min;
3104             pData->param.ranges[j].max = max;
3105             pData->param.ranges[j].def = def;
3106             pData->param.ranges[j].step = step;
3107             pData->param.ranges[j].stepSmall = stepSmall;
3108             pData->param.ranges[j].stepLarge = stepLarge;
3109 
3110             fParamBuffers[j] = def;
3111         }
3112 
3113         if (needsCtrlIn)
3114         {
3115             portName.clear();
3116 
3117             if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
3118             {
3119                 portName  = pData->name;
3120                 portName += ":";
3121             }
3122 
3123             portName += "events-in";
3124             portName.truncate(portNameSize);
3125 
3126             pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
3127 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3128             pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
3129 #endif
3130         }
3131 
3132         if (needsCtrlOut)
3133         {
3134             portName.clear();
3135 
3136             if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
3137             {
3138                 portName  = pData->name;
3139                 portName += ":";
3140             }
3141 
3142             portName += "events-out";
3143             portName.truncate(portNameSize);
3144 
3145             pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
3146         }
3147 
3148         if (fExt.worker != nullptr && fEventsIn.ctrl != nullptr)
3149         {
3150             fAtomBufferWorkerIn.createBuffer(eventBufferSize);
3151             fAtomBufferWorkerResp.createBuffer(eventBufferSize);
3152             fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferWorkerIn.getSize()];
3153         }
3154 
3155         if (fRdfDescriptor->ParameterCount > 0 ||
3156             (fUI.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
3157             fAtomBufferEvIn.createBuffer(eventBufferSize);
3158 
3159         if (hasPatchParameterOutputs ||
3160             (fUI.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0))
3161         {
3162             fAtomBufferUiOut.createBuffer(std::min(eventBufferSize*32, 1638400U));
3163             fAtomBufferUiOutTmpData = new uint8_t[fAtomBufferUiOut.getSize()];
3164         }
3165 
3166         if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port == nullptr)
3167             fEventsIn.ctrl->port = pData->event.portIn;
3168 
3169         if (fEventsOut.ctrl != nullptr && fEventsOut.ctrl->port == nullptr)
3170             fEventsOut.ctrl->port = pData->event.portOut;
3171 
3172         if (fEventsIn.ctrl != nullptr && fExt.midnam != nullptr)
3173         {
3174             if (char* const midnam = fExt.midnam->midnam(fHandle))
3175             {
3176                 fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd",
3177                                                   midnam, "text/xml");
3178                 if (fExt.midnam->free != nullptr)
3179                     fExt.midnam->free(midnam);
3180             }
3181         }
3182 
3183         if (forcedStereoIn || forcedStereoOut)
3184             pData->options |= PLUGIN_OPTION_FORCE_STEREO;
3185         else
3186             pData->options &= ~PLUGIN_OPTION_FORCE_STEREO;
3187 
3188         // plugin hints
3189         pData->hints = (pData->hints & PLUGIN_HAS_INLINE_DISPLAY) ? PLUGIN_HAS_INLINE_DISPLAY : 0
3190                      | (pData->hints & PLUGIN_NEEDS_UI_MAIN_THREAD) ? PLUGIN_NEEDS_UI_MAIN_THREAD : 0;
3191 
3192         if (isRealtimeSafe())
3193             pData->hints |= PLUGIN_IS_RTSAFE;
3194 
3195         if (fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty())
3196         {
3197             pData->hints |= PLUGIN_HAS_CUSTOM_UI;
3198 
3199             if (fUI.type == UI::TYPE_EMBED)
3200             {
3201                 switch (fUI.rdfDescriptor->Type)
3202                 {
3203                 case LV2_UI_GTK2:
3204                 case LV2_UI_GTK3:
3205                 case LV2_UI_QT4:
3206                 case LV2_UI_QT5:
3207                 case LV2_UI_EXTERNAL:
3208                 case LV2_UI_OLD_EXTERNAL:
3209                     break;
3210                 default:
3211                     pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI;
3212                     break;
3213                 }
3214             }
3215 
3216             if (fUI.type == UI::TYPE_EMBED || fUI.type == UI::TYPE_EXTERNAL)
3217                 pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
3218         }
3219 
3220         if (LV2_IS_GENERATOR(fRdfDescriptor->Type[0], fRdfDescriptor->Type[1]))
3221             pData->hints |= PLUGIN_IS_SYNTH;
3222 
3223         if (aOuts > 0 && (aIns == aOuts || aIns == 1))
3224             pData->hints |= PLUGIN_CAN_DRYWET;
3225 
3226         if (aOuts > 0)
3227             pData->hints |= PLUGIN_CAN_VOLUME;
3228 
3229         if (aOuts >= 2 && aOuts % 2 == 0)
3230             pData->hints |= PLUGIN_CAN_BALANCE;
3231 
3232         // extra plugin hints
3233         pData->extraHints = 0x0;
3234 
3235         // check initial latency
3236         findInitialLatencyValue(aIns, cvIns, aOuts, cvOuts);
3237 
3238         bufferSizeChanged(pData->engine->getBufferSize());
3239         reloadPrograms(true);
3240 
3241         evIns.clear();
3242         evOuts.clear();
3243 
3244         if (pData->active)
3245             activate();
3246 
3247         carla_debug("CarlaPluginLV2::reload() - end");
3248     }
3249 
findInitialLatencyValue(const uint32_t aIns,const uint32_t cvIns,const uint32_t aOuts,const uint32_t cvOuts) const3250     void findInitialLatencyValue(const uint32_t aIns,
3251                                  const uint32_t cvIns,
3252                                  const uint32_t aOuts,
3253                                  const uint32_t cvOuts) const
3254     {
3255         if (fLatencyIndex < 0)
3256             return;
3257 
3258         // we need to pre-run the plugin so it can update its latency control-port
3259         const uint32_t bufferSize = static_cast<uint32_t>(fLv2Options.nominalBufferSize);
3260 
3261         float tmpIn [( aIns+cvIns  > 0) ?  aIns+cvIns  : 1][bufferSize];
3262         float tmpOut[(aOuts+cvOuts > 0) ? aOuts+cvOuts : 1][bufferSize];
3263 
3264         {
3265             uint32_t i=0;
3266             for (; i < aIns; ++i)
3267             {
3268                 carla_zeroFloats(tmpIn[i], bufferSize);
3269 
3270                 try {
3271                     fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, tmpIn[i]);
3272                 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio input");
3273             }
3274 
3275             for (uint32_t j=0; j < cvIns; ++i, ++j)
3276             {
3277                 carla_zeroFloats(tmpIn[i], bufferSize);
3278 
3279                 try {
3280                     fDescriptor->connect_port(fHandle, pData->cvIn.ports[j].rindex, tmpIn[i]);
3281                 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv input");
3282             }
3283         }
3284 
3285         {
3286             uint32_t i=0;
3287             for (; i < aOuts; ++i)
3288             {
3289                 carla_zeroFloats(tmpOut[i], bufferSize);
3290 
3291                 try {
3292                     fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, tmpOut[i]);
3293                 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio output");
3294             }
3295 
3296             for (uint32_t j=0; j < cvOuts; ++i, ++j)
3297             {
3298                 carla_zeroFloats(tmpOut[i], bufferSize);
3299 
3300                 try {
3301                     fDescriptor->connect_port(fHandle, pData->cvOut.ports[j].rindex, tmpOut[i]);
3302                 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv output");
3303             }
3304         }
3305 
3306         if (fDescriptor->activate != nullptr)
3307         {
3308             try {
3309                 fDescriptor->activate(fHandle);
3310             } CARLA_SAFE_EXCEPTION("LV2 latency activate");
3311         }
3312 
3313         try {
3314             fDescriptor->run(fHandle, bufferSize);
3315         } CARLA_SAFE_EXCEPTION("LV2 latency run");
3316 
3317         if (fDescriptor->deactivate != nullptr)
3318         {
3319             try {
3320                 fDescriptor->deactivate(fHandle);
3321             } CARLA_SAFE_EXCEPTION("LV2 latency deactivate");
3322         }
3323 
3324         // done, let's get the value
3325         if (const uint32_t latency = getLatencyInFrames())
3326         {
3327             pData->client->setLatency(latency);
3328 #ifndef BUILD_BRIDGE
3329             pData->latency.recreateBuffers(std::max(aIns, aOuts), latency);
3330 #endif
3331         }
3332     }
3333 
reloadPrograms(const bool doInit)3334     void reloadPrograms(const bool doInit) override
3335     {
3336         carla_debug("CarlaPluginLV2::reloadPrograms(%s)", bool2str(doInit));
3337         const uint32_t oldCount = pData->midiprog.count;
3338         const int32_t  current  = pData->midiprog.current;
3339 
3340         // special LV2 programs handling
3341         if (doInit)
3342         {
3343             pData->prog.clear();
3344 
3345             const uint32_t presetCount(fRdfDescriptor->PresetCount);
3346 
3347             if (presetCount > 0)
3348             {
3349                 pData->prog.createNew(presetCount);
3350 
3351                 for (uint32_t i=0; i < presetCount; ++i)
3352                     pData->prog.names[i] = carla_strdup(fRdfDescriptor->Presets[i].Label);
3353             }
3354         }
3355 
3356         // Delete old programs
3357         pData->midiprog.clear();
3358 
3359         // Query new programs
3360         uint32_t newCount = 0;
3361         if (fExt.programs != nullptr && fExt.programs->get_program != nullptr && fExt.programs->select_program != nullptr)
3362         {
3363             for (; fExt.programs->get_program(fHandle, newCount);)
3364                 ++newCount;
3365         }
3366 
3367         if (newCount > 0)
3368         {
3369             pData->midiprog.createNew(newCount);
3370 
3371             // Update data
3372             for (uint32_t i=0; i < newCount; ++i)
3373             {
3374                 const LV2_Program_Descriptor* const pdesc(fExt.programs->get_program(fHandle, i));
3375                 CARLA_SAFE_ASSERT_CONTINUE(pdesc != nullptr);
3376                 CARLA_SAFE_ASSERT(pdesc->name != nullptr);
3377 
3378                 pData->midiprog.data[i].bank    = pdesc->bank;
3379                 pData->midiprog.data[i].program = pdesc->program;
3380                 pData->midiprog.data[i].name    = carla_strdup(pdesc->name);
3381             }
3382         }
3383 
3384         if (doInit)
3385         {
3386             if (newCount > 0)
3387             {
3388                 setMidiProgram(0, false, false, false, true);
3389             }
3390             else if (fHasLoadDefaultState)
3391             {
3392                 // load default state
3393                 if (LilvState* const state = Lv2WorldClass::getInstance().getStateFromURI(fDescriptor->URI,
3394                                                                                           (const LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data))
3395                 {
3396                     lilv_state_restore(state, fExt.state, fHandle, carla_lilv_set_port_value, this, 0, fFeatures);
3397 
3398                     if (fHandle2 != nullptr)
3399                         lilv_state_restore(state, fExt.state, fHandle2, carla_lilv_set_port_value, this, 0, fFeatures);
3400 
3401                     lilv_state_free(state);
3402                 }
3403             }
3404         }
3405         else
3406         {
3407             // Check if current program is invalid
3408             bool programChanged = false;
3409 
3410             if (newCount == oldCount+1)
3411             {
3412                 // one midi program added, probably created by user
3413                 pData->midiprog.current = static_cast<int32_t>(oldCount);
3414                 programChanged = true;
3415             }
3416             else if (current < 0 && newCount > 0)
3417             {
3418                 // programs exist now, but not before
3419                 pData->midiprog.current = 0;
3420                 programChanged = true;
3421             }
3422             else if (current >= 0 && newCount == 0)
3423             {
3424                 // programs existed before, but not anymore
3425                 pData->midiprog.current = -1;
3426                 programChanged = true;
3427             }
3428             else if (current >= static_cast<int32_t>(newCount))
3429             {
3430                 // current midi program > count
3431                 pData->midiprog.current = 0;
3432                 programChanged = true;
3433             }
3434             else
3435             {
3436                 // no change
3437                 pData->midiprog.current = current;
3438             }
3439 
3440             if (programChanged)
3441                 setMidiProgram(pData->midiprog.current, true, true, true, false);
3442 
3443             pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
3444         }
3445     }
3446 
3447     // -------------------------------------------------------------------
3448     // Plugin processing
3449 
activate()3450     void activate() noexcept override
3451     {
3452         CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
3453         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
3454 
3455         if (fDescriptor->activate != nullptr)
3456         {
3457             try {
3458                 fDescriptor->activate(fHandle);
3459             } CARLA_SAFE_EXCEPTION("LV2 activate");
3460 
3461             if (fHandle2 != nullptr)
3462             {
3463                 try {
3464                     fDescriptor->activate(fHandle2);
3465                 } CARLA_SAFE_EXCEPTION("LV2 activate #2");
3466             }
3467         }
3468 
3469         fFirstActive = true;
3470     }
3471 
deactivate()3472     void deactivate() noexcept override
3473     {
3474         CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
3475         CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
3476 
3477         if (fDescriptor->deactivate != nullptr)
3478         {
3479             try {
3480                 fDescriptor->deactivate(fHandle);
3481             } CARLA_SAFE_EXCEPTION("LV2 deactivate");
3482 
3483             if (fHandle2 != nullptr)
3484             {
3485                 try {
3486                     fDescriptor->deactivate(fHandle2);
3487                 } CARLA_SAFE_EXCEPTION("LV2 deactivate #2");
3488             }
3489         }
3490     }
3491 
process(const float * const * const audioIn,float ** const audioOut,const float * const * const cvIn,float ** const cvOut,const uint32_t frames)3492     void process(const float* const* const audioIn, float** const audioOut,
3493                  const float* const* const cvIn, float** const cvOut, const uint32_t frames) override
3494     {
3495         // --------------------------------------------------------------------------------------------------------
3496         // Check if active
3497 
3498         if (! pData->active)
3499         {
3500             // disable any output sound
3501             for (uint32_t i=0; i < pData->audioOut.count; ++i)
3502                 carla_zeroFloats(audioOut[i], frames);
3503             for (uint32_t i=0; i < pData->cvOut.count; ++i)
3504                 carla_zeroFloats(cvOut[i], frames);
3505             return;
3506         }
3507 
3508         // --------------------------------------------------------------------------------------------------------
3509         // Event itenerators from different APIs (input)
3510 
3511         LV2_Atom_Buffer_Iterator evInAtomIters[fEventsIn.count];
3512         LV2_Event_Iterator       evInEventIters[fEventsIn.count];
3513         LV2_MIDIState            evInMidiStates[fEventsIn.count];
3514 
3515         for (uint32_t i=0; i < fEventsIn.count; ++i)
3516         {
3517             if (fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM)
3518             {
3519                 lv2_atom_buffer_reset(fEventsIn.data[i].atom, true);
3520                 lv2_atom_buffer_begin(&evInAtomIters[i], fEventsIn.data[i].atom);
3521             }
3522             else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_EVENT)
3523             {
3524                 lv2_event_buffer_reset(fEventsIn.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[i].event->data);
3525                 lv2_event_begin(&evInEventIters[i], fEventsIn.data[i].event);
3526             }
3527             else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
3528             {
3529                 fEventsIn.data[i].midi.event_count = 0;
3530                 fEventsIn.data[i].midi.size        = 0;
3531                 evInMidiStates[i].midi        = &fEventsIn.data[i].midi;
3532                 evInMidiStates[i].frame_count = frames;
3533                 evInMidiStates[i].position    = 0;
3534             }
3535         }
3536 
3537         for (uint32_t i=0; i < fEventsOut.count; ++i)
3538         {
3539             if (fEventsOut.data[i].type & CARLA_EVENT_DATA_ATOM)
3540             {
3541                 lv2_atom_buffer_reset(fEventsOut.data[i].atom, false);
3542             }
3543             else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_EVENT)
3544             {
3545                 lv2_event_buffer_reset(fEventsOut.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[i].event->data);
3546             }
3547             else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
3548             {
3549                 // not needed
3550             }
3551         }
3552 
3553         // --------------------------------------------------------------------------------------------------------
3554         // Check if needs reset
3555 
3556         if (pData->needsReset)
3557         {
3558             if (fEventsIn.ctrl != nullptr && (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) != 0)
3559             {
3560                 const uint32_t j = fEventsIn.ctrlIndex;
3561                 CARLA_ASSERT(j < fEventsIn.count);
3562 
3563                 uint8_t midiData[3] = { 0, 0, 0 };
3564 
3565                 if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
3566                 {
3567                     for (uint8_t i=0; i < MAX_MIDI_CHANNELS; ++i)
3568                     {
3569                         midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
3570                         midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
3571 
3572                         if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3573                             lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3574 
3575                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3576                             lv2_event_write(&evInEventIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3577 
3578                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3579                             lv2midi_put_event(&evInMidiStates[j], 0.0, 3, midiData);
3580 
3581                         midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
3582                         midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
3583 
3584                         if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3585                             lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3586 
3587                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3588                             lv2_event_write(&evInEventIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3589 
3590                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3591                             lv2midi_put_event(&evInMidiStates[j], 0.0, 3, midiData);
3592                     }
3593                 }
3594                 else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
3595                 {
3596                     for (uint8_t k=0; k < MAX_MIDI_NOTE; ++k)
3597                     {
3598                         midiData[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
3599                         midiData[1] = k;
3600 
3601                         if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3602                             lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3603 
3604                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3605                             lv2_event_write(&evInEventIters[j], 0, 0, kUridMidiEvent, 3, midiData);
3606 
3607                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3608                             lv2midi_put_event(&evInMidiStates[j], 0.0, 3, midiData);
3609                     }
3610                 }
3611             }
3612 
3613             pData->needsReset = false;
3614         }
3615 
3616         // --------------------------------------------------------------------------------------------------------
3617         // TimeInfo
3618 
3619         const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
3620 
3621         if (fFirstActive || fLastTimeInfo != timeInfo)
3622         {
3623             bool doPostRt;
3624             int32_t rindex;
3625 
3626             const double barBeat = static_cast<double>(timeInfo.bbt.beat - 1)
3627                                  + (timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat);
3628 
3629             // update input ports
3630             for (uint32_t k=0; k < pData->param.count; ++k)
3631             {
3632                 if (pData->param.data[k].type != PARAMETER_INPUT)
3633                     continue;
3634                 if (pData->param.special[k] != PARAMETER_SPECIAL_TIME)
3635                     continue;
3636 
3637                 doPostRt = false;
3638                 rindex = pData->param.data[k].rindex;
3639 
3640                 CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount));
3641 
3642                 switch (fRdfDescriptor->Ports[rindex].Designation)
3643                 {
3644                 // Non-BBT
3645                 case LV2_PORT_DESIGNATION_TIME_SPEED:
3646                     if (fLastTimeInfo.playing != timeInfo.playing)
3647                     {
3648                         fParamBuffers[k] = timeInfo.playing ? 1.0f : 0.0f;
3649                         doPostRt = true;
3650                     }
3651                     break;
3652 
3653                 case LV2_PORT_DESIGNATION_TIME_FRAME:
3654                     if (fLastTimeInfo.frame != timeInfo.frame)
3655                     {
3656                         fParamBuffers[k] = static_cast<float>(timeInfo.frame);
3657                         doPostRt = true;
3658                     }
3659                     break;
3660 
3661                 case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
3662                     break;
3663 
3664                 // BBT
3665                 case LV2_PORT_DESIGNATION_TIME_BAR:
3666                     if (timeInfo.bbt.valid && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
3667                     {
3668                         fParamBuffers[k] = static_cast<float>(timeInfo.bbt.bar - 1);
3669                         doPostRt = true;
3670                     }
3671                     break;
3672 
3673                 case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
3674                     if (timeInfo.bbt.valid && (carla_isNotEqual(fLastTimeInfo.bbt.tick, timeInfo.bbt.tick) ||
3675                                                fLastTimeInfo.bbt.beat != timeInfo.bbt.beat))
3676                     {
3677                         fParamBuffers[k] = static_cast<float>(barBeat);
3678                         doPostRt = true;
3679                     }
3680                     break;
3681 
3682                 case LV2_PORT_DESIGNATION_TIME_BEAT:
3683                     if (timeInfo.bbt.valid && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
3684                     {
3685                         fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beat - 1);
3686                         doPostRt = true;
3687                     }
3688                     break;
3689 
3690                 case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
3691                     if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatType, timeInfo.bbt.beatType))
3692                     {
3693                         fParamBuffers[k] = timeInfo.bbt.beatType;
3694                         doPostRt = true;
3695                     }
3696                     break;
3697                 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
3698                     if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerBar, timeInfo.bbt.beatsPerBar))
3699                     {
3700                         fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
3701                         doPostRt = true;
3702                     }
3703                     break;
3704 
3705                 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
3706                     if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.beatsPerMinute, timeInfo.bbt.beatsPerMinute))
3707                     {
3708                         fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beatsPerMinute);
3709                         doPostRt = true;
3710                     }
3711                     break;
3712 
3713                 case LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT:
3714                     if (timeInfo.bbt.valid && carla_isNotEqual(fLastTimeInfo.bbt.ticksPerBeat, timeInfo.bbt.ticksPerBeat))
3715                     {
3716                         fParamBuffers[k] = static_cast<float>(timeInfo.bbt.ticksPerBeat);
3717                         doPostRt = true;
3718                     }
3719                     break;
3720                 }
3721 
3722                 if (doPostRt)
3723                     pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
3724             }
3725 
3726             for (uint32_t i=0; i < fEventsIn.count; ++i)
3727             {
3728                 if ((fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM) == 0 || (fEventsIn.data[i].type & CARLA_EVENT_TYPE_TIME) == 0)
3729                     continue;
3730 
3731                 uint8_t timeInfoBuf[256];
3732                 LV2_Atom_Forge atomForge;
3733                 initAtomForge(atomForge);
3734                 lv2_atom_forge_set_buffer(&atomForge, timeInfoBuf, sizeof(timeInfoBuf));
3735 
3736                 LV2_Atom_Forge_Frame forgeFrame;
3737                 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridTimePosition);
3738 
3739                 lv2_atom_forge_key(&atomForge, kUridTimeSpeed);
3740                 lv2_atom_forge_float(&atomForge, timeInfo.playing ? 1.0f : 0.0f);
3741 
3742                 lv2_atom_forge_key(&atomForge, kUridTimeFrame);
3743                 lv2_atom_forge_long(&atomForge, static_cast<int64_t>(timeInfo.frame));
3744 
3745                 if (timeInfo.bbt.valid)
3746                 {
3747                     lv2_atom_forge_key(&atomForge, kUridTimeBar);
3748                     lv2_atom_forge_long(&atomForge, timeInfo.bbt.bar - 1);
3749 
3750                     lv2_atom_forge_key(&atomForge, kUridTimeBarBeat);
3751                     lv2_atom_forge_float(&atomForge, static_cast<float>(barBeat));
3752 
3753                     lv2_atom_forge_key(&atomForge, kUridTimeBeat);
3754                     lv2_atom_forge_double(&atomForge, timeInfo.bbt.beat - 1);
3755 
3756                     lv2_atom_forge_key(&atomForge, kUridTimeBeatUnit);
3757                     lv2_atom_forge_int(&atomForge, static_cast<int32_t>(timeInfo.bbt.beatType));
3758 
3759                     lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerBar);
3760                     lv2_atom_forge_float(&atomForge, timeInfo.bbt.beatsPerBar);
3761 
3762                     lv2_atom_forge_key(&atomForge, kUridTimeBeatsPerMinute);
3763                     lv2_atom_forge_float(&atomForge, static_cast<float>(timeInfo.bbt.beatsPerMinute));
3764 
3765                     lv2_atom_forge_key(&atomForge, kUridTimeTicksPerBeat);
3766                     lv2_atom_forge_double(&atomForge, timeInfo.bbt.ticksPerBeat);
3767                 }
3768 
3769                 lv2_atom_forge_pop(&atomForge, &forgeFrame);
3770 
3771                 LV2_Atom* const atom((LV2_Atom*)timeInfoBuf);
3772                 CARLA_SAFE_ASSERT_BREAK(atom->size < 256);
3773 
3774                 // send only deprecated blank object for now
3775                 lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, kUridAtomBlank, atom->size, LV2_ATOM_BODY_CONST(atom));
3776 
3777                 // for atom:object
3778                 //lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom));
3779             }
3780 
3781             pData->postRtEvents.trySplice();
3782 
3783             fLastTimeInfo = timeInfo;
3784         }
3785 
3786         // --------------------------------------------------------------------------------------------------------
3787         // Event Input and Processing
3788 
3789         if (fEventsIn.ctrl != nullptr)
3790         {
3791             // ----------------------------------------------------------------------------------------------------
3792             // Message Input
3793 
3794             if (fAtomBufferEvIn.tryLock())
3795             {
3796                 if (fAtomBufferEvIn.isDataAvailableForReading())
3797                 {
3798                     const LV2_Atom* atom;
3799                     uint32_t j, portIndex;
3800 
3801                     for (; fAtomBufferEvIn.get(atom, portIndex);)
3802                     {
3803                         j = (portIndex < fEventsIn.count) ? portIndex : fEventsIn.ctrlIndex;
3804 
3805                         if (! lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)))
3806                         {
3807                             carla_stderr2("Event input buffer full, at least 1 message lost");
3808                             continue;
3809                         }
3810 
3811                         inspectAtomForParameterChange(atom);
3812                     }
3813                 }
3814 
3815                 fAtomBufferEvIn.unlock();
3816             }
3817 
3818             // ----------------------------------------------------------------------------------------------------
3819             // MIDI Input (External)
3820 
3821             if (pData->extNotes.mutex.tryLock())
3822             {
3823                 if ((fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) == 0)
3824                 {
3825                     // does not handle MIDI
3826                     pData->extNotes.data.clear();
3827                 }
3828                 else
3829                 {
3830                     const uint32_t j = fEventsIn.ctrlIndex;
3831 
3832                     for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
3833                     {
3834                         const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
3835                         CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
3836 
3837                         uint8_t midiEvent[3];
3838                         midiEvent[0] = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
3839                         midiEvent[1] = note.note;
3840                         midiEvent[2] = note.velo;
3841 
3842                         if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
3843                             lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, kUridMidiEvent, 3, midiEvent);
3844 
3845                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
3846                             lv2_event_write(&evInEventIters[j], 0, 0, kUridMidiEvent, 3, midiEvent);
3847 
3848                         else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
3849                             lv2midi_put_event(&evInMidiStates[j], 0.0, 3, midiEvent);
3850                     }
3851 
3852                     pData->extNotes.data.clear();
3853                 }
3854 
3855                 pData->extNotes.mutex.unlock();
3856 
3857             } // End of MIDI Input (External)
3858 
3859             // ----------------------------------------------------------------------------------------------------
3860             // Event Input (System)
3861 
3862 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3863             bool allNotesOffSent  = false;
3864 #endif
3865             bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
3866 
3867             uint32_t startTime  = 0;
3868             uint32_t timeOffset = 0;
3869             uint32_t nextBankId;
3870 
3871             if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
3872                 nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
3873             else
3874                 nextBankId = 0;
3875 
3876 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3877             if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr)
3878                 pData->event.cvSourcePorts->initPortBuffers(cvIn + pData->cvIn.count, frames, isSampleAccurate, pData->event.portIn);
3879 #endif
3880 
3881             const uint32_t numEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
3882 
3883             for (uint32_t i=0; i < numEvents; ++i)
3884             {
3885                 EngineEvent& event(fEventsIn.ctrl->port->getEvent(i));
3886 
3887                 uint32_t eventTime = event.time;
3888                 CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime < frames, eventTime, frames);
3889 
3890                 if (eventTime < timeOffset)
3891                 {
3892                     carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
3893                                   eventTime, timeOffset, pData->name);
3894                     eventTime = timeOffset;
3895                 }
3896 
3897                 if (isSampleAccurate && eventTime > timeOffset)
3898                 {
3899                     if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset))
3900                     {
3901                         startTime  = 0;
3902                         timeOffset = eventTime;
3903 
3904                         if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
3905                             nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
3906                         else
3907                             nextBankId = 0;
3908 
3909                         for (uint32_t j=0; j < fEventsIn.count; ++j)
3910                         {
3911                             if (fEventsIn.data[j].type & CARLA_EVENT_DATA_ATOM)
3912                             {
3913                                 lv2_atom_buffer_reset(fEventsIn.data[j].atom, true);
3914                                 lv2_atom_buffer_begin(&evInAtomIters[j], fEventsIn.data[j].atom);
3915                             }
3916                             else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_EVENT)
3917                             {
3918                                 lv2_event_buffer_reset(fEventsIn.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[j].event->data);
3919                                 lv2_event_begin(&evInEventIters[j], fEventsIn.data[j].event);
3920                             }
3921                             else if (fEventsIn.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
3922                             {
3923                                 fEventsIn.data[j].midi.event_count = 0;
3924                                 fEventsIn.data[j].midi.size        = 0;
3925                                 evInMidiStates[j].position         = eventTime;
3926                             }
3927                         }
3928 
3929                         for (uint32_t j=0; j < fEventsOut.count; ++j)
3930                         {
3931                             if (fEventsOut.data[j].type & CARLA_EVENT_DATA_ATOM)
3932                             {
3933                                 lv2_atom_buffer_reset(fEventsOut.data[j].atom, false);
3934                             }
3935                             else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_EVENT)
3936                             {
3937                                 lv2_event_buffer_reset(fEventsOut.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[j].event->data);
3938                             }
3939                             else if (fEventsOut.data[j].type & CARLA_EVENT_DATA_MIDI_LL)
3940                             {
3941                                 // not needed
3942                             }
3943                         }
3944                     }
3945                     else
3946                     {
3947                         startTime += timeOffset;
3948                     }
3949                 }
3950 
3951                 switch (event.type)
3952                 {
3953                 case kEngineEventTypeNull:
3954                     break;
3955 
3956                 case kEngineEventTypeControl: {
3957                     EngineControlEvent& ctrlEvent(event.ctrl);
3958 
3959                     switch (ctrlEvent.type)
3960                     {
3961                     case kEngineControlEventTypeNull:
3962                         break;
3963 
3964                     case kEngineControlEventTypeParameter: {
3965                         float value;
3966 
3967 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3968                         // non-midi
3969                         if (event.channel == kEngineEventNonMidiChannel)
3970                         {
3971                             const uint32_t k = ctrlEvent.param;
3972                             CARLA_SAFE_ASSERT_CONTINUE(k < pData->param.count);
3973 
3974                             ctrlEvent.handled = true;
3975                             value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
3976                             setParameterValueRT(k, value, true);
3977                             continue;
3978                         }
3979 
3980                         // Control backend stuff
3981                         if (event.channel == pData->ctrlChannel)
3982                         {
3983                             if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
3984                             {
3985                                 ctrlEvent.handled = true;
3986                                 value = ctrlEvent.normalizedValue;
3987                                 setDryWetRT(value, true);
3988                             }
3989                             else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
3990                             {
3991                                 ctrlEvent.handled = true;
3992                                 value = ctrlEvent.normalizedValue*127.0f/100.0f;
3993                                 setVolumeRT(value, true);
3994                             }
3995                             else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
3996                             {
3997                                 float left, right;
3998                                 value = ctrlEvent.normalizedValue/0.5f - 1.0f;
3999 
4000                                 if (value < 0.0f)
4001                                 {
4002                                     left  = -1.0f;
4003                                     right = (value*2.0f)+1.0f;
4004                                 }
4005                                 else if (value > 0.0f)
4006                                 {
4007                                     left  = (value*2.0f)-1.0f;
4008                                     right = 1.0f;
4009                                 }
4010                                 else
4011                                 {
4012                                     left  = -1.0f;
4013                                     right = 1.0f;
4014                                 }
4015 
4016                                 ctrlEvent.handled = true;
4017                                 setBalanceLeftRT(left, true);
4018                                 setBalanceRightRT(right, true);
4019                             }
4020                         }
4021 #endif
4022                         // Control plugin parameters
4023                         uint32_t k;
4024                         for (k=0; k < pData->param.count; ++k)
4025                         {
4026                             if (pData->param.data[k].midiChannel != event.channel)
4027                                 continue;
4028                             if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
4029                                 continue;
4030                             if (pData->param.data[k].type != PARAMETER_INPUT)
4031                                 continue;
4032                             if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
4033                                 continue;
4034 
4035                             ctrlEvent.handled = true;
4036 
4037                             if (pData->param.data[k].mappedFlags & PARAMETER_MAPPING_MIDI_DELTA)
4038                                 value = pData->param.getFinalValueWithMidiDelta(k, fParamBuffers[k], ctrlEvent.midiValue);
4039                             else
4040                                 value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
4041 
4042                             setParameterValueRT(k, value, true);
4043                         }
4044 
4045                         if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
4046                         {
4047                             uint8_t midiData[3];
4048                             midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4049                             midiData[1] = uint8_t(ctrlEvent.param);
4050                             midiData[2] = uint8_t(ctrlEvent.normalizedValue*127.0f);
4051 
4052                             const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4053 
4054                             if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4055                                 lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4056 
4057                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4058                                 lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4059 
4060                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4061                                 lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
4062                         }
4063 
4064 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4065                         if (! ctrlEvent.handled)
4066                             checkForMidiLearn(event);
4067 #endif
4068                         break;
4069                     } // case kEngineControlEventTypeParameter
4070 
4071                     case kEngineControlEventTypeMidiBank:
4072                         if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
4073                         {
4074                             if (event.channel == pData->ctrlChannel)
4075                                 nextBankId = ctrlEvent.param;
4076                         }
4077                         else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
4078                         {
4079                             uint8_t midiData[3];
4080                             midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4081                             midiData[1] = MIDI_CONTROL_BANK_SELECT;
4082                             midiData[2] = uint8_t(ctrlEvent.param);
4083 
4084                             const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4085 
4086                             if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4087                                 lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4088 
4089                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4090                                 lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4091 
4092                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4093                                 lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
4094                         }
4095                         break;
4096 
4097                     case kEngineControlEventTypeMidiProgram:
4098                         if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
4099                         {
4100                             if (event.channel == pData->ctrlChannel)
4101                             {
4102                                 const uint32_t nextProgramId(ctrlEvent.param);
4103 
4104                                 for (uint32_t k=0; k < pData->midiprog.count; ++k)
4105                                 {
4106                                     if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
4107                                     {
4108                                         setMidiProgramRT(k, true);
4109                                         break;
4110                                     }
4111                                 }
4112                             }
4113                         }
4114                         else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
4115                         {
4116                             uint8_t midiData[2];
4117                             midiData[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4118                             midiData[1] = uint8_t(ctrlEvent.param);
4119 
4120                             const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4121 
4122                             if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4123                                 lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 2, midiData);
4124 
4125                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4126                                 lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 2, midiData);
4127 
4128                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4129                                 lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 2, midiData);
4130                         }
4131                         break;
4132 
4133                     case kEngineControlEventTypeAllSoundOff:
4134                         if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
4135                         {
4136                             const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4137 
4138                             uint8_t midiData[3];
4139                             midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4140                             midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
4141                             midiData[2] = 0;
4142 
4143                             if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4144                                 lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4145 
4146                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4147                                 lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4148 
4149                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4150                                 lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
4151                         }
4152                         break;
4153 
4154                     case kEngineControlEventTypeAllNotesOff:
4155                         if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
4156                         {
4157 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4158                             if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
4159                             {
4160                                 allNotesOffSent = true;
4161                                 postponeRtAllNotesOff();
4162                             }
4163 #endif
4164 
4165                             const uint32_t mtime(isSampleAccurate ? startTime : eventTime);
4166 
4167                             uint8_t midiData[3];
4168                             midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
4169                             midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
4170                             midiData[2] = 0;
4171 
4172                             if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4173                                 lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4174 
4175                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4176                                 lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, kUridMidiEvent, 3, midiData);
4177 
4178                             else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4179                                 lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
4180                         }
4181                         break;
4182                     } // switch (ctrlEvent.type)
4183                     break;
4184                 } // case kEngineEventTypeControl
4185 
4186                 case kEngineEventTypeMidi: {
4187                     const EngineMidiEvent& midiEvent(event.midi);
4188 
4189                     const uint8_t* const midiData(midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data);
4190 
4191                     uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
4192 
4193                     if ((status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON) && (pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES))
4194                         continue;
4195                     if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
4196                         continue;
4197                     if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
4198                         continue;
4199                     if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
4200                         continue;
4201                     if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
4202                         continue;
4203 
4204                     // Fix bad note-off (per LV2 spec)
4205                     if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
4206                         status = MIDI_STATUS_NOTE_OFF;
4207 
4208                     const uint32_t j     = fEventsIn.ctrlIndex;
4209                     const uint32_t mtime = isSampleAccurate ? startTime : eventTime;
4210 
4211                     // put back channel in data
4212                     uint8_t midiData2[midiEvent.size];
4213                     midiData2[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT));
4214                     std::memcpy(midiData2+1, midiData+1, static_cast<std::size_t>(midiEvent.size-1));
4215 
4216                     if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
4217                         lv2_atom_buffer_write(&evInAtomIters[j], mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
4218 
4219                     else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
4220                         lv2_event_write(&evInEventIters[j], mtime, 0, kUridMidiEvent, midiEvent.size, midiData2);
4221 
4222                     else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
4223                         lv2midi_put_event(&evInMidiStates[j], mtime, midiEvent.size, midiData2);
4224 
4225                     if (status == MIDI_STATUS_NOTE_ON)
4226                     {
4227                         pData->postponeNoteOnRtEvent(true, event.channel, midiData[1], midiData[2]);
4228                     }
4229                     else if (status == MIDI_STATUS_NOTE_OFF)
4230                     {
4231                         pData->postponeNoteOffRtEvent(true, event.channel, midiData[1]);
4232                     }
4233                 } break;
4234                 } // switch (event.type)
4235             }
4236 
4237             pData->postRtEvents.trySplice();
4238 
4239             if (frames > timeOffset)
4240                 processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset);
4241 
4242         } // End of Event Input and Processing
4243 
4244         // --------------------------------------------------------------------------------------------------------
4245         // Plugin processing (no events)
4246 
4247         else
4248         {
4249             processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0);
4250 
4251         } // End of Plugin processing (no events)
4252 
4253         // --------------------------------------------------------------------------------------------------------
4254         // Final work
4255 
4256         if (fEventsIn.ctrl != nullptr && fExt.worker != nullptr && fAtomBufferWorkerResp.tryLock())
4257         {
4258             if (fAtomBufferWorkerResp.isDataAvailableForReading())
4259             {
4260                 const LV2_Atom* atom;
4261                 uint32_t portIndex;
4262 
4263                 for (; fAtomBufferWorkerResp.get(atom, portIndex);)
4264                 {
4265                     CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerResp);
4266                     fExt.worker->work_response(fHandle, atom->size, LV2_ATOM_BODY_CONST(atom));
4267                 }
4268             }
4269 
4270             fAtomBufferWorkerResp.unlock();
4271         }
4272 
4273         if (fExt.worker != nullptr && fExt.worker->end_run != nullptr)
4274         {
4275             fExt.worker->end_run(fHandle);
4276 
4277             if (fHandle2 != nullptr)
4278                 fExt.worker->end_run(fHandle2);
4279         }
4280 
4281         // --------------------------------------------------------------------------------------------------------
4282         // Events/MIDI Output
4283 
4284         for (uint32_t i=0; i < fEventsOut.count; ++i)
4285         {
4286             uint32_t lastFrame = 0;
4287             Lv2EventData& evData(fEventsOut.data[i]);
4288 
4289             if (evData.type & CARLA_EVENT_DATA_ATOM)
4290             {
4291                 const LV2_Atom_Event* ev;
4292                 LV2_Atom_Buffer_Iterator iter;
4293 
4294                 uint8_t* data;
4295                 lv2_atom_buffer_begin(&iter, evData.atom);
4296 
4297                 for (;;)
4298                 {
4299                     data = nullptr;
4300                     ev = lv2_atom_buffer_get(&iter, &data);
4301 
4302                     if (ev == nullptr || ev->body.size == 0 || data == nullptr)
4303                         break;
4304 
4305                     if (ev->body.type == kUridMidiEvent)
4306                     {
4307                         if (evData.port != nullptr)
4308                         {
4309                             CARLA_SAFE_ASSERT_CONTINUE(ev->time.frames >= 0);
4310                             CARLA_SAFE_ASSERT_CONTINUE(ev->body.size < 0xFF);
4311 
4312                             uint32_t currentFrame = static_cast<uint32_t>(ev->time.frames);
4313                             if (currentFrame < lastFrame)
4314                                 currentFrame = lastFrame;
4315                             else if (currentFrame >= frames)
4316                                 currentFrame = frames - 1;
4317 
4318                             evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->body.size), data);
4319                         }
4320                     }
4321                     else if (fAtomBufferUiOutTmpData != nullptr)
4322                     {
4323                         fAtomBufferUiOut.put(&ev->body, evData.rindex);
4324                     }
4325 
4326                     lv2_atom_buffer_increment(&iter);
4327                 }
4328             }
4329             else if ((evData.type & CARLA_EVENT_DATA_EVENT) != 0 && evData.port != nullptr)
4330             {
4331                 const LV2_Event* ev;
4332                 LV2_Event_Iterator iter;
4333 
4334                 uint8_t* data;
4335                 lv2_event_begin(&iter, evData.event);
4336 
4337                 for (;;)
4338                 {
4339                     data = nullptr;
4340                     ev = lv2_event_get(&iter, &data);
4341 
4342                     if (ev == nullptr || data == nullptr)
4343                         break;
4344 
4345                     uint32_t currentFrame = ev->frames;
4346                     if (currentFrame < lastFrame)
4347                         currentFrame = lastFrame;
4348                     else if (currentFrame >= frames)
4349                         currentFrame = frames - 1;
4350 
4351                     if (ev->type == kUridMidiEvent)
4352                     {
4353                         CARLA_SAFE_ASSERT_CONTINUE(ev->size < 0xFF);
4354                         evData.port->writeMidiEvent(currentFrame, static_cast<uint8_t>(ev->size), data);
4355                     }
4356 
4357                     lv2_event_increment(&iter);
4358                 }
4359             }
4360             else if ((evData.type & CARLA_EVENT_DATA_MIDI_LL) != 0 && evData.port != nullptr)
4361             {
4362                 LV2_MIDIState state = { &evData.midi, frames, 0 };
4363 
4364                 uint32_t eventSize;
4365                 double   eventTime;
4366                 uchar* eventData;
4367 
4368                 for (;;)
4369                 {
4370                     eventSize = 0;
4371                     eventTime = 0.0;
4372                     eventData = nullptr;
4373                     lv2midi_get_event(&state, &eventTime, &eventSize, &eventData);
4374 
4375                     if (eventData == nullptr || eventSize == 0)
4376                         break;
4377 
4378                     CARLA_SAFE_ASSERT_CONTINUE(eventSize < 0xFF);
4379                     CARLA_SAFE_ASSERT_CONTINUE(eventTime >= 0.0);
4380 
4381                     evData.port->writeMidiEvent(static_cast<uint32_t>(eventTime), static_cast<uint8_t>(eventSize), eventData);
4382                     lv2midi_step(&state);
4383                 }
4384             }
4385         }
4386 
4387 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4388         // --------------------------------------------------------------------------------------------------------
4389         // Control Output
4390 
4391         if (pData->event.portOut != nullptr)
4392         {
4393             uint8_t  channel;
4394             uint16_t param;
4395             float    value;
4396 
4397             for (uint32_t k=0; k < pData->param.count; ++k)
4398             {
4399                 if (pData->param.data[k].type != PARAMETER_OUTPUT)
4400                     continue;
4401 
4402                 if (fStrictBounds >= 0 && (pData->param.data[k].hints & PARAMETER_IS_STRICT_BOUNDS) != 0)
4403                     // plugin is responsible to ensure correct bounds
4404                     pData->param.ranges[k].fixValue(fParamBuffers[k]);
4405 
4406                 if (pData->param.data[k].mappedControlIndex > 0)
4407                 {
4408                     channel = pData->param.data[k].midiChannel;
4409                     param   = static_cast<uint16_t>(pData->param.data[k].mappedControlIndex);
4410                     value   = pData->param.ranges[k].getNormalizedValue(fParamBuffers[k]);
4411                     pData->event.portOut->writeControlEvent(0, channel, kEngineControlEventTypeParameter,
4412                                                             param, -1, value);
4413                 }
4414             }
4415         } // End of Control Output
4416 #endif
4417 
4418         fFirstActive = false;
4419 
4420         // --------------------------------------------------------------------------------------------------------
4421     }
4422 
processSingle(const float * const * const audioIn,float ** const audioOut,const float * const * const cvIn,float ** const cvOut,const uint32_t frames,const uint32_t timeOffset)4423     bool processSingle(const float* const* const audioIn, float** const audioOut,
4424                        const float* const* const cvIn, float** const cvOut,
4425                        const uint32_t frames, const uint32_t timeOffset)
4426     {
4427         CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
4428 
4429         if (pData->audioIn.count > 0)
4430         {
4431             CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
4432             CARLA_SAFE_ASSERT_RETURN(fAudioInBuffers != nullptr, false);
4433         }
4434         if (pData->audioOut.count > 0)
4435         {
4436             CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false);
4437             CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false);
4438         }
4439         if (pData->cvIn.count > 0)
4440         {
4441             CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false);
4442         }
4443         if (pData->cvOut.count > 0)
4444         {
4445             CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false);
4446         }
4447 
4448         // --------------------------------------------------------------------------------------------------------
4449         // Try lock, silence otherwise
4450 
4451 #ifndef STOAT_TEST_BUILD
4452         if (pData->engine->isOffline())
4453         {
4454             pData->singleMutex.lock();
4455         }
4456         else
4457 #endif
4458         if (! pData->singleMutex.tryLock())
4459         {
4460             for (uint32_t i=0; i < pData->audioOut.count; ++i)
4461             {
4462                 for (uint32_t k=0; k < frames; ++k)
4463                     audioOut[i][k+timeOffset] = 0.0f;
4464             }
4465             for (uint32_t i=0; i < pData->cvOut.count; ++i)
4466             {
4467                 for (uint32_t k=0; k < frames; ++k)
4468                     cvOut[i][k+timeOffset] = 0.0f;
4469             }
4470 
4471             return false;
4472         }
4473 
4474         // --------------------------------------------------------------------------------------------------------
4475         // Set audio buffers
4476 
4477         for (uint32_t i=0; i < pData->audioIn.count; ++i)
4478             carla_copyFloats(fAudioInBuffers[i], audioIn[i]+timeOffset, frames);
4479 
4480         for (uint32_t i=0; i < pData->audioOut.count; ++i)
4481             carla_zeroFloats(fAudioOutBuffers[i], frames);
4482 
4483         // --------------------------------------------------------------------------------------------------------
4484         // Set CV buffers
4485 
4486         for (uint32_t i=0; i < pData->cvIn.count; ++i)
4487             carla_copyFloats(fCvInBuffers[i], cvIn[i]+timeOffset, frames);
4488 
4489         for (uint32_t i=0; i < pData->cvOut.count; ++i)
4490             carla_zeroFloats(fCvOutBuffers[i], frames);
4491 
4492         // --------------------------------------------------------------------------------------------------------
4493         // Run plugin
4494 
4495         fDescriptor->run(fHandle, frames);
4496 
4497         if (fHandle2 != nullptr)
4498             fDescriptor->run(fHandle2, frames);
4499 
4500         // --------------------------------------------------------------------------------------------------------
4501         // Handle trigger parameters
4502 
4503         for (uint32_t k=0; k < pData->param.count; ++k)
4504         {
4505             if (pData->param.data[k].type != PARAMETER_INPUT)
4506                 continue;
4507 
4508             if (pData->param.data[k].hints & PARAMETER_IS_TRIGGER)
4509             {
4510                 if (carla_isNotEqual(fParamBuffers[k], pData->param.ranges[k].def))
4511                 {
4512                     fParamBuffers[k] = pData->param.ranges[k].def;
4513                     pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4514                 }
4515             }
4516         }
4517 
4518         pData->postRtEvents.trySplice();
4519 
4520 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4521         // --------------------------------------------------------------------------------------------------------
4522         // Post-processing (dry/wet, volume and balance)
4523 
4524         {
4525             const bool doDryWet  = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
4526             const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
4527             const bool isMono    = (pData->audioIn.count == 1);
4528 
4529             bool isPair;
4530             float bufValue, oldBufLeft[doBalance ? frames : 1];
4531 
4532             for (uint32_t i=0; i < pData->audioOut.count; ++i)
4533             {
4534                 // Dry/Wet
4535                 if (doDryWet)
4536                 {
4537                     const uint32_t c = isMono ? 0 : i;
4538 
4539                     for (uint32_t k=0; k < frames; ++k)
4540                     {
4541 # ifndef BUILD_BRIDGE
4542                         if (k < pData->latency.frames && pData->latency.buffers != nullptr)
4543                             bufValue = pData->latency.buffers[c][k];
4544                         else if (pData->latency.frames < frames)
4545                             bufValue = fAudioInBuffers[c][k-pData->latency.frames];
4546                         else
4547 # endif
4548                             bufValue = fAudioInBuffers[c][k];
4549 
4550                         fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
4551                     }
4552                 }
4553 
4554                 // Balance
4555                 if (doBalance)
4556                 {
4557                     isPair = (i % 2 == 0);
4558 
4559                     if (isPair)
4560                     {
4561                         CARLA_ASSERT(i+1 < pData->audioOut.count);
4562                         carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames);
4563                     }
4564 
4565                     float balRangeL = (pData->postProc.balanceLeft  + 1.0f)/2.0f;
4566                     float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
4567 
4568                     for (uint32_t k=0; k < frames; ++k)
4569                     {
4570                         if (isPair)
4571                         {
4572                             // left
4573                             fAudioOutBuffers[i][k]  = oldBufLeft[k]            * (1.0f - balRangeL);
4574                             fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
4575                         }
4576                         else
4577                         {
4578                             // right
4579                             fAudioOutBuffers[i][k]  = fAudioOutBuffers[i][k] * balRangeR;
4580                             fAudioOutBuffers[i][k] += oldBufLeft[k]          * balRangeL;
4581                         }
4582                     }
4583                 }
4584 
4585                 // Volume (and buffer copy)
4586                 {
4587                     for (uint32_t k=0; k < frames; ++k)
4588                         audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume;
4589                 }
4590             }
4591         } // End of Post-processing
4592 
4593 # ifndef BUILD_BRIDGE
4594         // --------------------------------------------------------------------------------------------------------
4595         // Save latency values for next callback
4596 
4597         if (pData->latency.frames != 0 && pData->latency.buffers != nullptr)
4598         {
4599             CARLA_SAFE_ASSERT(timeOffset == 0);
4600             const uint32_t latframes = pData->latency.frames;
4601 
4602             if (latframes <= frames)
4603             {
4604                 for (uint32_t i=0; i < pData->audioIn.count; ++i)
4605                     carla_copyFloats(pData->latency.buffers[i], audioIn[i]+(frames-latframes), latframes);
4606             }
4607             else
4608             {
4609                 const uint32_t diff = latframes - frames;
4610 
4611                 for (uint32_t i=0, k; i<pData->audioIn.count; ++i)
4612                 {
4613                     // push back buffer by 'frames'
4614                     for (k=0; k < diff; ++k)
4615                         pData->latency.buffers[i][k] = pData->latency.buffers[i][k+frames];
4616 
4617                     // put current input at the end
4618                     for (uint32_t j=0; k < latframes; ++j, ++k)
4619                         pData->latency.buffers[i][k] = audioIn[i][j];
4620                 }
4621             }
4622         }
4623 # endif
4624 #else // BUILD_BRIDGE_ALTERNATIVE_ARCH
4625         for (uint32_t i=0; i < pData->audioOut.count; ++i)
4626         {
4627             for (uint32_t k=0; k < frames; ++k)
4628                 audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k];
4629         }
4630 #endif
4631 
4632         for (uint32_t i=0; i < pData->cvOut.count; ++i)
4633         {
4634             for (uint32_t k=0; k < frames; ++k)
4635                 cvOut[i][k+timeOffset] = fCvOutBuffers[i][k];
4636         }
4637 
4638         // --------------------------------------------------------------------------------------------------------
4639 
4640         pData->singleMutex.unlock();
4641         return true;
4642     }
4643 
bufferSizeChanged(const uint32_t newBufferSize)4644     void bufferSizeChanged(const uint32_t newBufferSize) override
4645     {
4646         CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
4647         carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - start", newBufferSize);
4648 
4649         for (uint32_t i=0; i < pData->audioIn.count; ++i)
4650         {
4651             if (fAudioInBuffers[i] != nullptr)
4652                 delete[] fAudioInBuffers[i];
4653             fAudioInBuffers[i] = new float[newBufferSize];
4654         }
4655 
4656         for (uint32_t i=0; i < pData->audioOut.count; ++i)
4657         {
4658             if (fAudioOutBuffers[i] != nullptr)
4659                 delete[] fAudioOutBuffers[i];
4660             fAudioOutBuffers[i] = new float[newBufferSize];
4661         }
4662 
4663         if (fHandle2 == nullptr)
4664         {
4665             for (uint32_t i=0; i < pData->audioIn.count; ++i)
4666             {
4667                 CARLA_ASSERT(fAudioInBuffers[i] != nullptr);
4668                 fDescriptor->connect_port(fHandle, pData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
4669             }
4670 
4671             for (uint32_t i=0; i < pData->audioOut.count; ++i)
4672             {
4673                 CARLA_ASSERT(fAudioOutBuffers[i] != nullptr);
4674                 fDescriptor->connect_port(fHandle, pData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
4675             }
4676         }
4677         else
4678         {
4679             if (pData->audioIn.count > 0)
4680             {
4681                 CARLA_ASSERT(pData->audioIn.count == 2);
4682                 CARLA_ASSERT(fAudioInBuffers[0] != nullptr);
4683                 CARLA_ASSERT(fAudioInBuffers[1] != nullptr);
4684 
4685                 fDescriptor->connect_port(fHandle,  pData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
4686                 fDescriptor->connect_port(fHandle2, pData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
4687             }
4688 
4689             if (pData->audioOut.count > 0)
4690             {
4691                 CARLA_ASSERT(pData->audioOut.count == 2);
4692                 CARLA_ASSERT(fAudioOutBuffers[0] != nullptr);
4693                 CARLA_ASSERT(fAudioOutBuffers[1] != nullptr);
4694 
4695                 fDescriptor->connect_port(fHandle,  pData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
4696                 fDescriptor->connect_port(fHandle2, pData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
4697             }
4698         }
4699 
4700         for (uint32_t i=0; i < pData->cvIn.count; ++i)
4701         {
4702             if (fCvInBuffers[i] != nullptr)
4703                 delete[] fCvInBuffers[i];
4704             fCvInBuffers[i] = new float[newBufferSize];
4705 
4706             fDescriptor->connect_port(fHandle, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
4707 
4708             if (fHandle2 != nullptr)
4709                 fDescriptor->connect_port(fHandle2, pData->cvIn.ports[i].rindex, fCvInBuffers[i]);
4710         }
4711 
4712         for (uint32_t i=0; i < pData->cvOut.count; ++i)
4713         {
4714             if (fCvOutBuffers[i] != nullptr)
4715                 delete[] fCvOutBuffers[i];
4716             fCvOutBuffers[i] = new float[newBufferSize];
4717 
4718             fDescriptor->connect_port(fHandle, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
4719 
4720             if (fHandle2 != nullptr)
4721                 fDescriptor->connect_port(fHandle2, pData->cvOut.ports[i].rindex, fCvOutBuffers[i]);
4722         }
4723 
4724         const int newBufferSizeInt(static_cast<int>(newBufferSize));
4725 
4726         if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt))
4727         {
4728             fLv2Options.maxBufferSize = fLv2Options.nominalBufferSize = newBufferSizeInt;
4729 
4730             if (fLv2Options.minBufferSize != 1)
4731                 fLv2Options.minBufferSize = newBufferSizeInt;
4732 
4733             if (fExt.options != nullptr && fExt.options->set != nullptr)
4734             {
4735                 LV2_Options_Option options[4];
4736                 carla_zeroStructs(options, 4);
4737 
4738                 carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::MaxBlockLenth]);
4739                 carla_copyStruct(options[1], fLv2Options.opts[CarlaPluginLV2Options::NominalBlockLenth]);
4740 
4741                 if (fLv2Options.minBufferSize != 1)
4742                     carla_copyStruct(options[2], fLv2Options.opts[CarlaPluginLV2Options::MinBlockLenth]);
4743 
4744                 fExt.options->set(fHandle, options);
4745             }
4746         }
4747 
4748         carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - end", newBufferSize);
4749     }
4750 
sampleRateChanged(const double newSampleRate)4751     void sampleRateChanged(const double newSampleRate) override
4752     {
4753         CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
4754         carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - start", newSampleRate);
4755 
4756         const float sampleRatef = static_cast<float>(newSampleRate);
4757 
4758         if (carla_isNotEqual(fLv2Options.sampleRate, sampleRatef))
4759         {
4760             fLv2Options.sampleRate = sampleRatef;
4761 
4762             if (fExt.options != nullptr && fExt.options->set != nullptr)
4763             {
4764                 LV2_Options_Option options[2];
4765                 carla_copyStruct(options[0], fLv2Options.opts[CarlaPluginLV2Options::SampleRate]);
4766                 carla_zeroStruct(options[1]);
4767 
4768                 fExt.options->set(fHandle, options);
4769             }
4770         }
4771 
4772         for (uint32_t k=0; k < pData->param.count; ++k)
4773         {
4774             if (pData->param.data[k].type != PARAMETER_INPUT)
4775                 continue;
4776             if (pData->param.special[k] != PARAMETER_SPECIAL_SAMPLE_RATE)
4777                 continue;
4778 
4779             fParamBuffers[k] = sampleRatef;
4780             pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4781             break;
4782         }
4783 
4784         carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - end", newSampleRate);
4785     }
4786 
offlineModeChanged(const bool isOffline)4787     void offlineModeChanged(const bool isOffline) override
4788     {
4789         for (uint32_t k=0; k < pData->param.count; ++k)
4790         {
4791             if (pData->param.data[k].type == PARAMETER_INPUT && pData->param.special[k] == PARAMETER_SPECIAL_FREEWHEEL)
4792             {
4793                 fParamBuffers[k] = isOffline ? pData->param.ranges[k].max : pData->param.ranges[k].min;
4794                 pData->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k), fParamBuffers[k]);
4795                 break;
4796             }
4797         }
4798     }
4799 
4800     // -------------------------------------------------------------------
4801     // Plugin buffers
4802 
initBuffers() const4803     void initBuffers() const noexcept override
4804     {
4805         fEventsIn.initBuffers();
4806         fEventsOut.initBuffers();
4807 
4808         CarlaPlugin::initBuffers();
4809     }
4810 
clearBuffers()4811     void clearBuffers() noexcept override
4812     {
4813         carla_debug("CarlaPluginLV2::clearBuffers() - start");
4814 
4815         if (fAudioInBuffers != nullptr)
4816         {
4817             for (uint32_t i=0; i < pData->audioIn.count; ++i)
4818             {
4819                 if (fAudioInBuffers[i] != nullptr)
4820                 {
4821                     delete[] fAudioInBuffers[i];
4822                     fAudioInBuffers[i] = nullptr;
4823                 }
4824             }
4825 
4826             delete[] fAudioInBuffers;
4827             fAudioInBuffers = nullptr;
4828         }
4829 
4830         if (fAudioOutBuffers != nullptr)
4831         {
4832             for (uint32_t i=0; i < pData->audioOut.count; ++i)
4833             {
4834                 if (fAudioOutBuffers[i] != nullptr)
4835                 {
4836                     delete[] fAudioOutBuffers[i];
4837                     fAudioOutBuffers[i] = nullptr;
4838                 }
4839             }
4840 
4841             delete[] fAudioOutBuffers;
4842             fAudioOutBuffers = nullptr;
4843         }
4844 
4845         if (fCvInBuffers != nullptr)
4846         {
4847             for (uint32_t i=0; i < pData->cvIn.count; ++i)
4848             {
4849                 if (fCvInBuffers[i] != nullptr)
4850                 {
4851                     delete[] fCvInBuffers[i];
4852                     fCvInBuffers[i] = nullptr;
4853                 }
4854             }
4855 
4856             delete[] fCvInBuffers;
4857             fCvInBuffers = nullptr;
4858         }
4859 
4860         if (fCvOutBuffers != nullptr)
4861         {
4862             for (uint32_t i=0; i < pData->cvOut.count; ++i)
4863             {
4864                 if (fCvOutBuffers[i] != nullptr)
4865                 {
4866                     delete[] fCvOutBuffers[i];
4867                     fCvOutBuffers[i] = nullptr;
4868                 }
4869             }
4870 
4871             delete[] fCvOutBuffers;
4872             fCvOutBuffers = nullptr;
4873         }
4874 
4875         if (fParamBuffers != nullptr)
4876         {
4877             delete[] fParamBuffers;
4878             fParamBuffers = nullptr;
4879         }
4880 
4881         fEventsIn.clear(pData->event.portIn);
4882         fEventsOut.clear(pData->event.portOut);
4883 
4884         CarlaPlugin::clearBuffers();
4885 
4886         carla_debug("CarlaPluginLV2::clearBuffers() - end");
4887     }
4888 
4889     // -------------------------------------------------------------------
4890     // Post-poned UI Stuff
4891 
uiParameterChange(const uint32_t index,const float value)4892     void uiParameterChange(const uint32_t index, const float value) noexcept override
4893     {
4894         CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
4895         CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,);
4896         CARLA_SAFE_ASSERT_RETURN(pData->param.data[index].rindex >= 0,);
4897 
4898         if (fUI.type == UI::TYPE_BRIDGE)
4899         {
4900             if (! fPipeServer.isPipeRunning())
4901                 return;
4902         }
4903         else
4904         {
4905             if (fUI.handle == nullptr)
4906                 return;
4907             if (fUI.descriptor == nullptr || fUI.descriptor->port_event == nullptr)
4908                 return;
4909             if (fNeedsUiClose)
4910                 return;
4911         }
4912 
4913         ParameterData& pdata(pData->param.data[index]);
4914 
4915         if (pdata.hints & PARAMETER_IS_NOT_SAVED)
4916         {
4917             int32_t rindex = pdata.rindex;
4918             CARLA_SAFE_ASSERT_RETURN(rindex - static_cast<int32_t>(fRdfDescriptor->PortCount) >= 0,);
4919 
4920             rindex -= static_cast<int32_t>(fRdfDescriptor->PortCount);
4921             CARLA_SAFE_ASSERT_RETURN(rindex < static_cast<int32_t>(fRdfDescriptor->ParameterCount),);
4922 
4923             const char* const uri = fRdfDescriptor->Parameters[rindex].URI;
4924 
4925             if (fUI.type == UI::TYPE_BRIDGE)
4926             {
4927                 fPipeServer.writeLv2ParameterMessage(uri, value);
4928             }
4929             else if (fEventsIn.ctrl != nullptr)
4930             {
4931                 uint8_t atomBuf[256];
4932                 LV2_Atom_Forge atomForge;
4933                 initAtomForge(atomForge);
4934                 lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
4935 
4936                 LV2_Atom_Forge_Frame forgeFrame;
4937                 lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
4938 
4939                 lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
4940                 lv2_atom_forge_bool(&atomForge, true);
4941 
4942                 lv2_atom_forge_key(&atomForge, kUridPatchProperty);
4943                 lv2_atom_forge_urid(&atomForge, getCustomURID(uri));
4944 
4945                 lv2_atom_forge_key(&atomForge, kUridPatchValue);
4946 
4947                 switch (fRdfDescriptor->Parameters[rindex].Type)
4948                 {
4949                 case LV2_PARAMETER_TYPE_BOOL:
4950                     lv2_atom_forge_bool(&atomForge, value > 0.5f);
4951                     break;
4952                 case LV2_PARAMETER_TYPE_INT:
4953                     lv2_atom_forge_int(&atomForge, static_cast<int32_t>(value + 0.5f));
4954                     break;
4955                 case LV2_PARAMETER_TYPE_LONG:
4956                     lv2_atom_forge_long(&atomForge, static_cast<int64_t>(value + 0.5f));
4957                     break;
4958                 case LV2_PARAMETER_TYPE_FLOAT:
4959                     lv2_atom_forge_float(&atomForge, value);
4960                     break;
4961                 case LV2_PARAMETER_TYPE_DOUBLE:
4962                     lv2_atom_forge_double(&atomForge, value);
4963                     break;
4964                 default:
4965                     carla_stderr2("uiParameterChange called for invalid parameter, abort!");
4966                     return;
4967                 }
4968 
4969                 lv2_atom_forge_pop(&atomForge, &forgeFrame);
4970 
4971                 LV2_Atom* const atom((LV2_Atom*)atomBuf);
4972                 CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
4973 
4974                 fUI.descriptor->port_event(fUI.handle,
4975                                            fEventsIn.ctrl->rindex,
4976                                            lv2_atom_total_size(atom),
4977                                            kUridAtomTransferEvent,
4978                                            atom);
4979             }
4980         }
4981         else
4982         {
4983             if (fUI.type == UI::TYPE_BRIDGE)
4984             {
4985                 fPipeServer.writeControlMessage(static_cast<uint32_t>(pData->param.data[index].rindex), value);
4986             }
4987             else
4988             {
4989                 fUI.descriptor->port_event(fUI.handle,
4990                                            static_cast<uint32_t>(pData->param.data[index].rindex),
4991                                            sizeof(float), kUridNull, &value);
4992             }
4993         }
4994     }
4995 
uiMidiProgramChange(const uint32_t index)4996     void uiMidiProgramChange(const uint32_t index) noexcept override
4997     {
4998         CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
4999         CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
5000 
5001         if (fUI.type == UI::TYPE_BRIDGE)
5002         {
5003             if (fPipeServer.isPipeRunning())
5004                 fPipeServer.writeMidiProgramMessage(pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
5005         }
5006         else
5007         {
5008             if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program != nullptr && ! fNeedsUiClose)
5009                 fExt.uiprograms->select_program(fUI.handle, pData->midiprog.data[index].bank, pData->midiprog.data[index].program);
5010         }
5011     }
5012 
uiNoteOn(const uint8_t channel,const uint8_t note,const uint8_t velo)5013     void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override
5014     {
5015         CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5016         CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
5017         CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
5018         CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
5019 
5020 #if 0
5021         if (fUI.type == UI::TYPE_BRIDGE)
5022         {
5023             if (fPipeServer.isPipeRunning())
5024                 fPipeServer.writeMidiNoteMessage(false, channel, note, velo);
5025         }
5026         else
5027         {
5028             if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
5029             {
5030                 LV2_Atom_MidiEvent midiEv;
5031                 midiEv.atom.type = kUridMidiEvent;
5032                 midiEv.atom.size = 3;
5033                 midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT));
5034                 midiEv.data[1] = note;
5035                 midiEv.data[2] = velo;
5036 
5037                 fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
5038             }
5039         }
5040 #endif
5041     }
5042 
uiNoteOff(const uint8_t channel,const uint8_t note)5043     void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override
5044     {
5045         CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL || fFilePathURI.isNotEmpty(),);
5046         CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
5047         CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
5048 
5049 #if 0
5050         if (fUI.type == UI::TYPE_BRIDGE)
5051         {
5052             if (fPipeServer.isPipeRunning())
5053                 fPipeServer.writeMidiNoteMessage(false, channel, note, 0);
5054         }
5055         else
5056         {
5057             if (fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr && fEventsIn.ctrl != nullptr && ! fNeedsUiClose)
5058             {
5059                 LV2_Atom_MidiEvent midiEv;
5060                 midiEv.atom.type = kUridMidiEvent;
5061                 midiEv.atom.size = 3;
5062                 midiEv.data[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (channel & MIDI_CHANNEL_BIT));
5063                 midiEv.data[1] = note;
5064                 midiEv.data[2] = 0;
5065 
5066                 fUI.descriptor->port_event(fUI.handle, fEventsIn.ctrl->rindex, lv2_atom_total_size(midiEv), kUridAtomTransferEvent, &midiEv);
5067             }
5068         }
5069 #endif
5070     }
5071 
5072     // -------------------------------------------------------------------
5073     // Internal helper functions
5074 
cloneLV2Files(const CarlaPlugin & other)5075     void cloneLV2Files(const CarlaPlugin& other) override
5076     {
5077         CARLA_SAFE_ASSERT_RETURN(other.getType() == PLUGIN_LV2,);
5078 
5079         const CarlaPluginLV2& otherLV2((const CarlaPluginLV2&)other);
5080 
5081         const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5082 
5083         if (tmpDir.exists())
5084             tmpDir.deleteRecursively();
5085 
5086         const File otherStateDir(otherLV2.handleStateMapToAbsolutePath(false, false, false, "."));
5087 
5088         if (otherStateDir.exists())
5089             otherStateDir.copyDirectoryTo(tmpDir);
5090 
5091         const File otherTmpDir(otherLV2.handleStateMapToAbsolutePath(false, false, true, "."));
5092 
5093         if (otherTmpDir.exists())
5094             otherTmpDir.copyDirectoryTo(tmpDir);
5095     }
5096 
restoreLV2State(const bool temporary)5097     void restoreLV2State(const bool temporary) noexcept override
5098     {
5099         if (fExt.state == nullptr || fExt.state->restore == nullptr)
5100             return;
5101 
5102         if (! temporary)
5103         {
5104             const File tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5105 
5106             if (tmpDir.exists())
5107                 tmpDir.deleteRecursively();
5108         }
5109 
5110         LV2_State_Status status = LV2_STATE_ERR_UNKNOWN;
5111 
5112         {
5113             const ScopedSingleProcessLocker spl(this, !fHasThreadSafeRestore);
5114 
5115             try {
5116                 status = fExt.state->restore(fHandle,
5117                                              carla_lv2_state_retrieve,
5118                                              this,
5119                                              LV2_STATE_IS_POD,
5120                                              temporary ? fFeatures : fStateFeatures);
5121             } catch(...) {}
5122 
5123             if (fHandle2 != nullptr)
5124             {
5125                 try {
5126                     fExt.state->restore(fHandle,
5127                                         carla_lv2_state_retrieve,
5128                                         this,
5129                                         LV2_STATE_IS_POD,
5130                                         temporary ? fFeatures : fStateFeatures);
5131                 } catch(...) {}
5132             }
5133         }
5134 
5135         switch (status)
5136         {
5137         case LV2_STATE_SUCCESS:
5138             carla_debug("CarlaPluginLV2::updateLV2State() - success");
5139             break;
5140         case LV2_STATE_ERR_UNKNOWN:
5141             carla_stderr("CarlaPluginLV2::updateLV2State() - unknown error");
5142             break;
5143         case LV2_STATE_ERR_BAD_TYPE:
5144             carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad type");
5145             break;
5146         case LV2_STATE_ERR_BAD_FLAGS:
5147             carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad flags");
5148             break;
5149         case LV2_STATE_ERR_NO_FEATURE:
5150             carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing feature");
5151             break;
5152         case LV2_STATE_ERR_NO_PROPERTY:
5153             carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing property");
5154             break;
5155         case LV2_STATE_ERR_NO_SPACE:
5156             carla_stderr("CarlaPluginLV2::updateLV2State() - error, insufficient space");
5157             break;
5158         }
5159     }
5160 
5161     // -------------------------------------------------------------------
5162 
isRealtimeSafe() const5163     bool isRealtimeSafe() const noexcept
5164     {
5165         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, false);
5166 
5167         for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
5168         {
5169             if (std::strcmp(fRdfDescriptor->Features[i].URI, LV2_CORE__hardRTCapable) == 0)
5170                 return true;
5171         }
5172 
5173         return false;
5174     }
5175 
5176     // -------------------------------------------------------------------
5177 
isUiBridgeable(const uint32_t uiId) const5178     bool isUiBridgeable(const uint32_t uiId) const noexcept
5179     {
5180         CARLA_SAFE_ASSERT_RETURN(uiId < fRdfDescriptor->UICount, false);
5181 
5182 #ifndef LV2_UIS_ONLY_INPROCESS
5183         const LV2_RDF_UI* const rdfUI(&fRdfDescriptor->UIs[uiId]);
5184 
5185         for (uint32_t i=0; i < rdfUI->FeatureCount; ++i)
5186         {
5187             const LV2_RDF_Feature& feat(rdfUI->Features[i]);
5188 
5189             if (! feat.Required)
5190                 continue;
5191             if (std::strcmp(feat.URI, LV2_INSTANCE_ACCESS_URI) == 0)
5192                 return false;
5193             if (std::strcmp(feat.URI, LV2_DATA_ACCESS_URI) == 0)
5194                 return false;
5195         }
5196 
5197         // Calf UIs are mostly useless without their special graphs
5198         // but they can be crashy under certain conditions, so follow user preferences
5199         if (std::strstr(rdfUI->URI, "http://calf.sourceforge.net/plugins/gui/") != nullptr)
5200             return pData->engine->getOptions().preferUiBridges;
5201 
5202         // LSP-Plugins UIs make heavy use of URIDs, for which carla right now is very slow
5203         // FIXME after some optimization, remove this
5204         if (std::strstr(rdfUI->URI, "http://lsp-plug.in/ui/lv2/") != nullptr)
5205             return false;
5206 
5207         return true;
5208 #else
5209         return false;
5210 #endif
5211     }
5212 
isUiResizable() const5213     bool isUiResizable() const noexcept
5214     {
5215         CARLA_SAFE_ASSERT_RETURN(fUI.rdfDescriptor != nullptr, false);
5216 
5217         for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
5218         {
5219             if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0)
5220                 return false;
5221             if (std::strcmp(fUI.rdfDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
5222                 return false;
5223         }
5224 
5225         return true;
5226     }
5227 
getUiBridgeBinary(const LV2_Property type) const5228     const char* getUiBridgeBinary(const LV2_Property type) const
5229     {
5230         CarlaString bridgeBinary(pData->engine->getOptions().binaryDir);
5231 
5232         if (bridgeBinary.isEmpty())
5233             return nullptr;
5234 
5235         switch (type)
5236         {
5237         case LV2_UI_GTK2:
5238             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk2";
5239             break;
5240         case LV2_UI_GTK3:
5241             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-gtk3";
5242             break;
5243         case LV2_UI_QT4:
5244             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt4";
5245             break;
5246         case LV2_UI_QT5:
5247             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-qt5";
5248             break;
5249         case LV2_UI_COCOA:
5250             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-cocoa";
5251             break;
5252         case LV2_UI_WINDOWS:
5253             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-windows";
5254             break;
5255         case LV2_UI_X11:
5256             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-x11";
5257             break;
5258         case LV2_UI_MOD:
5259             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-modgui";
5260             break;
5261 #if 0
5262         case LV2_UI_EXTERNAL:
5263         case LV2_UI_OLD_EXTERNAL:
5264             bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-lv2-external";
5265             break;
5266 #endif
5267         default:
5268             return nullptr;
5269         }
5270 
5271 #ifdef CARLA_OS_WIN
5272         bridgeBinary += ".exe";
5273 #endif
5274 
5275         if (! File(bridgeBinary.buffer()).existsAsFile())
5276             return nullptr;
5277 
5278         return bridgeBinary.dupSafe();
5279     }
5280 
5281     // -------------------------------------------------------------------
5282 
recheckExtensions()5283     void recheckExtensions()
5284     {
5285         CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,);
5286         carla_debug("CarlaPluginLV2::recheckExtensions()");
5287 
5288         fExt.options  = nullptr;
5289         fExt.programs = nullptr;
5290         fExt.state    = nullptr;
5291         fExt.worker   = nullptr;
5292         fExt.inlineDisplay = nullptr;
5293 
5294         for (uint32_t i=0; i < fRdfDescriptor->ExtensionCount; ++i)
5295         {
5296             const char* const extension = fRdfDescriptor->Extensions[i];
5297             CARLA_SAFE_ASSERT_CONTINUE(extension != nullptr);
5298 
5299             /**/ if (std::strcmp(extension, LV2_OPTIONS__interface) == 0)
5300                 pData->hints |= PLUGIN_HAS_EXTENSION_OPTIONS;
5301             else if (std::strcmp(extension, LV2_PROGRAMS__Interface) == 0)
5302                 pData->hints |= PLUGIN_HAS_EXTENSION_PROGRAMS;
5303             else if (std::strcmp(extension, LV2_STATE__interface) == 0)
5304                 pData->hints |= PLUGIN_HAS_EXTENSION_STATE;
5305             else if (std::strcmp(extension, LV2_WORKER__interface) == 0)
5306                 pData->hints |= PLUGIN_HAS_EXTENSION_WORKER;
5307             else if (std::strcmp(extension, LV2_INLINEDISPLAY__interface) == 0)
5308                 pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
5309             else if (std::strcmp(extension, LV2_MIDNAM__interface) == 0)
5310                 pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
5311             else
5312                 carla_stdout("Plugin '%s' has non-supported extension: '%s'", fRdfDescriptor->URI, extension);
5313         }
5314 
5315         // Fix for broken plugins, nasty!
5316         for (uint32_t i=0; i < fRdfDescriptor->FeatureCount; ++i)
5317         {
5318             const LV2_RDF_Feature& feature(fRdfDescriptor->Features[i]);
5319 
5320             if (std::strcmp(feature.URI, LV2_INLINEDISPLAY__queue_draw) == 0)
5321             {
5322                 if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
5323                     break;
5324 
5325                 carla_stdout("Plugin '%s' uses inline-display but does not set extension data, nasty!", fRdfDescriptor->URI);
5326                 pData->hints |= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY;
5327             }
5328             else if (std::strcmp(feature.URI, LV2_MIDNAM__update) == 0)
5329             {
5330                 if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
5331                     break;
5332 
5333                 carla_stdout("Plugin '%s' uses midnam but does not set extension data, nasty!", fRdfDescriptor->URI);
5334                 pData->hints |= PLUGIN_HAS_EXTENSION_MIDNAM;
5335             }
5336         }
5337 
5338         if (fDescriptor->extension_data != nullptr)
5339         {
5340             if (pData->hints & PLUGIN_HAS_EXTENSION_OPTIONS)
5341                 fExt.options = (const LV2_Options_Interface*)fDescriptor->extension_data(LV2_OPTIONS__interface);
5342 
5343             if (pData->hints & PLUGIN_HAS_EXTENSION_PROGRAMS)
5344                 fExt.programs = (const LV2_Programs_Interface*)fDescriptor->extension_data(LV2_PROGRAMS__Interface);
5345 
5346             if (pData->hints & PLUGIN_HAS_EXTENSION_STATE)
5347                 fExt.state = (const LV2_State_Interface*)fDescriptor->extension_data(LV2_STATE__interface);
5348 
5349             if (pData->hints & PLUGIN_HAS_EXTENSION_WORKER)
5350                 fExt.worker = (const LV2_Worker_Interface*)fDescriptor->extension_data(LV2_WORKER__interface);
5351 
5352             if (pData->hints & PLUGIN_HAS_EXTENSION_INLINE_DISPLAY)
5353                 fExt.inlineDisplay = (const LV2_Inline_Display_Interface*)fDescriptor->extension_data(LV2_INLINEDISPLAY__interface);
5354 
5355             if (pData->hints & PLUGIN_HAS_EXTENSION_MIDNAM)
5356                 fExt.midnam = (const LV2_Midnam_Interface*)fDescriptor->extension_data(LV2_MIDNAM__interface);
5357 
5358             // check if invalid
5359             if (fExt.options != nullptr && fExt.options->get == nullptr  && fExt.options->set == nullptr)
5360                 fExt.options = nullptr;
5361 
5362             if (fExt.programs != nullptr && (fExt.programs->get_program == nullptr || fExt.programs->select_program == nullptr))
5363                 fExt.programs = nullptr;
5364 
5365             if (fExt.state != nullptr && (fExt.state->save == nullptr || fExt.state->restore == nullptr))
5366                 fExt.state = nullptr;
5367 
5368             if (fExt.worker != nullptr && fExt.worker->work == nullptr)
5369                 fExt.worker = nullptr;
5370 
5371             if (fExt.inlineDisplay != nullptr)
5372             {
5373                 if (fExt.inlineDisplay->render != nullptr)
5374                 {
5375                     pData->hints |= PLUGIN_HAS_INLINE_DISPLAY;
5376                     pData->setCanDeleteLib(false);
5377                 }
5378                 else
5379                 {
5380                     fExt.inlineDisplay = nullptr;
5381                 }
5382             }
5383 
5384             if (fExt.midnam != nullptr && fExt.midnam->midnam == nullptr)
5385                 fExt.midnam = nullptr;
5386         }
5387 
5388         CARLA_SAFE_ASSERT_RETURN(fLatencyIndex == -1,);
5389 
5390         int32_t iCtrl=0;
5391         for (uint32_t i=0, count=fRdfDescriptor->PortCount; i<count; ++i)
5392         {
5393             const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);
5394 
5395             if (! LV2_IS_PORT_CONTROL(portTypes))
5396                 continue;
5397 
5398             const CarlaScopedValueSetter<int32_t> svs(iCtrl, iCtrl, iCtrl+1);
5399 
5400             if (! LV2_IS_PORT_OUTPUT(portTypes))
5401                 continue;
5402 
5403             const LV2_Property portDesignation(fRdfDescriptor->Ports[i].Designation);
5404 
5405             if (! LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation))
5406                 continue;
5407 
5408             fLatencyIndex = iCtrl;
5409             break;
5410         }
5411     }
5412 
5413     // -------------------------------------------------------------------
5414 
updateUi()5415     void updateUi()
5416     {
5417         CARLA_SAFE_ASSERT_RETURN(fUI.handle != nullptr,);
5418         CARLA_SAFE_ASSERT_RETURN(fUI.descriptor != nullptr,);
5419         carla_debug("CarlaPluginLV2::updateUi()");
5420 
5421         // update midi program
5422         if (fExt.uiprograms != nullptr && pData->midiprog.count > 0 && pData->midiprog.current >= 0)
5423         {
5424             const MidiProgramData& curData(pData->midiprog.getCurrent());
5425             fExt.uiprograms->select_program(fUI.handle, curData.bank, curData.program);
5426         }
5427 
5428         // update control ports
5429         if (fUI.descriptor->port_event != nullptr)
5430         {
5431             float value;
5432             for (uint32_t i=0; i < pData->param.count; ++i)
5433             {
5434                 value = getParameterValue(i);
5435                 fUI.descriptor->port_event(fUI.handle, static_cast<uint32_t>(pData->param.data[i].rindex), sizeof(float), kUridNull, &value);
5436             }
5437         }
5438     }
5439 
inspectAtomForParameterChange(const LV2_Atom * const atom)5440     void inspectAtomForParameterChange(const LV2_Atom* const atom)
5441     {
5442         if (atom->type != kUridAtomBlank && atom->type != kUridAtomObject)
5443             return;
5444 
5445         const LV2_Atom_Object_Body* const objbody = (const LV2_Atom_Object_Body*)(atom + 1);
5446 
5447         if (objbody->otype != kUridPatchSet)
5448             return;
5449 
5450         const LV2_Atom_URID *property   = NULL;
5451         const LV2_Atom_Bool *carlaParam = NULL;
5452         const LV2_Atom      *value      = NULL;
5453 
5454         lv2_atom_object_body_get(atom->size, objbody,
5455                                   kUridCarlaParameterChange, (const LV2_Atom**)&carlaParam,
5456                                   kUridPatchProperty,        (const LV2_Atom**)&property,
5457                                   kUridPatchValue,            &value,
5458                                   0);
5459 
5460         if (carlaParam != nullptr && carlaParam->body != 0)
5461             return;
5462 
5463         if (property == nullptr || value == nullptr)
5464             return;
5465 
5466         switch (value->type)
5467         {
5468         case kUridAtomBool:
5469         case kUridAtomInt:
5470         //case kUridAtomLong:
5471         case kUridAtomFloat:
5472         case kUridAtomDouble:
5473             break;
5474         default:
5475             return;
5476         }
5477 
5478         uint32_t parameterId;
5479         if (! getParameterIndexForURID(property->body, parameterId))
5480             return;
5481 
5482         const uint8_t* const vbody = (const uint8_t*)(value + 1);
5483         float rvalue;
5484 
5485         switch (value->type)
5486         {
5487         case kUridAtomBool:
5488             rvalue = *(const int32_t*)vbody != 0 ? 1.0f : 0.0f;
5489             break;
5490         case kUridAtomInt:
5491             rvalue = static_cast<float>(*(const int32_t*)vbody);
5492             break;
5493         /*
5494         case kUridAtomLong:
5495             rvalue = *(int64_t*)vbody;
5496             break;
5497         */
5498         case kUridAtomFloat:
5499             rvalue = *(const float*)vbody;
5500             break;
5501         case kUridAtomDouble:
5502             rvalue = static_cast<float>(*(const double*)vbody);
5503             break;
5504         default:
5505             rvalue = 0.0f;
5506             break;
5507         }
5508 
5509         rvalue = pData->param.getFixedValue(parameterId, rvalue);
5510         fParamBuffers[parameterId] = rvalue;
5511 
5512         CarlaPlugin::setParameterValue(parameterId, rvalue, false, true, true);
5513     }
5514 
getParameterIndexForURI(const char * const uri,uint32_t & parameterId)5515     bool getParameterIndexForURI(const char* const uri, uint32_t& parameterId) noexcept
5516     {
5517         parameterId = UINT32_MAX;
5518 
5519         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
5520         {
5521             const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
5522 
5523             switch (rdfParam.Type)
5524             {
5525             case LV2_PARAMETER_TYPE_BOOL:
5526             case LV2_PARAMETER_TYPE_INT:
5527             // case LV2_PARAMETER_TYPE_LONG:
5528             case LV2_PARAMETER_TYPE_FLOAT:
5529             case LV2_PARAMETER_TYPE_DOUBLE:
5530                 break;
5531             default:
5532                 continue;
5533             }
5534 
5535             if (std::strcmp(rdfParam.URI, uri) == 0)
5536             {
5537                 const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
5538 
5539                 for (uint32_t j=0; j < pData->param.count; ++j)
5540                 {
5541                     if (pData->param.data[j].rindex == rindex)
5542                     {
5543                         parameterId = j;
5544                         break;
5545                     }
5546                 }
5547                 break;
5548             }
5549         }
5550 
5551         return (parameterId != UINT32_MAX);
5552     }
5553 
getParameterIndexForURID(const LV2_URID urid,uint32_t & parameterId)5554     bool getParameterIndexForURID(const LV2_URID urid, uint32_t& parameterId) noexcept
5555     {
5556         parameterId = UINT32_MAX;
5557 
5558         if (urid >= fCustomURIDs.size())
5559             return false;
5560 
5561         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
5562         {
5563             const LV2_RDF_Parameter& rdfParam(fRdfDescriptor->Parameters[i]);
5564 
5565             switch (rdfParam.Type)
5566             {
5567             case LV2_PARAMETER_TYPE_BOOL:
5568             case LV2_PARAMETER_TYPE_INT:
5569             // case LV2_PARAMETER_TYPE_LONG:
5570             case LV2_PARAMETER_TYPE_FLOAT:
5571             case LV2_PARAMETER_TYPE_DOUBLE:
5572                 break;
5573             default:
5574                 continue;
5575             }
5576 
5577             const std::string& uri(fCustomURIDs[urid]);
5578 
5579             if (uri != rdfParam.URI)
5580                 continue;
5581 
5582             const int32_t rindex = static_cast<int32_t>(fRdfDescriptor->PortCount + i);
5583 
5584               for (uint32_t j=0; j < pData->param.count; ++j)
5585               {
5586                   if (pData->param.data[j].rindex == rindex)
5587                   {
5588                       parameterId = j;
5589                       break;
5590                   }
5591               }
5592               break;
5593         }
5594 
5595         return (parameterId != UINT32_MAX);
5596     }
5597 
5598     // -------------------------------------------------------------------
5599 
getCustomURID(const char * const uri)5600     LV2_URID getCustomURID(const char* const uri)
5601     {
5602         CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
5603         carla_debug("CarlaPluginLV2::getCustomURID(\"%s\")", uri);
5604 
5605         const std::string    s_uri(uri);
5606         const std::ptrdiff_t s_pos(std::find(fCustomURIDs.begin(), fCustomURIDs.end(), s_uri) - fCustomURIDs.begin());
5607 
5608         if (s_pos <= 0 || s_pos >= INT32_MAX)
5609             return kUridNull;
5610 
5611         const LV2_URID urid     = static_cast<LV2_URID>(s_pos);
5612         const LV2_URID uriCount = static_cast<LV2_URID>(fCustomURIDs.size());
5613 
5614         if (urid < uriCount)
5615             return urid;
5616 
5617         CARLA_SAFE_ASSERT(urid == uriCount);
5618 
5619         fCustomURIDs.push_back(uri);
5620 
5621         if (fUI.type == UI::TYPE_BRIDGE && fPipeServer.isPipeRunning())
5622             fPipeServer.writeLv2UridMessage(urid, uri);
5623 
5624         return urid;
5625     }
5626 
getCustomURIDString(const LV2_URID urid) const5627     const char* getCustomURIDString(const LV2_URID urid) const noexcept
5628     {
5629         CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, kUnmapFallback);
5630         CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.size(), kUnmapFallback);
5631         carla_debug("CarlaPluginLV2::getCustomURIString(%i)", urid);
5632 
5633         return fCustomURIDs[urid].c_str();
5634     }
5635 
5636     // -------------------------------------------------------------------
5637 
handleProgramChanged(const int32_t index)5638     void handleProgramChanged(const int32_t index)
5639     {
5640         CARLA_SAFE_ASSERT_RETURN(index >= -1,);
5641         carla_debug("CarlaPluginLV2::handleProgramChanged(%i)", index);
5642 
5643         if (index == -1)
5644         {
5645             const ScopedSingleProcessLocker spl(this, true);
5646             return reloadPrograms(false);
5647         }
5648 
5649         if (index < static_cast<int32_t>(pData->midiprog.count) && fExt.programs != nullptr && fExt.programs->get_program != nullptr)
5650         {
5651             if (const LV2_Program_Descriptor* const progDesc = fExt.programs->get_program(fHandle, static_cast<uint32_t>(index)))
5652             {
5653                 CARLA_SAFE_ASSERT_RETURN(progDesc->name != nullptr,);
5654 
5655                 if (pData->midiprog.data[index].name != nullptr)
5656                     delete[] pData->midiprog.data[index].name;
5657 
5658                 pData->midiprog.data[index].name = carla_strdup(progDesc->name);
5659 
5660                 if (index == pData->midiprog.current)
5661                     pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0, nullptr);
5662                 else
5663                     pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0, nullptr);
5664             }
5665         }
5666     }
5667 
5668     // -------------------------------------------------------------------
5669 
handleResizePort(const uint32_t index,const size_t size)5670     LV2_Resize_Port_Status handleResizePort(const uint32_t index, const size_t size)
5671     {
5672         CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_RESIZE_PORT_ERR_UNKNOWN);
5673         carla_debug("CarlaPluginLV2::handleResizePort(%i, " P_SIZE ")", index, size);
5674 
5675         // TODO
5676         return LV2_RESIZE_PORT_ERR_NO_SPACE;
5677         (void)index;
5678     }
5679 
5680     // -------------------------------------------------------------------
5681 
handleStateMapToAbstractPath(const bool temporary,const char * const absolutePath) const5682     char* handleStateMapToAbstractPath(const bool temporary, const char* const absolutePath) const
5683     {
5684         // may already be an abstract path
5685         if (! File::isAbsolutePath(absolutePath))
5686             return strdup(absolutePath);
5687 
5688         File projectDir, targetDir;
5689 
5690 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5691         if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
5692             projectDir = projFolder;
5693         else
5694 #endif
5695             projectDir = File::getCurrentWorkingDirectory();
5696 
5697         if (projectDir.isNull())
5698         {
5699             carla_stdout("Project directory not set, cannot map absolutePath %s", absolutePath);
5700             return nullptr;
5701         }
5702 
5703         water::String basedir(pData->engine->getName());
5704 
5705         if (temporary)
5706             basedir += ".tmp";
5707 
5708         targetDir = projectDir.getChildFile(basedir)
5709                               .getChildFile(getName());
5710 
5711         if (! targetDir.exists())
5712             targetDir.createDirectory();
5713 
5714         const File wabsolutePath(absolutePath);
5715 
5716         // we may be saving to non-tmp path, let's check
5717         if (! temporary)
5718         {
5719             const File tmpDir = projectDir.getChildFile(basedir + ".tmp")
5720                                           .getChildFile(getName());
5721 
5722             if (wabsolutePath.getFullPathName().startsWith(tmpDir.getFullPathName()))
5723             {
5724                 // gotcha, the temporary path is now the real one
5725                 targetDir = tmpDir;
5726             }
5727             else if (! wabsolutePath.getFullPathName().startsWith(targetDir.getFullPathName()))
5728             {
5729                 // seems like a normal save, let's be nice and put a symlink
5730                 const water::String abstractFilename(wabsolutePath.getFileName());
5731                 const File targetPath(targetDir.getChildFile(abstractFilename));
5732 
5733                 wabsolutePath.createSymbolicLink(targetPath, true);
5734 
5735                 carla_stdout("Creating symlink for '%s' in '%s'", absolutePath, targetDir.getFullPathName().toRawUTF8());
5736                 return strdup(abstractFilename.toRawUTF8());
5737             }
5738         }
5739 
5740         carla_stdout("Mapping absolutePath '%s' relative to targetDir '%s'",
5741                      absolutePath, targetDir.getFullPathName().toRawUTF8());
5742 
5743         return strdup(wabsolutePath.getRelativePathFrom(targetDir).toRawUTF8());
5744     }
5745 
handleStateMapToAbsolutePath(const bool createDirIfNeeded,const bool symlinkIfNeeded,const bool temporary,const char * const abstractPath) const5746     File handleStateMapToAbsolutePath(const bool createDirIfNeeded,
5747                                       const bool symlinkIfNeeded,
5748                                       const bool temporary,
5749                                       const char* const abstractPath) const
5750     {
5751         File targetDir, targetPath;
5752 
5753 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5754         if (const char* const projFolder = pData->engine->getCurrentProjectFolder())
5755             targetDir = projFolder;
5756         else
5757 #endif
5758             targetDir = File::getCurrentWorkingDirectory();
5759 
5760         if (targetDir.isNull())
5761         {
5762             carla_stdout("Project directory not set, cannot map abstractPath '%s'", abstractPath);
5763             return File();
5764         }
5765 
5766         water::String basedir(pData->engine->getName());
5767 
5768         if (temporary)
5769             basedir += ".tmp";
5770 
5771         targetDir = targetDir.getChildFile(basedir)
5772                              .getChildFile(getName());
5773 
5774         if (createDirIfNeeded && ! targetDir.exists())
5775             targetDir.createDirectory();
5776 
5777         if (File::isAbsolutePath(abstractPath))
5778         {
5779             File wabstractPath(abstractPath);
5780             targetPath = targetDir.getChildFile(wabstractPath.getFileName());
5781 
5782             if (symlinkIfNeeded)
5783             {
5784                 carla_stdout("Creating symlink for '%s' in '%s'",
5785                              abstractPath, targetDir.getFullPathName().toRawUTF8());
5786                 wabstractPath.createSymbolicLink(targetPath, true);
5787             }
5788         }
5789         else
5790         {
5791             targetPath = targetDir.getChildFile(abstractPath);
5792             targetDir  = targetPath.getParentDirectory();
5793 
5794             if (createDirIfNeeded && ! targetDir.exists())
5795                 targetDir.createDirectory();
5796         }
5797 
5798         if (std::strcmp(abstractPath, ".") != 0)
5799             carla_stdout("Mapping abstractPath '%s' relative to targetDir '%s'",
5800                          abstractPath, targetDir.getFullPathName().toRawUTF8());
5801 
5802         return targetPath;
5803     }
5804 
handleStateStore(const uint32_t key,const void * const value,const size_t size,const uint32_t type,const uint32_t flags)5805     LV2_State_Status handleStateStore(const uint32_t key, const void* const value, const size_t size, const uint32_t type, const uint32_t flags)
5806     {
5807         CARLA_SAFE_ASSERT_RETURN(key != kUridNull, LV2_STATE_ERR_NO_PROPERTY);
5808         CARLA_SAFE_ASSERT_RETURN(value != nullptr, LV2_STATE_ERR_NO_PROPERTY);
5809         CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_STATE_ERR_NO_PROPERTY);
5810         CARLA_SAFE_ASSERT_RETURN(type != kUridNull, LV2_STATE_ERR_BAD_TYPE);
5811 
5812         // FIXME linuxsampler does not set POD flag
5813         // CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
5814 
5815         carla_debug("CarlaPluginLV2::handleStateStore(%i:\"%s\", %p, " P_SIZE ", %i:\"%s\", %i)",
5816                     key, carla_lv2_urid_unmap(this, key), value, size, type, carla_lv2_urid_unmap(this, type), flags);
5817 
5818         const char* const skey(carla_lv2_urid_unmap(this, key));
5819         const char* const stype(carla_lv2_urid_unmap(this, type));
5820 
5821         CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
5822         CARLA_SAFE_ASSERT_RETURN(stype != nullptr && stype != kUnmapFallback, LV2_STATE_ERR_BAD_TYPE);
5823 
5824         // Check if we already have this key
5825         for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
5826         {
5827             CustomData& cData(it.getValue(kCustomDataFallbackNC));
5828             CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
5829 
5830             if (std::strcmp(cData.key, skey) == 0)
5831             {
5832                 // found it
5833                 delete[] cData.value;
5834 
5835                 if (type == kUridAtomString || type == kUridAtomPath)
5836                     cData.value = carla_strdup((const char*)value);
5837                 else
5838                     cData.value = CarlaString::asBase64(value, size).dup();
5839 
5840                 return LV2_STATE_SUCCESS;
5841             }
5842         }
5843 
5844         // Otherwise store it
5845         CustomData newData;
5846         newData.type = carla_strdup(stype);
5847         newData.key  = carla_strdup(skey);
5848 
5849         if (type == kUridAtomString || type == kUridAtomPath)
5850             newData.value = carla_strdup((const char*)value);
5851         else
5852             newData.value = CarlaString::asBase64(value, size).dup();
5853 
5854         pData->custom.append(newData);
5855 
5856         return LV2_STATE_SUCCESS;
5857 
5858         // unused
5859         (void)flags;
5860     }
5861 
handleStateRetrieve(const uint32_t key,size_t * const size,uint32_t * const type,uint32_t * const flags)5862     const void* handleStateRetrieve(const uint32_t key, size_t* const size, uint32_t* const type, uint32_t* const flags)
5863     {
5864         CARLA_SAFE_ASSERT_RETURN(key != kUridNull, nullptr);
5865         CARLA_SAFE_ASSERT_RETURN(size != nullptr, nullptr);
5866         CARLA_SAFE_ASSERT_RETURN(type != nullptr, nullptr);
5867         CARLA_SAFE_ASSERT_RETURN(flags != nullptr, nullptr);
5868         carla_debug("CarlaPluginLV2::handleStateRetrieve(%i, %p, %p, %p)", key, size, type, flags);
5869 
5870         const char* const skey(carla_lv2_urid_unmap(this, key));
5871         CARLA_SAFE_ASSERT_RETURN(skey != nullptr && skey != kUnmapFallback, nullptr);
5872 
5873         const char* stype = nullptr;
5874         const char* stringData = nullptr;
5875 
5876         for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
5877         {
5878             const CustomData& cData(it.getValue(kCustomDataFallback));
5879             CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
5880 
5881             if (std::strcmp(cData.key, skey) == 0)
5882             {
5883                 stype      = cData.type;
5884                 stringData = cData.value;
5885                 break;
5886             }
5887         }
5888 
5889         if (stype == nullptr || stringData == nullptr)
5890         {
5891             carla_stderr("Plugin requested value for '%s' which is not available", skey);
5892             *size = *type = *flags = 0;
5893             return nullptr;
5894         }
5895 
5896         *type  = carla_lv2_urid_map(this, stype);
5897         *flags = LV2_STATE_IS_POD;
5898 
5899         if (*type == kUridAtomString || *type == kUridAtomPath)
5900         {
5901             *size = std::strlen(stringData);
5902             return stringData;
5903         }
5904 
5905         if (fLastStateChunk != nullptr)
5906         {
5907             std::free(fLastStateChunk);
5908             fLastStateChunk = nullptr;
5909         }
5910 
5911         std::vector<uint8_t> chunk(carla_getChunkFromBase64String(stringData));
5912         CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0, nullptr);
5913 
5914         fLastStateChunk = std::malloc(chunk.size());
5915         CARLA_SAFE_ASSERT_RETURN(fLastStateChunk != nullptr, nullptr);
5916 
5917 #ifdef CARLA_PROPER_CPP11_SUPPORT
5918         std::memcpy(fLastStateChunk, chunk.data(), chunk.size());
5919 #else
5920         std::memcpy(fLastStateChunk, &chunk.front(), chunk.size());
5921 #endif
5922 
5923         *size = chunk.size();
5924         return fLastStateChunk;
5925     }
5926 
5927     // -------------------------------------------------------------------
5928 
handleWorkerSchedule(const uint32_t size,const void * const data)5929     LV2_Worker_Status handleWorkerSchedule(const uint32_t size, const void* const data)
5930     {
5931         CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr, LV2_WORKER_ERR_UNKNOWN);
5932         CARLA_SAFE_ASSERT_RETURN(fEventsIn.ctrl != nullptr, LV2_WORKER_ERR_UNKNOWN);
5933         carla_debug("CarlaPluginLV2::handleWorkerSchedule(%i, %p)", size, data);
5934 
5935         if (pData->engine->isOffline())
5936         {
5937             fExt.worker->work(fHandle, carla_lv2_worker_respond, this, size, data);
5938             return LV2_WORKER_SUCCESS;
5939         }
5940 
5941         LV2_Atom atom;
5942         atom.size = size;
5943         atom.type = kUridCarlaAtomWorkerIn;
5944 
5945         return fAtomBufferWorkerIn.putChunk(&atom, data, fEventsOut.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
5946     }
5947 
handleWorkerRespond(const uint32_t size,const void * const data)5948     LV2_Worker_Status handleWorkerRespond(const uint32_t size, const void* const data)
5949     {
5950         CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work_response != nullptr, LV2_WORKER_ERR_UNKNOWN);
5951         carla_debug("CarlaPluginLV2::handleWorkerRespond(%i, %p)", size, data);
5952 
5953         LV2_Atom atom;
5954         atom.size = size;
5955         atom.type = kUridCarlaAtomWorkerResp;
5956 
5957         return fAtomBufferWorkerResp.putChunk(&atom, data, fEventsIn.ctrlIndex) ? LV2_WORKER_SUCCESS : LV2_WORKER_ERR_NO_SPACE;
5958     }
5959 
5960     // -------------------------------------------------------------------
5961 
handleInlineDisplayQueueRedraw()5962     void handleInlineDisplayQueueRedraw()
5963     {
5964         switch (pData->engine->getProccessMode())
5965         {
5966         case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
5967         case ENGINE_PROCESS_MODE_PATCHBAY:
5968             fInlineDisplayNeedsRedraw = true;
5969             break;
5970         default:
5971             break;
5972         }
5973     }
5974 
renderInlineDisplay(const uint32_t width,const uint32_t height) const5975     const LV2_Inline_Display_Image_Surface* renderInlineDisplay(const uint32_t width, const uint32_t height) const
5976     {
5977         CARLA_SAFE_ASSERT_RETURN(fExt.inlineDisplay != nullptr && fExt.inlineDisplay->render != nullptr, nullptr);
5978         CARLA_SAFE_ASSERT_RETURN(width > 0, nullptr);
5979         CARLA_SAFE_ASSERT_RETURN(height > 0, nullptr);
5980 
5981         return fExt.inlineDisplay->render(fHandle, width, height);
5982     }
5983 
5984     // -------------------------------------------------------------------
5985 
handleMidnamUpdate()5986     void handleMidnamUpdate()
5987     {
5988         CARLA_SAFE_ASSERT_RETURN(fExt.midnam != nullptr,);
5989 
5990         if (fEventsIn.ctrl == nullptr)
5991             return;
5992 
5993         char* const midnam = fExt.midnam->midnam(fHandle);
5994         CARLA_SAFE_ASSERT_RETURN(midnam != nullptr,);
5995 
5996         fEventsIn.ctrl->port->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd", midnam, "text/xml");
5997 
5998         if (fExt.midnam->free != nullptr)
5999             fExt.midnam->free(midnam);
6000     }
6001 
6002     // -------------------------------------------------------------------
6003 
handleExternalUIClosed()6004     void handleExternalUIClosed()
6005     {
6006         CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EXTERNAL,);
6007         carla_debug("CarlaPluginLV2::handleExternalUIClosed()");
6008 
6009         fNeedsUiClose = true;
6010     }
6011 
handlePluginUIClosed()6012     void handlePluginUIClosed() override
6013     {
6014         CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
6015         CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
6016         carla_debug("CarlaPluginLV2::handlePluginUIClosed()");
6017 
6018         fNeedsUiClose = true;
6019     }
6020 
handlePluginUIResized(const uint width,const uint height)6021     void handlePluginUIResized(const uint width, const uint height) override
6022     {
6023         CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,);
6024         CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
6025         carla_debug("CarlaPluginLV2::handlePluginUIResized(%u, %u)", width, height);
6026 
6027         if (fUI.handle != nullptr && fExt.uiresize != nullptr)
6028             fExt.uiresize->ui_resize(fUI.handle, static_cast<int>(width), static_cast<int>(height));
6029     }
6030 
6031     // -------------------------------------------------------------------
6032 
handleUIPortMap(const char * const symbol) const6033     uint32_t handleUIPortMap(const char* const symbol) const noexcept
6034     {
6035         CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', LV2UI_INVALID_PORT_INDEX);
6036         carla_debug("CarlaPluginLV2::handleUIPortMap(\"%s\")", symbol);
6037 
6038         for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
6039         {
6040             if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, symbol) == 0)
6041                 return i;
6042         }
6043 
6044         return LV2UI_INVALID_PORT_INDEX;
6045     }
6046 
handleUIRequestValue(const LV2_URID key,const LV2_URID type,const LV2_Feature * const * features)6047     LV2UI_Request_Value_Status handleUIRequestValue(const LV2_URID key,
6048                                                     const LV2_URID type,
6049                                                     const LV2_Feature* const* features)
6050     {
6051         CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
6052         carla_debug("CarlaPluginLV2::handleUIRequestValue(%u, %u, %p)", key, type, features);
6053 
6054         if (type != kUridAtomPath)
6055             return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
6056 
6057         const char* const uri = getCustomURIDString(key);
6058         CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
6059 
6060         // check if a file browser is already open
6061         if (fUI.fileNeededForURI != nullptr || fUI.fileBrowserOpen)
6062             return LV2UI_REQUEST_VALUE_BUSY;
6063 
6064         for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i)
6065         {
6066             if (fRdfDescriptor->Parameters[i].Type != LV2_PARAMETER_TYPE_PATH)
6067                 continue;
6068             if (std::strcmp(fRdfDescriptor->Parameters[i].URI, uri) != 0)
6069                 continue;
6070 
6071             // TODO file browser filters, also store label to use for title
6072             fUI.fileNeededForURI = uri;
6073 
6074             return LV2UI_REQUEST_VALUE_SUCCESS;
6075         }
6076 
6077         return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED;
6078 
6079         // may be unused
6080         (void)features;
6081     }
6082 
handleUIResize(const int width,const int height)6083     int handleUIResize(const int width, const int height)
6084     {
6085         CARLA_SAFE_ASSERT_RETURN(width > 0, 1);
6086         CARLA_SAFE_ASSERT_RETURN(height > 0, 1);
6087         carla_debug("CarlaPluginLV2::handleUIResize(%i, %i)", width, height);
6088 
6089         if (fUI.embedded)
6090         {
6091             pData->engine->callback(true, true,
6092                                     ENGINE_CALLBACK_EMBED_UI_RESIZED,
6093                                     pData->id, width, height,
6094                                     0, 0.0f, nullptr);
6095         }
6096         else
6097         {
6098             CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr, 1);
6099             fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true);
6100         }
6101 
6102         return 0;
6103     }
6104 
handleUITouch(const uint32_t rindex,const bool touch)6105     void handleUITouch(const uint32_t rindex, const bool touch)
6106     {
6107         carla_debug("CarlaPluginLV2::handleUITouch(%u, %s)", rindex, bool2str(touch));
6108 
6109         uint32_t index = LV2UI_INVALID_PORT_INDEX;
6110 
6111         for (uint32_t i=0; i < pData->param.count; ++i)
6112         {
6113             if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
6114                 continue;
6115             index = i;
6116             break;
6117         }
6118 
6119         CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
6120 
6121         pData->engine->touchPluginParameter(pData->id, index, touch);
6122     }
6123 
handleUIWrite(const uint32_t rindex,const uint32_t bufferSize,const uint32_t format,const void * const buffer)6124     void handleUIWrite(const uint32_t rindex, const uint32_t bufferSize, const uint32_t format, const void* const buffer)
6125     {
6126         CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
6127         CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,);
6128         carla_debug("CarlaPluginLV2::handleUIWrite(%i, %i, %i, %p)", rindex, bufferSize, format, buffer);
6129 
6130         uint32_t index = LV2UI_INVALID_PORT_INDEX;
6131 
6132         switch (format)
6133         {
6134         case kUridNull: {
6135             CARLA_SAFE_ASSERT_RETURN(rindex < fRdfDescriptor->PortCount,);
6136             CARLA_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),);
6137 
6138             for (uint32_t i=0; i < pData->param.count; ++i)
6139             {
6140                 if (pData->param.data[i].rindex != static_cast<int32_t>(rindex))
6141                     continue;
6142                 index = i;
6143                 break;
6144             }
6145 
6146             CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,);
6147 
6148             const float value(*(const float*)buffer);
6149 
6150             // check if we should feedback message back to UI
6151             bool sendGui = false;
6152 
6153             if (const uint32_t notifCount = fUI.rdfDescriptor->PortNotificationCount)
6154             {
6155                 const char* const portSymbol = fRdfDescriptor->Ports[rindex].Symbol;
6156 
6157                 for (uint32_t i=0; i < notifCount; ++i)
6158                 {
6159                     const LV2_RDF_UI_PortNotification& portNotif(fUI.rdfDescriptor->PortNotifications[i]);
6160 
6161                     if (portNotif.Protocol != LV2_UI_PORT_PROTOCOL_FLOAT)
6162                         continue;
6163 
6164                     if (portNotif.Symbol != nullptr)
6165                     {
6166                         if (std::strcmp(portNotif.Symbol, portSymbol) != 0)
6167                             continue;
6168                     }
6169                     else if (portNotif.Index != rindex)
6170                     {
6171                         continue;
6172                     }
6173 
6174                     sendGui = true;
6175                     break;
6176                 }
6177             }
6178 
6179             setParameterValue(index, value, sendGui, true, true);
6180 
6181         } break;
6182 
6183         case kUridAtomTransferAtom:
6184         case kUridAtomTransferEvent: {
6185             CARLA_SAFE_ASSERT_RETURN(bufferSize >= sizeof(LV2_Atom),);
6186 
6187             const LV2_Atom* const atom((const LV2_Atom*)buffer);
6188 
6189             // plugins sometimes fail on this, not good...
6190             const uint32_t totalSize = lv2_atom_total_size(atom);
6191             const uint32_t paddedSize = lv2_atom_pad_size(totalSize);
6192 
6193             if (bufferSize != totalSize && bufferSize != paddedSize)
6194                 carla_stderr2("Warning: LV2 UI sending atom with invalid size %u! size: %u, padded-size: %u",
6195                               bufferSize, totalSize, paddedSize);
6196 
6197             for (uint32_t i=0; i < fEventsIn.count; ++i)
6198             {
6199                 if (fEventsIn.data[i].rindex != rindex)
6200                     continue;
6201                 index = i;
6202                 break;
6203             }
6204 
6205             // for bad plugins
6206             if (index == LV2UI_INVALID_PORT_INDEX)
6207             {
6208                 CARLA_SAFE_ASSERT(index != LV2UI_INVALID_PORT_INDEX); // FIXME
6209                 index = fEventsIn.ctrlIndex;
6210             }
6211 
6212             fAtomBufferEvIn.put(atom, index);
6213         } break;
6214 
6215         default:
6216             carla_stdout("CarlaPluginLV2::handleUIWrite(%i, %i, %i:\"%s\", %p) - unknown format",
6217                          rindex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer);
6218             break;
6219         }
6220     }
6221 
handleUIBridgeParameter(const char * const uri,const float value)6222     void handleUIBridgeParameter(const char* const uri, const float value)
6223     {
6224         CARLA_SAFE_ASSERT_RETURN(uri != nullptr,);
6225         carla_debug("CarlaPluginLV2::handleUIBridgeParameter(%s, %f)", uri, static_cast<double>(value));
6226 
6227         uint32_t parameterId;
6228 
6229         if (getParameterIndexForURI(uri, parameterId))
6230             setParameterValue(parameterId, value, false, true, true);
6231     }
6232 
6233     // -------------------------------------------------------------------
6234 
handleLilvSetPortValue(const char * const portSymbol,const void * const value,const uint32_t size,const uint32_t type)6235     void handleLilvSetPortValue(const char* const portSymbol, const void* const value, const uint32_t size, const uint32_t type)
6236     {
6237         CARLA_SAFE_ASSERT_RETURN(portSymbol != nullptr && portSymbol[0] != '\0',);
6238         CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
6239         CARLA_SAFE_ASSERT_RETURN(size > 0,);
6240         CARLA_SAFE_ASSERT_RETURN(type != kUridNull,);
6241         carla_debug("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i)", portSymbol, value, size, type);
6242 
6243         int32_t rindex = -1;
6244 
6245         for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
6246         {
6247             if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, portSymbol) == 0)
6248             {
6249                 rindex = static_cast<int32_t>(i);
6250                 break;
6251             }
6252         }
6253 
6254         CARLA_SAFE_ASSERT_RETURN(rindex >= 0,);
6255 
6256         float paramValue;
6257 
6258         switch (type)
6259         {
6260         case kUridAtomBool:
6261             CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
6262             paramValue = *(const int32_t*)value != 0 ? 1.0f : 0.0f;
6263             break;
6264         case kUridAtomDouble:
6265             CARLA_SAFE_ASSERT_RETURN(size == sizeof(double),);
6266             paramValue = static_cast<float>((*(const double*)value));
6267             break;
6268         case kUridAtomFloat:
6269             CARLA_SAFE_ASSERT_RETURN(size == sizeof(float),);
6270             paramValue = *(const float*)value;
6271             break;
6272         case kUridAtomInt:
6273             CARLA_SAFE_ASSERT_RETURN(size == sizeof(int32_t),);
6274             paramValue = static_cast<float>(*(const int32_t*)value);
6275             break;
6276         case kUridAtomLong:
6277             CARLA_SAFE_ASSERT_RETURN(size == sizeof(int64_t),);
6278             paramValue = static_cast<float>(*(const int64_t*)value);
6279             break;
6280         default:
6281             carla_stdout("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i:\"%s\") - unknown type",
6282                          portSymbol, value, size, type, carla_lv2_urid_unmap(this, type));
6283             return;
6284         }
6285 
6286         for (uint32_t i=0; i < pData->param.count; ++i)
6287         {
6288             if (pData->param.data[i].rindex == rindex)
6289             {
6290                 setParameterValueRT(i, paramValue, true);
6291                 break;
6292             }
6293         }
6294     }
6295 
6296     // -------------------------------------------------------------------
6297 
getNativeHandle() const6298     void* getNativeHandle() const noexcept override
6299     {
6300         return fHandle;
6301     }
6302 
getNativeDescriptor() const6303     const void* getNativeDescriptor() const noexcept override
6304     {
6305         return fDescriptor;
6306     }
6307 
getUiBridgeProcessId() const6308     uintptr_t getUiBridgeProcessId() const noexcept override
6309     {
6310         return fPipeServer.isPipeRunning() ? fPipeServer.getPID() : 0;
6311     }
6312 
6313     // -------------------------------------------------------------------
6314 
6315 public:
init(const CarlaPluginPtr plugin,const char * const name,const char * const uri,const uint options,const char * & needsArchBridge)6316     bool init(const CarlaPluginPtr plugin,
6317               const char* const name, const char* const uri, const uint options,
6318               const char*& needsArchBridge)
6319     {
6320         CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
6321 
6322         // ---------------------------------------------------------------
6323         // first checks
6324 
6325         if (pData->client != nullptr)
6326         {
6327             pData->engine->setLastError("Plugin client is already registered");
6328             return false;
6329         }
6330 
6331         if (uri == nullptr || uri[0] == '\0')
6332         {
6333             pData->engine->setLastError("null uri");
6334             return false;
6335         }
6336 
6337         const EngineOptions& opts(pData->engine->getOptions());
6338 
6339         // ---------------------------------------------------------------
6340         // Init LV2 World if needed, sets LV2_PATH for lilv
6341 
6342         Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
6343 
6344         if (opts.pathLV2 != nullptr && opts.pathLV2[0] != '\0')
6345             lv2World.initIfNeeded(opts.pathLV2);
6346         else if (const char* const LV2_PATH = std::getenv("LV2_PATH"))
6347             lv2World.initIfNeeded(LV2_PATH);
6348         else
6349             lv2World.initIfNeeded(LILV_DEFAULT_LV2_PATH);
6350 
6351         // ---------------------------------------------------------------
6352         // get plugin from lv2_rdf (lilv)
6353 
6354         fRdfDescriptor = lv2_rdf_new(uri, true);
6355 
6356         if (fRdfDescriptor == nullptr)
6357         {
6358             pData->engine->setLastError("Failed to find the requested plugin");
6359             return false;
6360         }
6361 
6362 #ifdef ADAPT_FOR_APPLE_SILLICON
6363         // ---------------------------------------------------------------
6364         // check if we can open this binary, might need a bridge
6365 
6366         {
6367             const CarlaMagic magic;
6368 
6369             if (const char* const output = magic.getFileDescription(fRdfDescriptor->Binary))
6370             {
6371 # ifdef __aarch64__
6372                 if (std::strstr(output, "arm64") == nullptr && std::strstr(output, "x86_64") != nullptr)
6373                     needsArchBridge = "x86_64";
6374 # else
6375                 if (std::strstr(output, "x86_64") == nullptr && std::strstr(output, "arm64") != nullptr)
6376                     needsArchBridge = "arm64";
6377 # endif
6378                 if (needsArchBridge != nullptr)
6379                     return false;
6380             }
6381         }
6382 #endif // ADAPT_FOR_APPLE_SILLICON
6383 
6384         // ---------------------------------------------------------------
6385         // open DLL
6386 
6387 #ifdef CARLA_OS_MAC
6388         // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
6389         removeFileFromQuarantine(fRdfDescriptor->Binary);
6390 #endif
6391 
6392         if (! pData->libOpen(fRdfDescriptor->Binary))
6393         {
6394             pData->engine->setLastError(pData->libError(fRdfDescriptor->Binary));
6395             return false;
6396         }
6397 
6398         // ---------------------------------------------------------------
6399         // try to get DLL main entry via new mode
6400 
6401         if (const LV2_Lib_Descriptor_Function libDescFn = pData->libSymbol<LV2_Lib_Descriptor_Function>("lv2_lib_descriptor"))
6402         {
6403             // -----------------------------------------------------------
6404             // all ok, get lib descriptor
6405 
6406             const LV2_Lib_Descriptor* const libDesc = libDescFn(fRdfDescriptor->Bundle, nullptr);
6407 
6408             if (libDesc == nullptr)
6409             {
6410                 pData->engine->setLastError("Could not find the LV2 Descriptor");
6411                 return false;
6412             }
6413 
6414             // -----------------------------------------------------------
6415             // get descriptor that matches URI (new mode)
6416 
6417             uint32_t i = 0;
6418             while ((fDescriptor = libDesc->get_plugin(libDesc->handle, i++)))
6419             {
6420                 if (std::strcmp(fDescriptor->URI, uri) == 0)
6421                     break;
6422             }
6423         }
6424         else
6425         {
6426             // -----------------------------------------------------------
6427             // get DLL main entry (old mode)
6428 
6429             const LV2_Descriptor_Function descFn = pData->libSymbol<LV2_Descriptor_Function>("lv2_descriptor");
6430 
6431             if (descFn == nullptr)
6432             {
6433                 pData->engine->setLastError("Could not find the LV2 Descriptor in the plugin library");
6434                 return false;
6435             }
6436 
6437             // -----------------------------------------------------------
6438             // get descriptor that matches URI (old mode)
6439 
6440             uint32_t i = 0;
6441             while ((fDescriptor = descFn(i++)))
6442             {
6443                 if (std::strcmp(fDescriptor->URI, uri) == 0)
6444                     break;
6445             }
6446         }
6447 
6448         if (fDescriptor == nullptr)
6449         {
6450             pData->engine->setLastError("Could not find the requested plugin URI in the plugin library");
6451             return false;
6452         }
6453 
6454         // ---------------------------------------------------------------
6455         // check supported port-types and features
6456 
6457         bool canContinue = true;
6458 
6459         // Check supported ports
6460         for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
6461         {
6462             const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
6463 
6464             if (! is_lv2_port_supported(portTypes))
6465             {
6466                 if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor->Ports[j].Properties))
6467                 {
6468                     pData->engine->setLastError("Plugin requires a port type that is not currently supported");
6469                     canContinue = false;
6470                     break;
6471                 }
6472             }
6473         }
6474 
6475         // Check supported features
6476         for (uint32_t j=0; j < fRdfDescriptor->FeatureCount && canContinue; ++j)
6477         {
6478             const LV2_RDF_Feature& feature(fRdfDescriptor->Features[j]);
6479 
6480             if (std::strcmp(feature.URI, LV2_DATA_ACCESS_URI) == 0 || std::strcmp(feature.URI, LV2_INSTANCE_ACCESS_URI) == 0)
6481             {
6482                 carla_stderr("Plugin DSP wants UI feature '%s', ignoring this", feature.URI);
6483             }
6484             else if (std::strcmp(feature.URI, LV2_BUF_SIZE__fixedBlockLength) == 0)
6485             {
6486                 fNeedsFixedBuffers = true;
6487             }
6488             else if (std::strcmp(feature.URI, LV2_PORT_PROPS__supportsStrictBounds) == 0)
6489             {
6490                 fStrictBounds = feature.Required ? 1 : 0;
6491             }
6492             else if (std::strcmp(feature.URI, LV2_STATE__loadDefaultState) == 0)
6493             {
6494                 fHasLoadDefaultState = true;
6495             }
6496             else if (std::strcmp(feature.URI, LV2_STATE__threadSafeRestore) == 0)
6497             {
6498                 fHasThreadSafeRestore = true;
6499             }
6500             else if (feature.Required && ! is_lv2_feature_supported(feature.URI))
6501             {
6502                 CarlaString msg("Plugin wants a feature that is not supported:\n");
6503                 msg += feature.URI;
6504 
6505                 canContinue = false;
6506                 pData->engine->setLastError(msg);
6507                 break;
6508             }
6509         }
6510 
6511         if (! canContinue)
6512         {
6513             // error already set
6514             return false;
6515         }
6516 
6517         if (fNeedsFixedBuffers && ! pData->engine->usesConstantBufferSize())
6518         {
6519             pData->engine->setLastError("Cannot use this plugin under the current engine.\n"
6520                                         "The plugin requires a fixed block size which is not possible right now.");
6521             return false;
6522         }
6523 
6524         // ---------------------------------------------------------------
6525         // set icon
6526 
6527         if (std::strncmp(fDescriptor->URI, "http://distrho.sf.net/", 22) == 0)
6528             pData->iconName = carla_strdup_safe("distrho");
6529 
6530         // ---------------------------------------------------------------
6531         // set info
6532 
6533         if (name != nullptr && name[0] != '\0')
6534             pData->name = pData->engine->getUniquePluginName(name);
6535         else
6536             pData->name = pData->engine->getUniquePluginName(fRdfDescriptor->Name);
6537 
6538         // ---------------------------------------------------------------
6539         // register client
6540 
6541         pData->client = pData->engine->addClient(plugin);
6542 
6543         if (pData->client == nullptr || ! pData->client->isOk())
6544         {
6545             pData->engine->setLastError("Failed to register plugin client");
6546             return false;
6547         }
6548 
6549         // ---------------------------------------------------------------
6550         // initialize options
6551 
6552         const int bufferSize = static_cast<int>(pData->engine->getBufferSize());
6553 
6554         fLv2Options.minBufferSize     = fNeedsFixedBuffers ? bufferSize : 1;
6555         fLv2Options.maxBufferSize     = bufferSize;
6556         fLv2Options.nominalBufferSize = bufferSize;
6557         fLv2Options.sampleRate        = static_cast<float>(pData->engine->getSampleRate());
6558         fLv2Options.transientWinId    = static_cast<int64_t>(opts.frontendWinId);
6559 
6560         uint32_t eventBufferSize = MAX_DEFAULT_BUFFER_SIZE;
6561 
6562         for (uint32_t j=0; j < fRdfDescriptor->PortCount; ++j)
6563         {
6564             const LV2_Property portTypes(fRdfDescriptor->Ports[j].Types);
6565 
6566             if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
6567             {
6568                 if (fRdfDescriptor->Ports[j].MinimumSize > eventBufferSize)
6569                     eventBufferSize = fRdfDescriptor->Ports[j].MinimumSize;
6570             }
6571         }
6572 
6573         fLv2Options.sequenceSize = static_cast<int>(eventBufferSize);
6574 
6575         fLv2Options.bgColor = opts.bgColor;
6576         fLv2Options.fgColor = opts.fgColor;
6577         fLv2Options.uiScale = opts.uiScale;
6578 
6579         // ---------------------------------------------------------------
6580         // initialize features (part 1)
6581 
6582         LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
6583         eventFt->callback_data           = this;
6584         eventFt->lv2_event_ref           = carla_lv2_event_ref;
6585         eventFt->lv2_event_unref         = carla_lv2_event_unref;
6586 
6587         LV2_Log_Log* const logFt = new LV2_Log_Log;
6588         logFt->handle            = this;
6589         logFt->printf            = carla_lv2_log_printf;
6590         logFt->vprintf           = carla_lv2_log_vprintf;
6591 
6592         LV2_State_Free_Path* const stateFreePathFt = new LV2_State_Free_Path;
6593         stateFreePathFt->handle                    = this;
6594         stateFreePathFt->free_path                 = carla_lv2_state_free_path;
6595 
6596         LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
6597         stateMakePathFt->handle                    = this;
6598         stateMakePathFt->path                      = carla_lv2_state_make_path_tmp;
6599 
6600         LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
6601         stateMapPathFt->handle                   = this;
6602         stateMapPathFt->abstract_path            = carla_lv2_state_map_to_abstract_path_tmp;
6603         stateMapPathFt->absolute_path            = carla_lv2_state_map_to_absolute_path_tmp;
6604 
6605         LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
6606         programsFt->handle                  = this;
6607         programsFt->program_changed         = carla_lv2_program_changed;
6608 
6609         LV2_Resize_Port_Resize* const rsPortFt = new LV2_Resize_Port_Resize;
6610         rsPortFt->data                         = this;
6611         rsPortFt->resize                       = carla_lv2_resize_port;
6612 
6613         LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
6614         lv2_rtmempool_init(rtMemPoolFt);
6615 
6616         LV2_RtMemPool_Pool_Deprecated* const rtMemPoolOldFt = new LV2_RtMemPool_Pool_Deprecated;
6617         lv2_rtmempool_init_deprecated(rtMemPoolOldFt);
6618 
6619         LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
6620         uriMapFt->callback_data             = this;
6621         uriMapFt->uri_to_id                 = carla_lv2_uri_to_id;
6622 
6623         LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
6624         uridMapFt->handle             = this;
6625         uridMapFt->map                = carla_lv2_urid_map;
6626 
6627         LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
6628         uridUnmapFt->handle               = this;
6629         uridUnmapFt->unmap                = carla_lv2_urid_unmap;
6630 
6631         LV2_Worker_Schedule* const workerFt = new LV2_Worker_Schedule;
6632         workerFt->handle                    = this;
6633         workerFt->schedule_work             = carla_lv2_worker_schedule;
6634 
6635         LV2_Inline_Display* const inlineDisplay = new LV2_Inline_Display;
6636         inlineDisplay->handle                   = this;
6637         inlineDisplay->queue_draw               = carla_lv2_inline_display_queue_draw;
6638 
6639         LV2_Midnam* const midnam = new LV2_Midnam;
6640         midnam->handle = this;
6641         midnam->update = carla_lv2_midnam_update;
6642 
6643         // ---------------------------------------------------------------
6644         // initialize features (part 2)
6645 
6646         for (uint32_t j=0; j < kFeatureCountPlugin; ++j)
6647             fFeatures[j] = new LV2_Feature;
6648 
6649         fFeatures[kFeatureIdBufSizeBounded]->URI   = LV2_BUF_SIZE__boundedBlockLength;
6650         fFeatures[kFeatureIdBufSizeBounded]->data  = nullptr;
6651 
6652         fFeatures[kFeatureIdBufSizeFixed]->URI     = fNeedsFixedBuffers
6653                                                    ? LV2_BUF_SIZE__fixedBlockLength
6654                                                    : LV2_BUF_SIZE__boundedBlockLength;
6655         fFeatures[kFeatureIdBufSizeFixed]->data    = nullptr;
6656 
6657         fFeatures[kFeatureIdBufSizePowerOf2]->URI  = LV2_BUF_SIZE__powerOf2BlockLength;
6658         fFeatures[kFeatureIdBufSizePowerOf2]->data = nullptr;
6659 
6660         fFeatures[kFeatureIdEvent]->URI          = LV2_EVENT_URI;
6661         fFeatures[kFeatureIdEvent]->data         = eventFt;
6662 
6663         fFeatures[kFeatureIdHardRtCapable]->URI  = LV2_CORE__hardRTCapable;
6664         fFeatures[kFeatureIdHardRtCapable]->data = nullptr;
6665 
6666         fFeatures[kFeatureIdInPlaceBroken]->URI  = LV2_CORE__inPlaceBroken;
6667         fFeatures[kFeatureIdInPlaceBroken]->data = nullptr;
6668 
6669         fFeatures[kFeatureIdIsLive]->URI         = LV2_CORE__isLive;
6670         fFeatures[kFeatureIdIsLive]->data        = nullptr;
6671 
6672         fFeatures[kFeatureIdLogs]->URI       = LV2_LOG__log;
6673         fFeatures[kFeatureIdLogs]->data      = logFt;
6674 
6675         fFeatures[kFeatureIdOptions]->URI    = LV2_OPTIONS__options;
6676         fFeatures[kFeatureIdOptions]->data   = fLv2Options.opts;
6677 
6678         fFeatures[kFeatureIdPrograms]->URI   = LV2_PROGRAMS__Host;
6679         fFeatures[kFeatureIdPrograms]->data  = programsFt;
6680 
6681         fFeatures[kFeatureIdResizePort]->URI   = LV2_RESIZE_PORT__resize;
6682         fFeatures[kFeatureIdResizePort]->data  = rsPortFt;
6683 
6684         fFeatures[kFeatureIdRtMemPool]->URI  = LV2_RTSAFE_MEMORY_POOL__Pool;
6685         fFeatures[kFeatureIdRtMemPool]->data = rtMemPoolFt;
6686 
6687         fFeatures[kFeatureIdRtMemPoolOld]->URI  = LV2_RTSAFE_MEMORY_POOL_DEPRECATED_URI;
6688         fFeatures[kFeatureIdRtMemPoolOld]->data = rtMemPoolOldFt;
6689 
6690         fFeatures[kFeatureIdStateFreePath]->URI  = LV2_STATE__freePath;
6691         fFeatures[kFeatureIdStateFreePath]->data = stateFreePathFt;
6692 
6693         fFeatures[kFeatureIdStateMakePath]->URI  = LV2_STATE__makePath;
6694         fFeatures[kFeatureIdStateMakePath]->data = stateMakePathFt;
6695 
6696         fFeatures[kFeatureIdStateMapPath]->URI   = LV2_STATE__mapPath;
6697         fFeatures[kFeatureIdStateMapPath]->data  = stateMapPathFt;
6698 
6699         fFeatures[kFeatureIdStrictBounds]->URI   = LV2_PORT_PROPS__supportsStrictBounds;
6700         fFeatures[kFeatureIdStrictBounds]->data  = nullptr;
6701 
6702         fFeatures[kFeatureIdUriMap]->URI     = LV2_URI_MAP_URI;
6703         fFeatures[kFeatureIdUriMap]->data    = uriMapFt;
6704 
6705         fFeatures[kFeatureIdUridMap]->URI    = LV2_URID__map;
6706         fFeatures[kFeatureIdUridMap]->data   = uridMapFt;
6707 
6708         fFeatures[kFeatureIdUridUnmap]->URI  = LV2_URID__unmap;
6709         fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;
6710 
6711         fFeatures[kFeatureIdWorker]->URI     = LV2_WORKER__schedule;
6712         fFeatures[kFeatureIdWorker]->data    = workerFt;
6713 
6714         fFeatures[kFeatureIdInlineDisplay]->URI  = LV2_INLINEDISPLAY__queue_draw;
6715         fFeatures[kFeatureIdInlineDisplay]->data = inlineDisplay;
6716 
6717         fFeatures[kFeatureIdMidnam]->URI  = LV2_MIDNAM__update;
6718         fFeatures[kFeatureIdMidnam]->data = midnam;
6719 
6720         // ---------------------------------------------------------------
6721         // initialize features (part 3)
6722 
6723         LV2_State_Make_Path* const stateMakePathFt2 = new LV2_State_Make_Path;
6724         stateMakePathFt2->handle                    = this;
6725         stateMakePathFt2->path                      = carla_lv2_state_make_path_real;
6726 
6727         LV2_State_Map_Path* const stateMapPathFt2 = new LV2_State_Map_Path;
6728         stateMapPathFt2->handle                   = this;
6729         stateMapPathFt2->abstract_path            = carla_lv2_state_map_to_abstract_path_real;
6730         stateMapPathFt2->absolute_path            = carla_lv2_state_map_to_absolute_path_real;
6731 
6732         for (uint32_t j=0; j < kStateFeatureCountAll; ++j)
6733             fStateFeatures[j] = new LV2_Feature;
6734 
6735         fStateFeatures[kStateFeatureIdFreePath]->URI  = LV2_STATE__freePath;
6736         fStateFeatures[kStateFeatureIdFreePath]->data = stateFreePathFt;
6737 
6738         fStateFeatures[kStateFeatureIdMakePath]->URI  = LV2_STATE__makePath;
6739         fStateFeatures[kStateFeatureIdMakePath]->data = stateMakePathFt2;
6740 
6741         fStateFeatures[kStateFeatureIdMapPath]->URI   = LV2_STATE__mapPath;
6742         fStateFeatures[kStateFeatureIdMapPath]->data  = stateMapPathFt2;
6743 
6744         fStateFeatures[kStateFeatureIdWorker]->URI     = LV2_WORKER__schedule;
6745         fStateFeatures[kStateFeatureIdWorker]->data    = workerFt;
6746 
6747         // ---------------------------------------------------------------
6748         // initialize plugin
6749 
6750         try {
6751             fHandle = fDescriptor->instantiate(fDescriptor, pData->engine->getSampleRate(), fRdfDescriptor->Bundle, fFeatures);
6752         } catch(...) {}
6753 
6754         if (fHandle == nullptr)
6755         {
6756             pData->engine->setLastError("Plugin failed to initialize");
6757             return false;
6758         }
6759 
6760         recheckExtensions();
6761 
6762         // ---------------------------------------------------------------
6763         // set options
6764 
6765         pData->options = 0x0;
6766 
6767         if (fLatencyIndex >= 0 || getMidiOutCount() != 0 || fNeedsFixedBuffers)
6768             pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
6769         else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
6770             pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
6771 
6772         if (opts.forceStereo)
6773             pData->options |= PLUGIN_OPTION_FORCE_STEREO;
6774         else if (options & PLUGIN_OPTION_FORCE_STEREO)
6775             pData->options |= PLUGIN_OPTION_FORCE_STEREO;
6776 
6777         if (getMidiInCount() != 0)
6778         {
6779             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
6780                 pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
6781             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
6782                 pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
6783             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
6784                 pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
6785             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
6786                 pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
6787             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
6788                 pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
6789             if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PROGRAM_CHANGES))
6790                 pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
6791             if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
6792                 pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
6793         }
6794 
6795         if (fExt.programs != nullptr && (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0)
6796         {
6797             if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
6798                 pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
6799         }
6800 
6801         // ---------------------------------------------------------------
6802         // gui stuff
6803 
6804         if (fRdfDescriptor->UICount != 0)
6805             initUi();
6806 
6807         return true;
6808 
6809         // might be unused
6810         (void)needsArchBridge;
6811     }
6812 
6813     // -------------------------------------------------------------------
6814 
initUi()6815     void initUi()
6816     {
6817         // ---------------------------------------------------------------
6818         // find the most appropriate ui
6819 
6820         int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eMod, iCocoa, iWindows, iX11, iExt, iFinal;
6821         eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eMod = iCocoa = iWindows = iX11 = iExt = iFinal = -1;
6822 
6823 #if defined(LV2_UIS_ONLY_BRIDGES)
6824         const bool preferUiBridges = true;
6825 #elif defined(BUILD_BRIDGE)
6826         const bool preferUiBridges = false;
6827 #else
6828         const bool preferUiBridges = pData->engine->getOptions().preferUiBridges;
6829 #endif
6830         bool hasShowInterface = false;
6831 
6832         for (uint32_t i=0; i < fRdfDescriptor->UICount; ++i)
6833         {
6834             CARLA_SAFE_ASSERT_CONTINUE(fRdfDescriptor->UIs[i].URI != nullptr);
6835 
6836             const int ii(static_cast<int>(i));
6837 
6838             switch (fRdfDescriptor->UIs[i].Type)
6839             {
6840             case LV2_UI_QT4:
6841                 if (isUiBridgeable(i))
6842                     eQt4 = ii;
6843                 break;
6844             case LV2_UI_QT5:
6845                 if (isUiBridgeable(i))
6846                     eQt5 = ii;
6847                 break;
6848             case LV2_UI_GTK2:
6849                 if (isUiBridgeable(i))
6850                     eGtk2 = ii;
6851                 break;
6852             case LV2_UI_GTK3:
6853                 if (isUiBridgeable(i))
6854                     eGtk3 = ii;
6855                 break;
6856 #ifdef CARLA_OS_MAC
6857             case LV2_UI_COCOA:
6858                 if (isUiBridgeable(i) && preferUiBridges)
6859                     eCocoa = ii;
6860                 iCocoa = ii;
6861                 break;
6862 #endif
6863 #ifdef CARLA_OS_WIN
6864             case LV2_UI_WINDOWS:
6865                 if (isUiBridgeable(i) && preferUiBridges)
6866                     eWindows = ii;
6867                 iWindows = ii;
6868                 break;
6869 #endif
6870             case LV2_UI_X11:
6871                 if (isUiBridgeable(i) && preferUiBridges)
6872                     eX11 = ii;
6873                 iX11 = ii;
6874                 break;
6875             case LV2_UI_EXTERNAL:
6876             case LV2_UI_OLD_EXTERNAL:
6877                 iExt = ii;
6878                 break;
6879             case LV2_UI_MOD:
6880                 eMod = ii;
6881                 break;
6882             default:
6883                 break;
6884             }
6885         }
6886 
6887         /**/ if (eQt4 >= 0)
6888             iFinal = eQt4;
6889         else if (eQt5 >= 0)
6890             iFinal = eQt5;
6891         else if (eGtk2 >= 0)
6892             iFinal = eGtk2;
6893         else if (eGtk3 >= 0)
6894             iFinal = eGtk3;
6895 #ifdef CARLA_OS_MAC
6896         else if (eCocoa >= 0)
6897             iFinal = eCocoa;
6898 #endif
6899 #ifdef CARLA_OS_WIN
6900         else if (eWindows >= 0)
6901             iFinal = eWindows;
6902 #endif
6903 #ifdef HAVE_X11
6904         else if (eX11 >= 0)
6905             iFinal = eX11;
6906 #endif
6907 #ifndef LV2_UIS_ONLY_BRIDGES
6908 # ifdef CARLA_OS_MAC
6909         else if (iCocoa >= 0)
6910             iFinal = iCocoa;
6911 # endif
6912 # ifdef CARLA_OS_WIN
6913         else if (iWindows >= 0)
6914             iFinal = iWindows;
6915 # endif
6916 # ifdef HAVE_X11
6917         else if (iX11 >= 0)
6918             iFinal = iX11;
6919 # endif
6920 #endif
6921         else if (iExt >= 0)
6922             iFinal = iExt;
6923 
6924 #ifndef BUILD_BRIDGE
6925         if (iFinal < 0)
6926 #endif
6927         {
6928             // no suitable UI found, see if there's one which supports ui:showInterface
6929             for (uint32_t i=0; i < fRdfDescriptor->UICount && ! hasShowInterface; ++i)
6930             {
6931                 LV2_RDF_UI* const ui(&fRdfDescriptor->UIs[i]);
6932 
6933                 for (uint32_t j=0; j < ui->ExtensionCount; ++j)
6934                 {
6935                     CARLA_SAFE_ASSERT_CONTINUE(ui->Extensions[j] != nullptr);
6936 
6937                     if (std::strcmp(ui->Extensions[j], LV2_UI__showInterface) != 0)
6938                         continue;
6939 
6940                     iFinal = static_cast<int>(i);
6941                     hasShowInterface = true;
6942                     break;
6943                 }
6944             }
6945 
6946             if (iFinal < 0)
6947             {
6948                 if (eMod < 0)
6949                 {
6950                     carla_stderr("Failed to find an appropriate LV2 UI for this plugin");
6951                     return;
6952                 }
6953 
6954                 // use MODGUI as last resort
6955                 iFinal = eMod;
6956             }
6957         }
6958 
6959         fUI.rdfDescriptor = &fRdfDescriptor->UIs[iFinal];
6960 
6961         // ---------------------------------------------------------------
6962         // check supported ui features
6963 
6964         bool canContinue = true;
6965         bool canDelete = true;
6966 
6967         for (uint32_t i=0; i < fUI.rdfDescriptor->FeatureCount; ++i)
6968         {
6969             const char* const uri(fUI.rdfDescriptor->Features[i].URI);
6970             CARLA_SAFE_ASSERT_CONTINUE(uri != nullptr && uri[0] != '\0');
6971 
6972             if (! is_lv2_ui_feature_supported(uri))
6973             {
6974                 if (fUI.rdfDescriptor->Features[i].Required)
6975                 {
6976                     carla_stderr("Plugin UI requires a feature that is not supported:\n%s", uri);
6977                     canContinue = false;
6978                     break;
6979                 }
6980 
6981                 carla_stderr("Plugin UI wants a feature that is not supported (ignored):\n%s", uri);
6982             }
6983 
6984             if (std::strcmp(uri, LV2_UI__makeResident) == 0 || std::strcmp(uri, LV2_UI__makeSONameResident) == 0)
6985                 canDelete = false;
6986             else if (std::strcmp(uri, LV2_UI__requestValue) == 0)
6987                 pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
6988         }
6989 
6990         if (! canContinue)
6991         {
6992             fUI.rdfDescriptor = nullptr;
6993             return;
6994         }
6995 
6996         // ---------------------------------------------------------------
6997         // initialize ui according to type
6998 
6999         const LV2_Property uiType(fUI.rdfDescriptor->Type);
7000 
7001         if (
7002             (iFinal == eQt4     ||
7003              iFinal == eQt5     ||
7004              iFinal == eGtk2    ||
7005              iFinal == eGtk3    ||
7006              iFinal == eCocoa   ||
7007              iFinal == eWindows ||
7008              iFinal == eX11     ||
7009              iFinal == eMod)
7010 #ifdef BUILD_BRIDGE
7011             && ! hasShowInterface
7012 #endif
7013             )
7014         {
7015             // -----------------------------------------------------------
7016             // initialize ui-bridge
7017 
7018             if (const char* const bridgeBinary = getUiBridgeBinary(uiType))
7019             {
7020                 carla_stdout("Will use UI-Bridge for '%s', binary: \"%s\"", pData->name, bridgeBinary);
7021 
7022                 CarlaString uiTitle;
7023 
7024                 if (pData->uiTitle.isNotEmpty())
7025                 {
7026                     uiTitle = pData->uiTitle;
7027                 }
7028                 else
7029                 {
7030                     uiTitle = pData->name;
7031                     uiTitle += " (GUI)";
7032                 }
7033 
7034                 fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
7035 
7036                 fUI.type = UI::TYPE_BRIDGE;
7037                 fPipeServer.setData(bridgeBinary, fRdfDescriptor->URI, fUI.rdfDescriptor->URI);
7038 
7039                 delete[] bridgeBinary;
7040                 return;
7041             }
7042 
7043             if (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || iFinal == eMod)
7044             {
7045                 carla_stderr2("Failed to find UI bridge binary for '%s', cannot use UI", pData->name);
7046                 fUI.rdfDescriptor = nullptr;
7047                 return;
7048             }
7049         }
7050 
7051 #ifdef LV2_UIS_ONLY_BRIDGES
7052         carla_stderr2("Failed to get an UI working, canBridge:%s", bool2str(isUiBridgeable(static_cast<uint32_t>(iFinal))));
7053         fUI.rdfDescriptor = nullptr;
7054         return;
7055 #endif
7056 
7057         // ---------------------------------------------------------------
7058         // open UI DLL
7059 
7060 #ifdef CARLA_OS_MAC
7061         // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
7062         removeFileFromQuarantine(fUI.rdfDescriptor->Binary);
7063 #endif
7064 
7065         if (! pData->uiLibOpen(fUI.rdfDescriptor->Binary, canDelete))
7066         {
7067             carla_stderr2("Could not load UI library, error was:\n%s", pData->libError(fUI.rdfDescriptor->Binary));
7068             fUI.rdfDescriptor = nullptr;
7069             return;
7070         }
7071 
7072         // ---------------------------------------------------------------
7073         // get UI DLL main entry
7074 
7075         LV2UI_DescriptorFunction uiDescFn = pData->uiLibSymbol<LV2UI_DescriptorFunction>("lv2ui_descriptor");
7076 
7077         if (uiDescFn == nullptr)
7078         {
7079             carla_stderr2("Could not find the LV2UI Descriptor in the UI library");
7080             pData->uiLibClose();
7081             fUI.rdfDescriptor = nullptr;
7082             return;
7083         }
7084 
7085         // ---------------------------------------------------------------
7086         // get UI descriptor that matches UI URI
7087 
7088         uint32_t i = 0;
7089         while ((fUI.descriptor = uiDescFn(i++)))
7090         {
7091             if (std::strcmp(fUI.descriptor->URI, fUI.rdfDescriptor->URI) == 0)
7092                 break;
7093         }
7094 
7095         if (fUI.descriptor == nullptr)
7096         {
7097             carla_stderr2("Could not find the requested GUI in the plugin UI library");
7098             pData->uiLibClose();
7099             fUI.rdfDescriptor = nullptr;
7100             return;
7101         }
7102 
7103         // ---------------------------------------------------------------
7104         // check if ui is usable
7105 
7106         switch (uiType)
7107         {
7108         case LV2_UI_NONE:
7109             carla_stdout("Will use LV2 Show Interface for '%s'", pData->name);
7110             fUI.type = UI::TYPE_EMBED;
7111             break;
7112         case LV2_UI_QT4:
7113             carla_stdout("Will use LV2 Qt4 UI for '%s', NOT!", pData->name);
7114             fUI.type = UI::TYPE_EMBED;
7115             break;
7116         case LV2_UI_QT5:
7117             carla_stdout("Will use LV2 Qt5 UI for '%s', NOT!", pData->name);
7118             fUI.type = UI::TYPE_EMBED;
7119             break;
7120         case LV2_UI_GTK2:
7121             carla_stdout("Will use LV2 Gtk2 UI for '%s', NOT!", pData->name);
7122             fUI.type = UI::TYPE_EMBED;
7123             break;
7124         case LV2_UI_GTK3:
7125             carla_stdout("Will use LV2 Gtk3 UI for '%s', NOT!", pData->name);
7126             fUI.type = UI::TYPE_EMBED;
7127             break;
7128 #ifdef CARLA_OS_MAC
7129         case LV2_UI_COCOA:
7130             carla_stdout("Will use LV2 Cocoa UI for '%s'", pData->name);
7131             fUI.type = UI::TYPE_EMBED;
7132             break;
7133 #endif
7134 #ifdef CARLA_OS_WIN
7135         case LV2_UI_WINDOWS:
7136             carla_stdout("Will use LV2 Windows UI for '%s'", pData->name);
7137             fUI.type = UI::TYPE_EMBED;
7138             break;
7139 #endif
7140         case LV2_UI_X11:
7141 #ifdef HAVE_X11
7142             carla_stdout("Will use LV2 X11 UI for '%s'", pData->name);
7143 #else
7144             carla_stdout("Will use LV2 X11 UI for '%s', NOT!", pData->name);
7145 #endif
7146             fUI.type = UI::TYPE_EMBED;
7147             break;
7148         case LV2_UI_EXTERNAL:
7149         case LV2_UI_OLD_EXTERNAL:
7150             carla_stdout("Will use LV2 External UI for '%s'", pData->name);
7151             fUI.type = UI::TYPE_EXTERNAL;
7152             break;
7153         }
7154 
7155         if (fUI.type == UI::TYPE_NULL)
7156         {
7157             pData->uiLibClose();
7158             fUI.descriptor = nullptr;
7159             fUI.rdfDescriptor = nullptr;
7160             return;
7161         }
7162 
7163         // ---------------------------------------------------------------
7164         // initialize ui data
7165 
7166         {
7167             CarlaString uiTitle;
7168 
7169             if (pData->uiTitle.isNotEmpty())
7170             {
7171                 uiTitle = pData->uiTitle;
7172             }
7173             else
7174             {
7175                 uiTitle = pData->name;
7176                 uiTitle += " (GUI)";
7177             }
7178 
7179             fLv2Options.windowTitle = uiTitle.releaseBufferPointer();
7180         }
7181 
7182         fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].size  = (uint32_t)std::strlen(fLv2Options.windowTitle);
7183         fLv2Options.opts[CarlaPluginLV2Options::WindowTitle].value = fLv2Options.windowTitle;
7184 
7185         // ---------------------------------------------------------------
7186         // initialize ui features (part 1)
7187 
7188         LV2_Extension_Data_Feature* const uiDataFt = new LV2_Extension_Data_Feature;
7189         uiDataFt->data_access                      = fDescriptor->extension_data;
7190 
7191         LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
7192         uiPortMapFt->handle               = this;
7193         uiPortMapFt->port_index           = carla_lv2_ui_port_map;
7194 
7195         LV2UI_Request_Value* const uiRequestValueFt = new LV2UI_Request_Value;
7196         uiRequestValueFt->handle                    = this;
7197         uiRequestValueFt->request                   = carla_lv2_ui_request_value;
7198 
7199         LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
7200         uiResizeFt->handle             = this;
7201         uiResizeFt->ui_resize          = carla_lv2_ui_resize;
7202 
7203         LV2UI_Touch* const uiTouchFt = new LV2UI_Touch;
7204         uiTouchFt->handle            = this;
7205         uiTouchFt->touch             = carla_lv2_ui_touch;
7206 
7207         LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host;
7208         uiExternalHostFt->ui_closed                  = carla_lv2_external_ui_closed;
7209         uiExternalHostFt->plugin_human_id            = fLv2Options.windowTitle;
7210 
7211         // ---------------------------------------------------------------
7212         // initialize ui features (part 2)
7213 
7214         for (uint32_t j=kFeatureCountPlugin; j < kFeatureCountAll; ++j)
7215             fFeatures[j] = new LV2_Feature;
7216 
7217         fFeatures[kFeatureIdUiDataAccess]->URI      = LV2_DATA_ACCESS_URI;
7218         fFeatures[kFeatureIdUiDataAccess]->data     = uiDataFt;
7219 
7220         fFeatures[kFeatureIdUiInstanceAccess]->URI  = LV2_INSTANCE_ACCESS_URI;
7221         fFeatures[kFeatureIdUiInstanceAccess]->data = fHandle;
7222 
7223         fFeatures[kFeatureIdUiIdleInterface]->URI  = LV2_UI__idleInterface;
7224         fFeatures[kFeatureIdUiIdleInterface]->data = nullptr;
7225 
7226         fFeatures[kFeatureIdUiFixedSize]->URI      = LV2_UI__fixedSize;
7227         fFeatures[kFeatureIdUiFixedSize]->data     = nullptr;
7228 
7229         fFeatures[kFeatureIdUiMakeResident]->URI   = LV2_UI__makeResident;
7230         fFeatures[kFeatureIdUiMakeResident]->data  = nullptr;
7231 
7232         fFeatures[kFeatureIdUiMakeResident2]->URI  = LV2_UI__makeSONameResident;
7233         fFeatures[kFeatureIdUiMakeResident2]->data = nullptr;
7234 
7235         fFeatures[kFeatureIdUiNoUserResize]->URI   = LV2_UI__noUserResize;
7236         fFeatures[kFeatureIdUiNoUserResize]->data  = nullptr;
7237 
7238         fFeatures[kFeatureIdUiParent]->URI         = LV2_UI__parent;
7239         fFeatures[kFeatureIdUiParent]->data        = nullptr;
7240 
7241         fFeatures[kFeatureIdUiPortMap]->URI        = LV2_UI__portMap;
7242         fFeatures[kFeatureIdUiPortMap]->data       = uiPortMapFt;
7243 
7244         fFeatures[kFeatureIdUiPortSubscribe]->URI  = LV2_UI__portSubscribe;
7245         fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr;
7246 
7247         fFeatures[kFeatureIdUiRequestValue]->URI  = LV2_UI__requestValue;
7248         fFeatures[kFeatureIdUiRequestValue]->data = uiRequestValueFt;
7249 
7250         fFeatures[kFeatureIdUiResize]->URI       = LV2_UI__resize;
7251         fFeatures[kFeatureIdUiResize]->data      = uiResizeFt;
7252 
7253         fFeatures[kFeatureIdUiTouch]->URI        = LV2_UI__touch;
7254         fFeatures[kFeatureIdUiTouch]->data       = uiTouchFt;
7255 
7256         fFeatures[kFeatureIdExternalUi]->URI     = LV2_EXTERNAL_UI__Host;
7257         fFeatures[kFeatureIdExternalUi]->data    = uiExternalHostFt;
7258 
7259         fFeatures[kFeatureIdExternalUiOld]->URI  = LV2_EXTERNAL_UI_DEPRECATED_URI;
7260         fFeatures[kFeatureIdExternalUiOld]->data = uiExternalHostFt;
7261 
7262         // ---------------------------------------------------------------
7263         // initialize ui extensions
7264 
7265         if (fUI.descriptor->extension_data == nullptr)
7266             return;
7267 
7268         fExt.uiidle     = (const LV2UI_Idle_Interface*)fUI.descriptor->extension_data(LV2_UI__idleInterface);
7269         fExt.uishow     = (const LV2UI_Show_Interface*)fUI.descriptor->extension_data(LV2_UI__showInterface);
7270         fExt.uiresize   = (const LV2UI_Resize*)fUI.descriptor->extension_data(LV2_UI__resize);
7271         fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface);
7272 
7273         // check if invalid
7274         if (fExt.uiidle != nullptr && fExt.uiidle->idle == nullptr)
7275             fExt.uiidle = nullptr;
7276 
7277         if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr))
7278             fExt.uishow = nullptr;
7279 
7280         if (fExt.uiresize != nullptr && fExt.uiresize->ui_resize == nullptr)
7281             fExt.uiresize = nullptr;
7282 
7283         if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr)
7284             fExt.uiprograms = nullptr;
7285 
7286         // don't use uiidle if external
7287         if (fUI.type == UI::TYPE_EXTERNAL)
7288             fExt.uiidle = nullptr;
7289     }
7290 
7291     // -------------------------------------------------------------------
7292 
handleTransferAtom(const uint32_t portIndex,const LV2_Atom * const atom)7293     void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom)
7294     {
7295         CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);
7296         carla_debug("CarlaPluginLV2::handleTransferAtom(%i, %p)", portIndex, atom);
7297 
7298         fAtomBufferEvIn.put(atom, portIndex);
7299     }
7300 
handleUridMap(const LV2_URID urid,const char * const uri)7301     void handleUridMap(const LV2_URID urid, const char* const uri)
7302     {
7303         CARLA_SAFE_ASSERT_RETURN(urid != kUridNull,);
7304         CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
7305         carla_debug("CarlaPluginLV2::handleUridMap(%i v " P_SIZE ", \"%s\")", urid, fCustomURIDs.size()-1, uri);
7306 
7307         const std::size_t uriCount(fCustomURIDs.size());
7308 
7309         if (urid < uriCount)
7310         {
7311             const char* const ourURI(carla_lv2_urid_unmap(this, urid));
7312             CARLA_SAFE_ASSERT_RETURN(ourURI != nullptr && ourURI != kUnmapFallback,);
7313 
7314             if (std::strcmp(ourURI, uri) != 0)
7315             {
7316                 carla_stderr2("PLUGIN :: wrong URI '%s' vs '%s'", ourURI,  uri);
7317             }
7318         }
7319         else
7320         {
7321             CARLA_SAFE_ASSERT_RETURN(urid == uriCount,);
7322             fCustomURIDs.push_back(uri);
7323         }
7324     }
7325 
7326     // -------------------------------------------------------------------
7327 
writeAtomPath(const char * const path,const LV2_URID urid)7328     void writeAtomPath(const char* const path, const LV2_URID urid)
7329     {
7330         uint8_t atomBuf[4096];
7331         LV2_Atom_Forge atomForge;
7332         initAtomForge(atomForge);
7333         lv2_atom_forge_set_buffer(&atomForge, atomBuf, sizeof(atomBuf));
7334 
7335         LV2_Atom_Forge_Frame forgeFrame;
7336         lv2_atom_forge_object(&atomForge, &forgeFrame, kUridNull, kUridPatchSet);
7337 
7338         lv2_atom_forge_key(&atomForge, kUridCarlaParameterChange);
7339         lv2_atom_forge_bool(&atomForge, true);
7340 
7341         lv2_atom_forge_key(&atomForge, kUridPatchProperty);
7342         lv2_atom_forge_urid(&atomForge, urid);
7343 
7344         lv2_atom_forge_key(&atomForge, kUridPatchValue);
7345         lv2_atom_forge_path(&atomForge, path, static_cast<uint32_t>(std::strlen(path))+1);
7346 
7347         lv2_atom_forge_pop(&atomForge, &forgeFrame);
7348 
7349         LV2_Atom* const atom((LV2_Atom*)atomBuf);
7350         CARLA_SAFE_ASSERT(atom->size < sizeof(atomBuf));
7351 
7352         fAtomBufferEvIn.put(atom, fEventsIn.ctrlIndex);
7353     }
7354 
7355     // -------------------------------------------------------------------
7356 
7357 private:
7358     LV2_Handle   fHandle;
7359     LV2_Handle   fHandle2;
7360     LV2_Feature* fFeatures[kFeatureCountAll+1];
7361     LV2_Feature* fStateFeatures[kStateFeatureCountAll+1];
7362     const LV2_Descriptor*     fDescriptor;
7363     const LV2_RDF_Descriptor* fRdfDescriptor;
7364 
7365     float** fAudioInBuffers;
7366     float** fAudioOutBuffers;
7367     float** fCvInBuffers;
7368     float** fCvOutBuffers;
7369     float*  fParamBuffers;
7370 
7371     bool    fHasLoadDefaultState : 1;
7372     bool    fHasThreadSafeRestore : 1;
7373     bool    fNeedsFixedBuffers : 1;
7374     bool    fNeedsUiClose  : 1;
7375     bool    fInlineDisplayNeedsRedraw : 1;
7376     int64_t fInlineDisplayLastRedrawTime;
7377     int32_t fLatencyIndex; // -1 if invalid
7378     int     fStrictBounds; // -1 unsupported, 0 optional, 1 required
7379 
7380     Lv2AtomRingBuffer fAtomBufferEvIn;
7381     Lv2AtomRingBuffer fAtomBufferUiOut;
7382     Lv2AtomRingBuffer fAtomBufferWorkerIn;
7383     Lv2AtomRingBuffer fAtomBufferWorkerResp;
7384     uint8_t*          fAtomBufferUiOutTmpData;
7385     uint8_t*          fAtomBufferWorkerInTmpData;
7386 
7387     CarlaPluginLV2EventData fEventsIn;
7388     CarlaPluginLV2EventData fEventsOut;
7389     CarlaPluginLV2Options   fLv2Options;
7390     CarlaPipeServerLV2      fPipeServer;
7391 
7392     std::vector<std::string> fCustomURIDs;
7393 
7394     bool fFirstActive; // first process() call after activate()
7395     void* fLastStateChunk;
7396     EngineTimeInfo fLastTimeInfo;
7397 
7398     // if plugin provides path parameter, use it as fake "gui"
7399     CarlaString fFilePathURI;
7400 
7401     struct Extensions {
7402         const LV2_Options_Interface* options;
7403         const LV2_State_Interface* state;
7404         const LV2_Worker_Interface* worker;
7405         const LV2_Inline_Display_Interface* inlineDisplay;
7406         const LV2_Midnam_Interface* midnam;
7407         const LV2_Programs_Interface* programs;
7408         const LV2UI_Idle_Interface* uiidle;
7409         const LV2UI_Show_Interface* uishow;
7410         const LV2UI_Resize* uiresize;
7411         const LV2_Programs_UI_Interface* uiprograms;
7412 
ExtensionsCarlaPluginLV2::Extensions7413         Extensions()
7414             : options(nullptr),
7415               state(nullptr),
7416               worker(nullptr),
7417               inlineDisplay(nullptr),
7418               midnam(nullptr),
7419               programs(nullptr),
7420               uiidle(nullptr),
7421               uishow(nullptr),
7422               uiresize(nullptr),
7423               uiprograms(nullptr) {}
7424 
7425         CARLA_DECLARE_NON_COPY_STRUCT(Extensions);
7426     } fExt;
7427 
7428     struct UI {
7429         enum Type {
7430             TYPE_NULL = 0,
7431             TYPE_BRIDGE,
7432             TYPE_EMBED,
7433             TYPE_EXTERNAL
7434         };
7435 
7436         Type type;
7437         LV2UI_Handle handle;
7438         LV2UI_Widget widget;
7439         const LV2UI_Descriptor* descriptor;
7440         const LV2_RDF_UI*       rdfDescriptor;
7441 
7442         bool embedded;
7443         bool fileBrowserOpen;
7444         const char* fileNeededForURI;
7445         CarlaPluginUI* window;
7446 
UICarlaPluginLV2::UI7447         UI()
7448             : type(TYPE_NULL),
7449               handle(nullptr),
7450               widget(nullptr),
7451               descriptor(nullptr),
7452               rdfDescriptor(nullptr),
7453               embedded(false),
7454               fileBrowserOpen(false),
7455               fileNeededForURI(nullptr),
7456               window(nullptr) {}
7457 
~UICarlaPluginLV2::UI7458         ~UI()
7459         {
7460             CARLA_SAFE_ASSERT(handle == nullptr);
7461             CARLA_SAFE_ASSERT(widget == nullptr);
7462             CARLA_SAFE_ASSERT(descriptor == nullptr);
7463             CARLA_SAFE_ASSERT(rdfDescriptor == nullptr);
7464             CARLA_SAFE_ASSERT(! fileBrowserOpen);
7465             CARLA_SAFE_ASSERT(fileNeededForURI == nullptr);
7466             CARLA_SAFE_ASSERT(window == nullptr);
7467         }
7468 
7469         CARLA_DECLARE_NON_COPY_STRUCT(UI);
7470     } fUI;
7471 
7472     // -------------------------------------------------------------------
7473     // Event Feature
7474 
carla_lv2_event_ref(LV2_Event_Callback_Data callback_data,LV2_Event * event)7475     static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
7476     {
7477         CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
7478         CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
7479         carla_debug("carla_lv2_event_ref(%p, %p)", callback_data, event);
7480 
7481         return 0;
7482     }
7483 
carla_lv2_event_unref(LV2_Event_Callback_Data callback_data,LV2_Event * event)7484     static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
7485     {
7486         CARLA_SAFE_ASSERT_RETURN(callback_data != nullptr, 0);
7487         CARLA_SAFE_ASSERT_RETURN(event != nullptr, 0);
7488         carla_debug("carla_lv2_event_unref(%p, %p)", callback_data, event);
7489 
7490         return 0;
7491     }
7492 
7493     // -------------------------------------------------------------------
7494     // Logs Feature
7495 
carla_lv2_log_printf(LV2_Log_Handle handle,LV2_URID type,const char * fmt,...)7496     static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
7497     {
7498         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
7499         CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
7500         CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
7501 
7502 #ifndef DEBUG
7503         if (type == kUridLogTrace)
7504             return 0;
7505 #endif
7506 
7507         va_list args;
7508         va_start(args, fmt);
7509         const int ret(carla_lv2_log_vprintf(handle, type, fmt, args));
7510         va_end(args);
7511 
7512         return ret;
7513     }
7514 
carla_lv2_log_vprintf(LV2_Log_Handle handle,LV2_URID type,const char * fmt,va_list ap)7515     static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
7516     {
7517         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
7518         CARLA_SAFE_ASSERT_RETURN(type != kUridNull, 0);
7519         CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
7520 
7521         int ret = 0;
7522 
7523         switch (type)
7524         {
7525         case kUridLogError:
7526             std::fprintf(stderr, "\x1b[31m");
7527             ret = std::vfprintf(stderr, fmt, ap);
7528             std::fprintf(stderr, "\x1b[0m");
7529             break;
7530 
7531         case kUridLogNote:
7532             ret = std::vfprintf(stdout, fmt, ap);
7533             break;
7534 
7535         case kUridLogTrace:
7536 #ifdef DEBUG
7537             std::fprintf(stdout, "\x1b[30;1m");
7538             ret = std::vfprintf(stdout, fmt, ap);
7539             std::fprintf(stdout, "\x1b[0m");
7540 #endif
7541             break;
7542 
7543         case kUridLogWarning:
7544             ret = std::vfprintf(stderr, fmt, ap);
7545             break;
7546 
7547         default:
7548             break;
7549         }
7550 
7551         return ret;
7552     }
7553 
7554     // -------------------------------------------------------------------
7555     // Programs Feature
7556 
carla_lv2_program_changed(LV2_Programs_Handle handle,int32_t index)7557     static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
7558     {
7559         CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7560         carla_debug("carla_lv2_program_changed(%p, %i)", handle, index);
7561 
7562         ((CarlaPluginLV2*)handle)->handleProgramChanged(index);
7563     }
7564 
7565     // -------------------------------------------------------------------
7566     // Resize Port Feature
7567 
carla_lv2_resize_port(LV2_Resize_Port_Feature_Data data,uint32_t index,size_t size)7568     static LV2_Resize_Port_Status carla_lv2_resize_port(LV2_Resize_Port_Feature_Data data, uint32_t index, size_t size)
7569     {
7570         CARLA_SAFE_ASSERT_RETURN(data != nullptr, LV2_RESIZE_PORT_ERR_UNKNOWN);
7571         carla_debug("carla_lv2_program_changed(%p, %i, " P_SIZE ")", data, index, size);
7572 
7573         return ((CarlaPluginLV2*)data)->handleResizePort(index, size);
7574     }
7575 
7576     // -------------------------------------------------------------------
7577     // State Feature
7578 
carla_lv2_state_free_path(LV2_State_Free_Path_Handle handle,char * const path)7579     static void carla_lv2_state_free_path(LV2_State_Free_Path_Handle handle, char* const path)
7580     {
7581         CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7582         carla_debug("carla_lv2_state_free_path(%p, \"%s\")", handle, path);
7583 
7584         std::free(path);
7585     }
7586 
carla_lv2_state_make_path_real(LV2_State_Make_Path_Handle handle,const char * const path)7587     static char* carla_lv2_state_make_path_real(LV2_State_Make_Path_Handle handle, const char* const path)
7588     {
7589         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7590         CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr);
7591         carla_debug("carla_lv2_state_make_path_real(%p, \"%s\")", handle, path);
7592 
7593         const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, false, path));
7594         return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7595     }
7596 
carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle,const char * const path)7597     static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle, const char* const path)
7598     {
7599         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7600         CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr);
7601         carla_debug("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle, path);
7602 
7603         const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, false, true, path));
7604         return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7605     }
7606 
carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle,const char * const absolute_path)7607     static char* carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
7608     {
7609         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7610         CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr);
7611         carla_debug("carla_lv2_state_map_to_abstract_path_real(%p, \"%s\")", handle, absolute_path);
7612 
7613         return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(false, absolute_path);
7614     }
7615 
carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle,const char * const absolute_path)7616     static char* carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle, const char* const absolute_path)
7617     {
7618         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7619         CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr);
7620         carla_debug("carla_lv2_state_map_to_abstract_path_tmp(%p, \"%s\")", handle, absolute_path);
7621 
7622         return ((CarlaPluginLV2*)handle)->handleStateMapToAbstractPath(true, absolute_path);
7623     }
7624 
carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle,const char * const abstract_path)7625     static char* carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
7626     {
7627         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7628         CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr);
7629         carla_debug("carla_lv2_state_map_to_absolute_path_real(%p, \"%s\")", handle, abstract_path);
7630 
7631         const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, false, abstract_path));
7632         return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7633     }
7634 
carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle,const char * const abstract_path)7635     static char* carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle, const char* const abstract_path)
7636     {
7637         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7638         CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr);
7639         carla_debug("carla_lv2_state_map_to_absolute_path_tmp(%p, \"%s\")", handle, abstract_path);
7640 
7641         const File file(((CarlaPluginLV2*)handle)->handleStateMapToAbsolutePath(true, true, true, abstract_path));
7642         return file.isNotNull() ? strdup(file.getFullPathName().toRawUTF8()) : nullptr;
7643     }
7644 
carla_lv2_state_store(LV2_State_Handle handle,uint32_t key,const void * value,size_t size,uint32_t type,uint32_t flags)7645     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)
7646     {
7647         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_STATE_ERR_UNKNOWN);
7648         carla_debug("carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i)", handle, key, value, size, type, flags);
7649 
7650         return ((CarlaPluginLV2*)handle)->handleStateStore(key, value, size, type, flags);
7651     }
7652 
carla_lv2_state_retrieve(LV2_State_Handle handle,uint32_t key,size_t * size,uint32_t * type,uint32_t * flags)7653     static const void* carla_lv2_state_retrieve(LV2_State_Handle handle, uint32_t key, size_t* size, uint32_t* type, uint32_t* flags)
7654     {
7655         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7656         carla_debug("carla_lv2_state_retrieve(%p, %i, %p, %p, %p)", handle, key, size, type, flags);
7657 
7658         return ((CarlaPluginLV2*)handle)->handleStateRetrieve(key, size, type, flags);
7659     }
7660 
7661     // -------------------------------------------------------------------
7662     // URI-Map Feature
7663 
carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data,const char * map,const char * uri)7664     static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
7665     {
7666         carla_debug("carla_lv2_uri_to_id(%p, \"%s\", \"%s\")", data, map, uri);
7667         return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
7668 
7669         // unused
7670         (void)map;
7671     }
7672 
7673     // -------------------------------------------------------------------
7674     // URID Feature
7675 
carla_lv2_urid_map(LV2_URID_Map_Handle handle,const char * uri)7676     static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
7677     {
7678         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, kUridNull);
7679         CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', kUridNull);
7680         carla_debug("carla_lv2_urid_map(%p, \"%s\")", handle, uri);
7681 
7682         // Atom types
7683         if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
7684             return kUridAtomBlank;
7685         if (std::strcmp(uri, LV2_ATOM__Bool) == 0)
7686             return kUridAtomBool;
7687         if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
7688             return kUridAtomChunk;
7689         if (std::strcmp(uri, LV2_ATOM__Double) == 0)
7690             return kUridAtomDouble;
7691         if (std::strcmp(uri, LV2_ATOM__Event) == 0)
7692             return kUridAtomEvent;
7693         if (std::strcmp(uri, LV2_ATOM__Float) == 0)
7694             return kUridAtomFloat;
7695         if (std::strcmp(uri, LV2_ATOM__Int) == 0)
7696             return kUridAtomInt;
7697         if (std::strcmp(uri, LV2_ATOM__Literal) == 0)
7698             return kUridAtomLiteral;
7699         if (std::strcmp(uri, LV2_ATOM__Long) == 0)
7700             return kUridAtomLong;
7701         if (std::strcmp(uri, LV2_ATOM__Number) == 0)
7702             return kUridAtomNumber;
7703         if (std::strcmp(uri, LV2_ATOM__Object) == 0)
7704             return kUridAtomObject;
7705         if (std::strcmp(uri, LV2_ATOM__Path) == 0)
7706             return kUridAtomPath;
7707         if (std::strcmp(uri, LV2_ATOM__Property) == 0)
7708             return kUridAtomProperty;
7709         if (std::strcmp(uri, LV2_ATOM__Resource) == 0)
7710             return kUridAtomResource;
7711         if (std::strcmp(uri, LV2_ATOM__Sequence) == 0)
7712             return kUridAtomSequence;
7713         if (std::strcmp(uri, LV2_ATOM__Sound) == 0)
7714             return kUridAtomSound;
7715         if (std::strcmp(uri, LV2_ATOM__String) == 0)
7716             return kUridAtomString;
7717         if (std::strcmp(uri, LV2_ATOM__Tuple) == 0)
7718             return kUridAtomTuple;
7719         if (std::strcmp(uri, LV2_ATOM__URI) == 0)
7720             return kUridAtomURI;
7721         if (std::strcmp(uri, LV2_ATOM__URID) == 0)
7722             return kUridAtomURID;
7723         if (std::strcmp(uri, LV2_ATOM__Vector) == 0)
7724             return kUridAtomVector;
7725         if (std::strcmp(uri, LV2_ATOM__atomTransfer) == 0)
7726             return kUridAtomTransferAtom;
7727         if (std::strcmp(uri, LV2_ATOM__eventTransfer) == 0)
7728             return kUridAtomTransferEvent;
7729 
7730         // BufSize types
7731         if (std::strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
7732             return kUridBufMaxLength;
7733         if (std::strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
7734             return kUridBufMinLength;
7735         if (std::strcmp(uri, LV2_BUF_SIZE__nominalBlockLength) == 0)
7736             return kUridBufNominalLength;
7737         if (std::strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
7738             return kUridBufSequenceSize;
7739 
7740         // Log types
7741         if (std::strcmp(uri, LV2_LOG__Error) == 0)
7742             return kUridLogError;
7743         if (std::strcmp(uri, LV2_LOG__Note) == 0)
7744             return kUridLogNote;
7745         if (std::strcmp(uri, LV2_LOG__Trace) == 0)
7746             return kUridLogTrace;
7747         if (std::strcmp(uri, LV2_LOG__Warning) == 0)
7748             return kUridLogWarning;
7749 
7750         // Patch types
7751         if (std::strcmp(uri, LV2_PATCH__Set) == 0)
7752             return kUridPatchSet;
7753         if (std::strcmp(uri, LV2_PATCH__property) == 0)
7754             return kUridPatchProperty;
7755         if (std::strcmp(uri, LV2_PATCH__subject) == 0)
7756             return kUridPatchSubject;
7757         if (std::strcmp(uri, LV2_PATCH__value) == 0)
7758             return kUridPatchValue;
7759 
7760         // Time types
7761         if (std::strcmp(uri, LV2_TIME__Position) == 0)
7762             return kUridTimePosition;
7763         if (std::strcmp(uri, LV2_TIME__bar) == 0)
7764             return kUridTimeBar;
7765         if (std::strcmp(uri, LV2_TIME__barBeat) == 0)
7766             return kUridTimeBarBeat;
7767         if (std::strcmp(uri, LV2_TIME__beat) == 0)
7768             return kUridTimeBeat;
7769         if (std::strcmp(uri, LV2_TIME__beatUnit) == 0)
7770             return kUridTimeBeatUnit;
7771         if (std::strcmp(uri, LV2_TIME__beatsPerBar) == 0)
7772             return kUridTimeBeatsPerBar;
7773         if (std::strcmp(uri, LV2_TIME__beatsPerMinute) == 0)
7774             return kUridTimeBeatsPerMinute;
7775         if (std::strcmp(uri, LV2_TIME__frame) == 0)
7776             return kUridTimeFrame;
7777         if (std::strcmp(uri, LV2_TIME__framesPerSecond) == 0)
7778             return kUridTimeFramesPerSecond;
7779         if (std::strcmp(uri, LV2_TIME__speed) == 0)
7780             return kUridTimeSpeed;
7781         if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0)
7782             return kUridTimeTicksPerBeat;
7783 
7784         // Others
7785         if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0)
7786             return kUridMidiEvent;
7787         if (std::strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
7788             return kUridParamSampleRate;
7789         if (std::strcmp(uri, LV2_UI__backgroundColor) == 0)
7790             return kUridBackgroundColor;
7791         if (std::strcmp(uri, LV2_UI__foregroundColor) == 0)
7792             return kUridForegroundColor;
7793         if (std::strcmp(uri, LV2_UI__scaleFactor) == 0)
7794             return kUridScaleFactor;
7795         if (std::strcmp(uri, LV2_UI__windowTitle) == 0)
7796             return kUridWindowTitle;
7797 
7798         // Custom Carla types
7799         if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_IN) == 0)
7800             return kUridCarlaAtomWorkerIn;
7801         if (std::strcmp(uri, URI_CARLA_ATOM_WORKER_RESP) == 0)
7802             return kUridCarlaAtomWorkerResp;
7803         if (std::strcmp(uri, URI_CARLA_PARAMETER_CHANGE) == 0)
7804             return kUridCarlaParameterChange;
7805         if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TransientWindowId) == 0)
7806             return kUridCarlaTransientWindowId;
7807 
7808         // Custom plugin types
7809         return ((CarlaPluginLV2*)handle)->getCustomURID(uri);
7810     }
7811 
carla_lv2_urid_unmap(LV2_URID_Map_Handle handle,LV2_URID urid)7812     static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
7813     {
7814         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
7815         CARLA_SAFE_ASSERT_RETURN(urid != kUridNull, nullptr);
7816         carla_debug("carla_lv2_urid_unmap(%p, %i)", handle, urid);
7817 
7818         switch (urid)
7819         {
7820         // Atom types
7821         case kUridAtomBlank:
7822             return LV2_ATOM__Blank;
7823         case kUridAtomBool:
7824             return LV2_ATOM__Bool;
7825         case kUridAtomChunk:
7826             return LV2_ATOM__Chunk;
7827         case kUridAtomDouble:
7828             return LV2_ATOM__Double;
7829         case kUridAtomEvent:
7830             return LV2_ATOM__Event;
7831         case kUridAtomFloat:
7832             return LV2_ATOM__Float;
7833         case kUridAtomInt:
7834             return LV2_ATOM__Int;
7835         case kUridAtomLiteral:
7836             return LV2_ATOM__Literal;
7837         case kUridAtomLong:
7838             return LV2_ATOM__Long;
7839         case kUridAtomNumber:
7840             return LV2_ATOM__Number;
7841         case kUridAtomObject:
7842             return LV2_ATOM__Object;
7843         case kUridAtomPath:
7844             return LV2_ATOM__Path;
7845         case kUridAtomProperty:
7846             return LV2_ATOM__Property;
7847         case kUridAtomResource:
7848             return LV2_ATOM__Resource;
7849         case kUridAtomSequence:
7850             return LV2_ATOM__Sequence;
7851         case kUridAtomSound:
7852             return LV2_ATOM__Sound;
7853         case kUridAtomString:
7854             return LV2_ATOM__String;
7855         case kUridAtomTuple:
7856             return LV2_ATOM__Tuple;
7857         case kUridAtomURI:
7858             return LV2_ATOM__URI;
7859         case kUridAtomURID:
7860             return LV2_ATOM__URID;
7861         case kUridAtomVector:
7862             return LV2_ATOM__Vector;
7863         case kUridAtomTransferAtom:
7864             return LV2_ATOM__atomTransfer;
7865         case kUridAtomTransferEvent:
7866             return LV2_ATOM__eventTransfer;
7867 
7868         // BufSize types
7869         case kUridBufMaxLength:
7870             return LV2_BUF_SIZE__maxBlockLength;
7871         case kUridBufMinLength:
7872             return LV2_BUF_SIZE__minBlockLength;
7873         case kUridBufNominalLength:
7874             return LV2_BUF_SIZE__nominalBlockLength;
7875         case kUridBufSequenceSize:
7876             return LV2_BUF_SIZE__sequenceSize;
7877 
7878         // Log types
7879         case kUridLogError:
7880             return LV2_LOG__Error;
7881         case kUridLogNote:
7882             return LV2_LOG__Note;
7883         case kUridLogTrace:
7884             return LV2_LOG__Trace;
7885         case kUridLogWarning:
7886             return LV2_LOG__Warning;
7887 
7888         // Patch types
7889         case kUridPatchSet:
7890             return LV2_PATCH__Set;
7891         case kUridPatchProperty:
7892             return LV2_PATCH__property;
7893         case kUridPatchSubject:
7894             return LV2_PATCH__subject;
7895         case kUridPatchValue:
7896             return LV2_PATCH__value;
7897 
7898         // Time types
7899         case kUridTimePosition:
7900             return LV2_TIME__Position;
7901         case kUridTimeBar:
7902             return LV2_TIME__bar;
7903         case kUridTimeBarBeat:
7904             return LV2_TIME__barBeat;
7905         case kUridTimeBeat:
7906             return LV2_TIME__beat;
7907         case kUridTimeBeatUnit:
7908             return LV2_TIME__beatUnit;
7909         case kUridTimeBeatsPerBar:
7910             return LV2_TIME__beatsPerBar;
7911         case kUridTimeBeatsPerMinute:
7912             return LV2_TIME__beatsPerMinute;
7913         case kUridTimeFrame:
7914             return LV2_TIME__frame;
7915         case kUridTimeFramesPerSecond:
7916             return LV2_TIME__framesPerSecond;
7917         case kUridTimeSpeed:
7918             return LV2_TIME__speed;
7919         case kUridTimeTicksPerBeat:
7920             return LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat;
7921 
7922         // Others
7923         case kUridMidiEvent:
7924             return LV2_MIDI__MidiEvent;
7925         case kUridParamSampleRate:
7926             return LV2_PARAMETERS__sampleRate;
7927         case kUridBackgroundColor:
7928             return LV2_UI__backgroundColor;
7929         case kUridForegroundColor:
7930             return LV2_UI__foregroundColor;
7931         case kUridScaleFactor:
7932             return LV2_UI__scaleFactor;
7933         case kUridWindowTitle:
7934             return LV2_UI__windowTitle;
7935 
7936         // Custom Carla types
7937         case kUridCarlaAtomWorkerIn:
7938             return URI_CARLA_ATOM_WORKER_IN;
7939         case kUridCarlaAtomWorkerResp:
7940             return URI_CARLA_ATOM_WORKER_RESP;
7941         case kUridCarlaParameterChange:
7942             return URI_CARLA_PARAMETER_CHANGE;
7943         case kUridCarlaTransientWindowId:
7944             return LV2_KXSTUDIO_PROPERTIES__TransientWindowId;
7945         }
7946 
7947         // Custom plugin types
7948         return ((CarlaPluginLV2*)handle)->getCustomURIDString(urid);
7949     }
7950 
7951     // -------------------------------------------------------------------
7952     // Worker Feature
7953 
carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle,uint32_t size,const void * data)7954     static LV2_Worker_Status carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data)
7955     {
7956         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
7957         carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle, size, data);
7958 
7959         return ((CarlaPluginLV2*)handle)->handleWorkerSchedule(size, data);
7960     }
7961 
carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle,uint32_t size,const void * data)7962     static LV2_Worker_Status carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void* data)
7963     {
7964         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2_WORKER_ERR_UNKNOWN);
7965         carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle, size, data);
7966 
7967         return ((CarlaPluginLV2*)handle)->handleWorkerRespond(size, data);
7968     }
7969 
7970     // -------------------------------------------------------------------
7971     // Inline Display Feature
7972 
carla_lv2_inline_display_queue_draw(LV2_Inline_Display_Handle handle)7973     static void carla_lv2_inline_display_queue_draw(LV2_Inline_Display_Handle handle)
7974     {
7975         CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7976         // carla_debug("carla_lv2_inline_display_queue_draw(%p)", handle);
7977 
7978         ((CarlaPluginLV2*)handle)->handleInlineDisplayQueueRedraw();
7979     }
7980 
7981     // -------------------------------------------------------------------
7982     // Midnam Feature
7983 
carla_lv2_midnam_update(LV2_Midnam_Handle handle)7984     static void carla_lv2_midnam_update(LV2_Midnam_Handle handle)
7985     {
7986         CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
7987         carla_stdout("carla_lv2_midnam_update(%p)", handle);
7988 
7989         ((CarlaPluginLV2*)handle)->handleMidnamUpdate();
7990     }
7991 
7992     // -------------------------------------------------------------------
7993     // External UI Feature
7994 
carla_lv2_external_ui_closed(LV2UI_Controller controller)7995     static void carla_lv2_external_ui_closed(LV2UI_Controller controller)
7996     {
7997         CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
7998         carla_debug("carla_lv2_external_ui_closed(%p)", controller);
7999 
8000         ((CarlaPluginLV2*)controller)->handleExternalUIClosed();
8001     }
8002 
8003     // -------------------------------------------------------------------
8004     // UI Port-Map Feature
8005 
carla_lv2_ui_port_map(LV2UI_Feature_Handle handle,const char * symbol)8006     static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
8007     {
8008         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_INVALID_PORT_INDEX);
8009         carla_debug("carla_lv2_ui_port_map(%p, \"%s\")", handle, symbol);
8010 
8011         return ((CarlaPluginLV2*)handle)->handleUIPortMap(symbol);
8012     }
8013 
8014     // ----------------------------------------------------------------------------------------------------------------
8015     // UI Request Parameter Feature
8016 
carla_lv2_ui_request_value(LV2UI_Feature_Handle handle,LV2_URID key,LV2_URID type,const LV2_Feature * const * features)8017     static LV2UI_Request_Value_Status carla_lv2_ui_request_value(LV2UI_Feature_Handle handle,
8018                                                                  LV2_URID key,
8019                                                                  LV2_URID type,
8020                                                                  const LV2_Feature* const* features)
8021     {
8022         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN);
8023         carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle, key, type, features);
8024 
8025         return ((CarlaPluginLV2*)handle)->handleUIRequestValue(key, type, features);
8026     }
8027 
8028     // -------------------------------------------------------------------
8029     // UI Resize Feature
8030 
carla_lv2_ui_resize(LV2UI_Feature_Handle handle,int width,int height)8031     static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
8032     {
8033         CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1);
8034         carla_debug("carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
8035 
8036         return ((CarlaPluginLV2*)handle)->handleUIResize(width, height);
8037     }
8038 
8039     // -------------------------------------------------------------------
8040     // UI Touch Feature
8041 
carla_lv2_ui_touch(LV2UI_Feature_Handle handle,uint32_t port_index,bool touch)8042     static void carla_lv2_ui_touch(LV2UI_Feature_Handle handle, uint32_t port_index, bool touch)
8043     {
8044         CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
8045         carla_debug("carla_lv2_ui_touch(%p, %u, %s)", handle, port_index, bool2str(touch));
8046 
8047         ((CarlaPluginLV2*)handle)->handleUITouch(port_index, touch);
8048     }
8049 
8050     // -------------------------------------------------------------------
8051     // UI Extension
8052 
carla_lv2_ui_write_function(LV2UI_Controller controller,uint32_t port_index,uint32_t buffer_size,uint32_t format,const void * buffer)8053     static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
8054     {
8055         CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
8056         carla_debug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
8057 
8058         ((CarlaPluginLV2*)controller)->handleUIWrite(port_index, buffer_size, format, buffer);
8059     }
8060 
8061     // -------------------------------------------------------------------
8062     // Lilv State
8063 
carla_lilv_set_port_value(const char * port_symbol,void * user_data,const void * value,uint32_t size,uint32_t type)8064     static void carla_lilv_set_port_value(const char* port_symbol, void* user_data, const void* value, uint32_t size, uint32_t type)
8065     {
8066         CARLA_SAFE_ASSERT_RETURN(user_data != nullptr,);
8067         carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i", port_symbol, user_data, value, size, type);
8068 
8069         ((CarlaPluginLV2*)user_data)->handleLilvSetPortValue(port_symbol, value, size, type);
8070     }
8071 
8072     // -------------------------------------------------------------------
8073 
8074     CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginLV2)
8075 };
8076 
8077 // -------------------------------------------------------------------------------------------------------------------
8078 
msgReceived(const char * const msg)8079 bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept
8080 {
8081     if (std::strcmp(msg, "exiting") == 0)
8082     {
8083         closePipeServer();
8084         fUiState = UiHide;
8085         return true;
8086     }
8087 
8088     if (std::strcmp(msg, "control") == 0)
8089     {
8090         uint32_t index;
8091         float value;
8092 
8093         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8094         CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
8095 
8096         try {
8097             kPlugin->handleUIWrite(index, sizeof(float), kUridNull, &value);
8098         } CARLA_SAFE_EXCEPTION("magReceived control");
8099 
8100         return true;
8101     }
8102 
8103     if (std::strcmp(msg, "pcontrol") == 0)
8104     {
8105         const char* uri;
8106         float value;
8107 
8108         CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, true), true);
8109         CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
8110 
8111         try {
8112             kPlugin->handleUIBridgeParameter(uri, value);
8113         } CARLA_SAFE_EXCEPTION("magReceived pcontrol");
8114 
8115         return true;
8116     }
8117 
8118     if (std::strcmp(msg, "atom") == 0)
8119     {
8120         uint32_t index, atomTotalSize, base64Size;
8121         const char* base64atom;
8122 
8123         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8124         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(atomTotalSize), true);
8125         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size), true);
8126         CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom, false, base64Size), true);
8127 
8128         std::vector<uint8_t> chunk(carla_getChunkFromBase64String(base64atom));
8129         CARLA_SAFE_ASSERT_UINT2_RETURN(chunk.size() >= sizeof(LV2_Atom), chunk.size(), sizeof(LV2_Atom), true);
8130 
8131 #ifdef CARLA_PROPER_CPP11_SUPPORT
8132         const LV2_Atom* const atom((const LV2_Atom*)chunk.data());
8133 #else
8134         const LV2_Atom* const atom((const LV2_Atom*)&chunk.front());
8135 #endif
8136         CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom) == chunk.size(), true);
8137 
8138         try {
8139             kPlugin->handleUIWrite(index, lv2_atom_total_size(atom), kUridAtomTransferEvent, atom);
8140         } CARLA_SAFE_EXCEPTION("magReceived atom");
8141 
8142         return true;
8143     }
8144 
8145     if (std::strcmp(msg, "program") == 0)
8146     {
8147         uint32_t index;
8148 
8149         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true);
8150 
8151         try {
8152             kPlugin->setMidiProgram(static_cast<int32_t>(index), false, true, true, false);
8153         } CARLA_SAFE_EXCEPTION("msgReceived program");
8154 
8155         return true;
8156     }
8157 
8158     if (std::strcmp(msg, "urid") == 0)
8159     {
8160         uint32_t urid, size;
8161         const char* uri;
8162 
8163         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(urid), true);
8164         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(size), true);
8165         CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri, false, size), true);
8166 
8167         if (urid != 0)
8168         {
8169             try {
8170                 kPlugin->handleUridMap(urid, uri);
8171             } CARLA_SAFE_EXCEPTION("msgReceived urid");
8172         }
8173 
8174         return true;
8175     }
8176 
8177     if (std::strcmp(msg, "reloadprograms") == 0)
8178     {
8179         int32_t index;
8180 
8181         CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
8182 
8183         try {
8184             kPlugin->handleProgramChanged(index);
8185         } CARLA_SAFE_EXCEPTION("handleProgramChanged");
8186 
8187         return true;
8188     }
8189 
8190     if (std::strcmp(msg, "requestvalue") == 0)
8191     {
8192         uint32_t key, type;
8193 
8194         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(key), true);
8195         CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(type), true);
8196 
8197         if (key != 0)
8198         {
8199             try {
8200                 kPlugin->handleUIRequestValue(key, type, nullptr);
8201             } CARLA_SAFE_EXCEPTION("msgReceived requestvalue");
8202         }
8203 
8204         return true;
8205     }
8206 
8207     return false;
8208 }
8209 
8210 // -------------------------------------------------------------------------------------------------------------------
8211 
newLV2(const Initializer & init)8212 CarlaPluginPtr CarlaPlugin::newLV2(const Initializer& init)
8213 {
8214     carla_debug("CarlaPlugin::newLV2({%p, \"%s\", \"%s\"})", init.engine, init.name, init.label);
8215 
8216     std::shared_ptr<CarlaPluginLV2> plugin(new CarlaPluginLV2(init.engine, init.id));
8217 
8218     const char* needsArchBridge = nullptr;
8219     if (plugin->init(plugin, init.name, init.label, init.options, needsArchBridge))
8220         return plugin;
8221 
8222     if (needsArchBridge != nullptr)
8223     {
8224         CarlaString bridgeBinary(init.engine->getOptions().binaryDir);
8225         bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-native";
8226 
8227         return CarlaPlugin::newBridge(init, BINARY_NATIVE, PLUGIN_LV2, needsArchBridge, bridgeBinary);
8228     }
8229 
8230     return nullptr;
8231 }
8232 
8233 // used in CarlaStandalone.cpp
8234 const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height);
8235 
carla_render_inline_display_lv2(const CarlaPluginPtr & plugin,uint32_t width,uint32_t height)8236 const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height)
8237 {
8238     const std::shared_ptr<CarlaPluginLV2>& lv2Plugin((const std::shared_ptr<CarlaPluginLV2>&)plugin);
8239 
8240     return lv2Plugin->renderInlineDisplay(width, height);
8241 }
8242 
8243 // -------------------------------------------------------------------------------------------------------------------
8244 
8245 CARLA_BACKEND_END_NAMESPACE
8246