1 // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
2 // SPDX-License-Identifier: GPL-2.0-or-later
5 // #define LV2_UIS_ONLY_BRIDGES
6 // #define LV2_UIS_ONLY_INPROCESS
8 #include "CarlaPluginInternal.hpp"
9 #include "CarlaEngine.hpp"
11 #include "CarlaLv2Utils.hpp"
13 #include "CarlaBackendUtils.hpp"
14 #include "CarlaBase64Utils.hpp"
15 #include "CarlaEngineUtils.hpp"
16 #include "CarlaPipeUtils.hpp"
17 #include "CarlaPluginUI.hpp"
18 #include "CarlaScopeUtils.hpp"
19 #include "Lv2AtomRingBuffer.hpp"
21 #include "../modules/lilv/config/lilv_config.h"
24 #include "rtmempool/rtmempool-lv2.h"
27 #include "water/files/File.h"
28 #include "water/misc/Time.h"
31 # include "CarlaMacUtils.hpp"
32 # if defined(CARLA_OS_64BIT) && defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
33 # define ADAPT_FOR_APPLE_SILLICON
34 # include "CarlaBinaryUtils.hpp"
39 # define LV2_UIS_ONLY_INPROCESS
47 #define URI_CARLA_ATOM_WORKER_IN "http://kxstudio.sf.net/ns/carla/atomWorkerIn"
48 #define URI_CARLA_ATOM_WORKER_RESP "http://kxstudio.sf.net/ns/carla/atomWorkerResp"
49 #define URI_CARLA_PARAMETER_CHANGE "http://kxstudio.sf.net/ns/carla/parameterChange"
51 CARLA_BACKEND_START_NAMESPACE
53 // -------------------------------------------------------------------------------------------------------------------
56 static const CustomData kCustomDataFallback
= { nullptr, nullptr, nullptr };
57 static /* */ CustomData kCustomDataFallbackNC
= { nullptr, nullptr, nullptr };
58 static const ExternalMidiNote kExternalMidiNoteFallback
= { -1, 0, 0 };
59 static const char* const kUnmapFallback
= "urn:null";
61 // -------------------------------------------------------------------------------------------------------------------
63 // Maximum default buffer size
64 const uint MAX_DEFAULT_BUFFER_SIZE
= 8192; // 0x2000
67 const uint PLUGIN_HAS_EXTENSION_OPTIONS
= 0x01000;
68 const uint PLUGIN_HAS_EXTENSION_PROGRAMS
= 0x02000;
69 const uint PLUGIN_HAS_EXTENSION_STATE
= 0x04000;
70 const uint PLUGIN_HAS_EXTENSION_WORKER
= 0x08000;
71 const uint PLUGIN_HAS_EXTENSION_INLINE_DISPLAY
= 0x10000;
72 const uint PLUGIN_HAS_EXTENSION_MIDNAM
= 0x20000;
74 // LV2 Event Data/Types
75 const uint CARLA_EVENT_DATA_ATOM
= 0x01;
76 const uint CARLA_EVENT_DATA_EVENT
= 0x02;
77 const uint CARLA_EVENT_DATA_MIDI_LL
= 0x04;
78 const uint CARLA_EVENT_TYPE_MESSAGE
= 0x10; // unused
79 const uint CARLA_EVENT_TYPE_MIDI
= 0x20;
80 const uint CARLA_EVENT_TYPE_TIME
= 0x40;
106 kUridAtomTransferAtom
,
107 kUridAtomTransferEvent
,
110 kUridBufNominalLength
,
111 kUridBufSequenceSize
,
127 kUridTimeBeatsPerBar
,
128 kUridTimeBeatsPerMinute
,
130 kUridTimeFramesPerSecond
,
132 kUridTimeTicksPerBeat
,
134 kUridParamSampleRate
,
136 kUridBackgroundColor
,
137 kUridForegroundColor
,
142 // custom carla props
143 kUridCarlaAtomWorkerIn
,
144 kUridCarlaAtomWorkerResp
,
145 kUridCarlaParameterChange
,
146 kUridCarlaTransientWindowId
,
152 enum CarlaLv2Features
{
154 kFeatureIdBufSizeBounded
= 0,
155 kFeatureIdBufSizeFixed
,
156 kFeatureIdBufSizePowerOf2
,
158 kFeatureIdHardRtCapable
,
159 kFeatureIdInPlaceBroken
,
164 kFeatureIdResizePort
,
166 kFeatureIdRtMemPoolOld
,
167 kFeatureIdStateFreePath
,
168 kFeatureIdStateMakePath
,
169 kFeatureIdStateMapPath
,
170 kFeatureIdStrictBounds
,
175 kFeatureIdInlineDisplay
,
177 kFeatureIdCtrlInPortChangeReq
,
180 kFeatureIdUiDataAccess
= kFeatureCountPlugin
,
181 kFeatureIdUiInstanceAccess
,
182 kFeatureIdUiIdleInterface
,
183 kFeatureIdUiFixedSize
,
184 kFeatureIdUiMakeResident
,
185 kFeatureIdUiMakeResident2
,
186 kFeatureIdUiNoUserResize
,
189 kFeatureIdUiPortSubscribe
,
191 kFeatureIdUiRequestValue
,
193 kFeatureIdExternalUi
,
194 kFeatureIdExternalUiOld
,
198 // LV2 Feature Ids (special state handlers)
199 enum CarlaLv2StateFeatures
{
200 kStateFeatureIdFreePath
,
201 kStateFeatureIdMakePath
,
202 kStateFeatureIdMapPath
,
203 kStateFeatureIdWorker
,
204 kStateFeatureCountAll
207 // -------------------------------------------------------------------------------------------------------------------
209 struct Lv2EventData
{
212 CarlaEngineEventPort
* port
;
215 LV2_Atom_Buffer
* atom
;
216 LV2_Event_Buffer
* event
;
220 Lv2EventData() noexcept
225 ~Lv2EventData() noexcept
233 const uint32_t rtype
= type
;
236 if (rtype
& CARLA_EVENT_DATA_ATOM
)
238 CARLA_SAFE_ASSERT_RETURN(atom
!= nullptr,);
243 else if (rtype
& CARLA_EVENT_DATA_EVENT
)
245 CARLA_SAFE_ASSERT_RETURN(event
!= nullptr,);
250 else if (rtype
& CARLA_EVENT_DATA_MIDI_LL
)
252 CARLA_SAFE_ASSERT_RETURN(midi
.data
!= nullptr,);
259 CARLA_DECLARE_NON_COPYABLE(Lv2EventData
)
262 union LV2EventIters
{
263 LV2_Atom_Buffer_Iterator atom
;
264 LV2_Event_Iterator event
;
265 LV2_MIDIState midiState
;
268 struct CarlaPluginLV2EventData
{
271 LV2EventIters
* iters
;
272 Lv2EventData
* ctrl
; // default port, either this->data[x] or pData->portIn/Out
275 CarlaPluginLV2EventData() noexcept
282 ~CarlaPluginLV2EventData() noexcept
284 CARLA_SAFE_ASSERT_INT(count
== 0, count
);
285 CARLA_SAFE_ASSERT(data
== nullptr);
286 CARLA_SAFE_ASSERT(iters
== nullptr);
287 CARLA_SAFE_ASSERT(ctrl
== nullptr);
288 CARLA_SAFE_ASSERT_INT(ctrlIndex
== 0, ctrlIndex
);
291 void createNew(const uint32_t newCount
)
293 CARLA_SAFE_ASSERT_INT(count
== 0, count
);
294 CARLA_SAFE_ASSERT_INT(ctrlIndex
== 0, ctrlIndex
);
295 CARLA_SAFE_ASSERT_RETURN(data
== nullptr,);
296 CARLA_SAFE_ASSERT_RETURN(iters
== nullptr,);
297 CARLA_SAFE_ASSERT_RETURN(ctrl
== nullptr,);
298 CARLA_SAFE_ASSERT_RETURN(newCount
> 0,);
300 data
= new Lv2EventData
[newCount
];
301 iters
= new LV2EventIters
[newCount
];
308 void clear(CarlaEngineEventPort
* const portToIgnore
) noexcept
312 for (uint32_t i
=0; i
< count
; ++i
)
314 if (data
[i
].port
!= nullptr)
316 if (data
[i
].port
!= portToIgnore
)
318 data
[i
].port
= nullptr;
326 if (iters
!= nullptr)
338 void initBuffers() const noexcept
340 for (uint32_t i
=0; i
< count
; ++i
)
342 if (data
[i
].port
!= nullptr && (ctrl
== nullptr || data
[i
].port
!= ctrl
->port
))
343 data
[i
].port
->initBuffer();
347 CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2EventData
)
350 // -------------------------------------------------------------------------------------------------------------------
352 struct CarlaPluginLV2Options
{
372 int nominalBufferSize
;
375 int64_t transientWinId
;
379 const char* windowTitle
;
380 LV2_Options_Option opts
[Count
];
382 CarlaPluginLV2Options() noexcept
385 nominalBufferSize(0),
386 sequenceSize(MAX_DEFAULT_BUFFER_SIZE
),
394 LV2_Options_Option
& optMaxBlockLenth(opts
[MaxBlockLenth
]);
395 optMaxBlockLenth
.context
= LV2_OPTIONS_INSTANCE
;
396 optMaxBlockLenth
.subject
= 0;
397 optMaxBlockLenth
.key
= kUridBufMaxLength
;
398 optMaxBlockLenth
.size
= sizeof(int);
399 optMaxBlockLenth
.type
= kUridAtomInt
;
400 optMaxBlockLenth
.value
= &maxBufferSize
;
402 LV2_Options_Option
& optMinBlockLenth(opts
[MinBlockLenth
]);
403 optMinBlockLenth
.context
= LV2_OPTIONS_INSTANCE
;
404 optMinBlockLenth
.subject
= 0;
405 optMinBlockLenth
.key
= kUridBufMinLength
;
406 optMinBlockLenth
.size
= sizeof(int);
407 optMinBlockLenth
.type
= kUridAtomInt
;
408 optMinBlockLenth
.value
= &minBufferSize
;
410 LV2_Options_Option
& optNominalBlockLenth(opts
[NominalBlockLenth
]);
411 optNominalBlockLenth
.context
= LV2_OPTIONS_INSTANCE
;
412 optNominalBlockLenth
.subject
= 0;
413 optNominalBlockLenth
.key
= kUridBufNominalLength
;
414 optNominalBlockLenth
.size
= sizeof(int);
415 optNominalBlockLenth
.type
= kUridAtomInt
;
416 optNominalBlockLenth
.value
= &nominalBufferSize
;
418 LV2_Options_Option
& optSequenceSize(opts
[SequenceSize
]);
419 optSequenceSize
.context
= LV2_OPTIONS_INSTANCE
;
420 optSequenceSize
.subject
= 0;
421 optSequenceSize
.key
= kUridBufSequenceSize
;
422 optSequenceSize
.size
= sizeof(int);
423 optSequenceSize
.type
= kUridAtomInt
;
424 optSequenceSize
.value
= &sequenceSize
;
426 LV2_Options_Option
& optBackgroundColor(opts
[BackgroundColor
]);
427 optBackgroundColor
.context
= LV2_OPTIONS_INSTANCE
;
428 optBackgroundColor
.subject
= 0;
429 optBackgroundColor
.key
= kUridBackgroundColor
;
430 optBackgroundColor
.size
= sizeof(int32_t);
431 optBackgroundColor
.type
= kUridAtomInt
;
432 optBackgroundColor
.value
= &bgColor
;
434 LV2_Options_Option
& optForegroundColor(opts
[ForegroundColor
]);
435 optForegroundColor
.context
= LV2_OPTIONS_INSTANCE
;
436 optForegroundColor
.subject
= 0;
437 optForegroundColor
.key
= kUridForegroundColor
;
438 optForegroundColor
.size
= sizeof(int32_t);
439 optForegroundColor
.type
= kUridAtomInt
;
440 optForegroundColor
.value
= &fgColor
;
443 LV2_Options_Option
& optScaleFactor(opts
[ScaleFactor
]);
444 optScaleFactor
.context
= LV2_OPTIONS_INSTANCE
;
445 optScaleFactor
.subject
= 0;
446 optScaleFactor
.key
= kUridScaleFactor
;
447 optScaleFactor
.size
= sizeof(float);
448 optScaleFactor
.type
= kUridAtomFloat
;
449 optScaleFactor
.value
= &uiScale
;
452 LV2_Options_Option
& optSampleRate(opts
[SampleRate
]);
453 optSampleRate
.context
= LV2_OPTIONS_INSTANCE
;
454 optSampleRate
.subject
= 0;
455 optSampleRate
.key
= kUridParamSampleRate
;
456 optSampleRate
.size
= sizeof(float);
457 optSampleRate
.type
= kUridAtomFloat
;
458 optSampleRate
.value
= &sampleRate
;
460 LV2_Options_Option
& optTransientWinId(opts
[TransientWinId
]);
461 optTransientWinId
.context
= LV2_OPTIONS_INSTANCE
;
462 optTransientWinId
.subject
= 0;
463 optTransientWinId
.key
= kUridCarlaTransientWindowId
;
464 optTransientWinId
.size
= sizeof(int64_t);
465 optTransientWinId
.type
= kUridAtomLong
;
466 optTransientWinId
.value
= &transientWinId
;
468 LV2_Options_Option
& optWindowTitle(opts
[WindowTitle
]);
469 optWindowTitle
.context
= LV2_OPTIONS_INSTANCE
;
470 optWindowTitle
.subject
= 0;
471 optWindowTitle
.key
= kUridWindowTitle
;
472 optWindowTitle
.size
= 0;
473 optWindowTitle
.type
= kUridAtomString
;
474 optWindowTitle
.value
= nullptr;
476 LV2_Options_Option
& optNull(opts
[Null
]);
477 optNull
.context
= LV2_OPTIONS_INSTANCE
;
479 optNull
.key
= kUridNull
;
481 optNull
.type
= kUridNull
;
482 optNull
.value
= nullptr;
485 ~CarlaPluginLV2Options() noexcept
487 LV2_Options_Option
& optWindowTitle(opts
[WindowTitle
]);
489 optWindowTitle
.size
= 0;
490 optWindowTitle
.value
= nullptr;
492 if (windowTitle
!= nullptr)
494 std::free(const_cast<char*>(windowTitle
));
495 windowTitle
= nullptr;
499 CARLA_DECLARE_NON_COPYABLE(CarlaPluginLV2Options
);
502 #ifndef LV2_UIS_ONLY_INPROCESS
503 // -------------------------------------------------------------------------------------------------------------------
505 class CarlaPluginLV2
;
507 class CarlaPipeServerLV2
: public CarlaPipeServer
517 CarlaPipeServerLV2(CarlaEngine
* const engine
, CarlaPluginLV2
* const plugin
)
525 ~CarlaPipeServerLV2() noexcept override
527 CARLA_SAFE_ASSERT_INT(fUiState
== UiNone
, fUiState
);
530 UiState
getAndResetUiState() noexcept
532 const UiState
uiState(fUiState
);
537 void setData(const char* const filename
, const char* const pluginURI
, const char* const uiURI
) noexcept
539 fFilename
= filename
;
540 fPluginURI
= pluginURI
;
544 bool startPipeServer(const int size
) noexcept
546 char sampleRateStr
[32];
548 const CarlaScopedLocale csl
;
549 std::snprintf(sampleRateStr
, 31, "%.12g", kEngine
->getSampleRate());
551 sampleRateStr
[31] = '\0';
553 const ScopedEngineEnvironmentLocker
_seel(kEngine
);
554 const CarlaScopedEnvVar
_sev1("LV2_PATH", kEngine
->getOptions().pathLV2
);
555 #ifdef CARLA_OS_LINUX
556 const CarlaScopedEnvVar
_sev2("LD_PRELOAD", nullptr);
558 carla_setenv("CARLA_SAMPLE_RATE", sampleRateStr
);
560 return CarlaPipeServer::startPipeServer(fFilename
, fPluginURI
, fUiURI
, size
);
563 void writeUiTitleMessage(const char* const title
) const noexcept
565 CARLA_SAFE_ASSERT_RETURN(title
!= nullptr && title
[0] != '\0',);
567 const CarlaMutexLocker
cml(getPipeLock());
569 if (! _writeMsgBuffer("uiTitle\n", 8))
571 if (! writeAndFixMessage(title
))
578 // returns true if msg was handled
579 bool msgReceived(const char* const msg
) noexcept override
;
582 CarlaEngine
* const kEngine
;
583 CarlaPluginLV2
* const kPlugin
;
585 CarlaString fFilename
;
586 CarlaString fPluginURI
;
590 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServerLV2
)
593 // -------------------------------------------------------------------------------------------------------------------
596 static void initAtomForge(LV2_Atom_Forge
& atomForge
) noexcept
598 carla_zeroStruct(atomForge
);
600 atomForge
.Bool
= kUridAtomBool
;
601 atomForge
.Chunk
= kUridAtomChunk
;
602 atomForge
.Double
= kUridAtomDouble
;
603 atomForge
.Float
= kUridAtomFloat
;
604 atomForge
.Int
= kUridAtomInt
;
605 atomForge
.Literal
= kUridAtomLiteral
;
606 atomForge
.Long
= kUridAtomLong
;
607 atomForge
.Object
= kUridAtomObject
;
608 atomForge
.Path
= kUridAtomPath
;
609 atomForge
.Property
= kUridAtomProperty
;
610 atomForge
.Sequence
= kUridAtomSequence
;
611 atomForge
.String
= kUridAtomString
;
612 atomForge
.Tuple
= kUridAtomTuple
;
613 atomForge
.URI
= kUridAtomURI
;
614 atomForge
.URID
= kUridAtomURID
;
615 atomForge
.Vector
= kUridAtomVector
;
617 #if defined(__clang__)
618 # pragma clang diagnostic push
619 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
620 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
621 # pragma GCC diagnostic push
622 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
624 atomForge
.Blank
= kUridAtomBlank
;
625 atomForge
.Resource
= kUridAtomResource
;
626 #if defined(__clang__)
627 # pragma clang diagnostic pop
628 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
629 # pragma GCC diagnostic pop
633 // -------------------------------------------------------------------------------------------------------------------
635 class CarlaPluginLV2
: public CarlaPlugin
,
636 private CarlaPluginUI::Callback
639 CarlaPluginLV2(CarlaEngine
* const engine
, const uint id
)
640 : CarlaPlugin(engine
, id
),
643 fDescriptor(nullptr),
644 fRdfDescriptor(nullptr),
645 fAudioInBuffers(nullptr),
646 fAudioOutBuffers(nullptr),
647 fCvInBuffers(nullptr),
648 fCvOutBuffers(nullptr),
649 fParamBuffers(nullptr),
650 fHasLoadDefaultState(false),
651 fHasThreadSafeRestore(false),
652 fNeedsFixedBuffers(false),
653 fNeedsUiClose(false),
654 fInlineDisplayNeedsRedraw(false),
655 fInlineDisplayLastRedrawTime(0),
660 fAtomBufferWorkerIn(),
661 fAtomBufferWorkerResp(),
662 fAtomBufferUiOutTmpData(nullptr),
663 fAtomBufferWorkerInTmpData(nullptr),
664 fAtomBufferRealtime(nullptr),
665 fAtomBufferRealtimeSize(0),
669 #ifndef LV2_UIS_ONLY_INPROCESS
670 fPipeServer(engine
, this),
672 fCustomURIDs(kUridCount
, std::string("urn:null")),
674 fLastStateChunk(nullptr),
680 carla_debug("CarlaPluginLV2::CarlaPluginLV2(%p, %i)", engine
, id
);
681 CARLA_SAFE_ASSERT(fCustomURIDs
.size() == kUridCount
);
683 carla_zeroPointers(fFeatures
, kFeatureCountAll
+1);
684 carla_zeroPointers(fStateFeatures
, kStateFeatureCountAll
+1);
687 ~CarlaPluginLV2() override
689 carla_debug("CarlaPluginLV2::~CarlaPluginLV2()");
691 fInlineDisplayNeedsRedraw
= false;
694 if (fUI
.type
!= UI::TYPE_NULL
)
698 #ifndef LV2_UIS_ONLY_INPROCESS
699 if (fUI
.type
== UI::TYPE_BRIDGE
)
701 fPipeServer
.stopPipeServer(pData
->engine
->getOptions().uiBridgesTimeout
);
706 if (fFeatures
[kFeatureIdUiDataAccess
] != nullptr && fFeatures
[kFeatureIdUiDataAccess
]->data
!= nullptr)
707 delete (LV2_Extension_Data_Feature
*)fFeatures
[kFeatureIdUiDataAccess
]->data
;
709 if (fFeatures
[kFeatureIdUiPortMap
] != nullptr && fFeatures
[kFeatureIdUiPortMap
]->data
!= nullptr)
710 delete (LV2UI_Port_Map
*)fFeatures
[kFeatureIdUiPortMap
]->data
;
712 if (fFeatures
[kFeatureIdUiRequestValue
] != nullptr && fFeatures
[kFeatureIdUiRequestValue
]->data
!= nullptr)
713 delete (LV2UI_Request_Value
*)fFeatures
[kFeatureIdUiRequestValue
]->data
;
715 if (fFeatures
[kFeatureIdUiResize
] != nullptr && fFeatures
[kFeatureIdUiResize
]->data
!= nullptr)
716 delete (LV2UI_Resize
*)fFeatures
[kFeatureIdUiResize
]->data
;
718 if (fFeatures
[kFeatureIdUiTouch
] != nullptr && fFeatures
[kFeatureIdUiTouch
]->data
!= nullptr)
719 delete (LV2UI_Touch
*)fFeatures
[kFeatureIdUiTouch
]->data
;
721 if (fFeatures
[kFeatureIdExternalUi
] != nullptr && fFeatures
[kFeatureIdExternalUi
]->data
!= nullptr)
722 delete (LV2_External_UI_Host
*)fFeatures
[kFeatureIdExternalUi
]->data
;
724 fUI
.descriptor
= nullptr;
728 #ifndef LV2_UIS_ONLY_BRIDGES
729 if (fUI
.window
!= nullptr)
732 fUI
.window
= nullptr;
736 fUI
.rdfDescriptor
= nullptr;
739 pData
->singleMutex
.lock();
740 pData
->masterMutex
.lock();
742 if (pData
->client
!= nullptr && pData
->client
->isActive())
743 pData
->client
->deactivate(true);
748 pData
->active
= false;
751 if (fExt
.state
!= nullptr)
753 const File
tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
756 tmpDir
.deleteRecursively();
759 if (fDescriptor
!= nullptr)
761 if (fDescriptor
->cleanup
!= nullptr)
763 if (fHandle
!= nullptr)
764 fDescriptor
->cleanup(fHandle
);
765 if (fHandle2
!= nullptr)
766 fDescriptor
->cleanup(fHandle2
);
771 fDescriptor
= nullptr;
774 if (fRdfDescriptor
!= nullptr)
776 delete fRdfDescriptor
;
777 fRdfDescriptor
= nullptr;
780 if (fFeatures
[kFeatureIdEvent
] != nullptr && fFeatures
[kFeatureIdEvent
]->data
!= nullptr)
781 delete (LV2_Event_Feature
*)fFeatures
[kFeatureIdEvent
]->data
;
783 if (fFeatures
[kFeatureIdLogs
] != nullptr && fFeatures
[kFeatureIdLogs
]->data
!= nullptr)
784 delete (LV2_Log_Log
*)fFeatures
[kFeatureIdLogs
]->data
;
786 if (fFeatures
[kFeatureIdStateFreePath
] != nullptr && fFeatures
[kFeatureIdStateFreePath
]->data
!= nullptr)
787 delete (LV2_State_Free_Path
*)fFeatures
[kFeatureIdStateFreePath
]->data
;
789 if (fFeatures
[kFeatureIdStateMakePath
] != nullptr && fFeatures
[kFeatureIdStateMakePath
]->data
!= nullptr)
790 delete (LV2_State_Make_Path
*)fFeatures
[kFeatureIdStateMakePath
]->data
;
792 if (fFeatures
[kFeatureIdStateMapPath
] != nullptr && fFeatures
[kFeatureIdStateMapPath
]->data
!= nullptr)
793 delete (LV2_State_Map_Path
*)fFeatures
[kFeatureIdStateMapPath
]->data
;
795 if (fFeatures
[kFeatureIdPrograms
] != nullptr && fFeatures
[kFeatureIdPrograms
]->data
!= nullptr)
796 delete (LV2_Programs_Host
*)fFeatures
[kFeatureIdPrograms
]->data
;
798 if (fFeatures
[kFeatureIdResizePort
] != nullptr && fFeatures
[kFeatureIdResizePort
]->data
!= nullptr)
799 delete (LV2_Resize_Port_Resize
*)fFeatures
[kFeatureIdResizePort
]->data
;
801 if (fFeatures
[kFeatureIdRtMemPool
] != nullptr && fFeatures
[kFeatureIdRtMemPool
]->data
!= nullptr)
802 delete (LV2_RtMemPool_Pool
*)fFeatures
[kFeatureIdRtMemPool
]->data
;
804 if (fFeatures
[kFeatureIdRtMemPoolOld
] != nullptr && fFeatures
[kFeatureIdRtMemPoolOld
]->data
!= nullptr)
805 delete (LV2_RtMemPool_Pool_Deprecated
*)fFeatures
[kFeatureIdRtMemPoolOld
]->data
;
807 if (fFeatures
[kFeatureIdUriMap
] != nullptr && fFeatures
[kFeatureIdUriMap
]->data
!= nullptr)
808 delete (LV2_URI_Map_Feature
*)fFeatures
[kFeatureIdUriMap
]->data
;
810 if (fFeatures
[kFeatureIdUridMap
] != nullptr && fFeatures
[kFeatureIdUridMap
]->data
!= nullptr)
811 delete (LV2_URID_Map
*)fFeatures
[kFeatureIdUridMap
]->data
;
813 if (fFeatures
[kFeatureIdUridUnmap
] != nullptr && fFeatures
[kFeatureIdUridUnmap
]->data
!= nullptr)
814 delete (LV2_URID_Unmap
*)fFeatures
[kFeatureIdUridUnmap
]->data
;
816 if (fFeatures
[kFeatureIdWorker
] != nullptr && fFeatures
[kFeatureIdWorker
]->data
!= nullptr)
817 delete (LV2_Worker_Schedule
*)fFeatures
[kFeatureIdWorker
]->data
;
819 if (fFeatures
[kFeatureIdInlineDisplay
] != nullptr && fFeatures
[kFeatureIdInlineDisplay
]->data
!= nullptr)
820 delete (LV2_Inline_Display
*)fFeatures
[kFeatureIdInlineDisplay
]->data
;
822 if (fFeatures
[kFeatureIdMidnam
] != nullptr && fFeatures
[kFeatureIdMidnam
]->data
!= nullptr)
823 delete (LV2_Midnam
*)fFeatures
[kFeatureIdMidnam
]->data
;
825 if (fFeatures
[kFeatureIdCtrlInPortChangeReq
] != nullptr && fFeatures
[kFeatureIdCtrlInPortChangeReq
]->data
!= nullptr)
826 delete (LV2_ControlInputPort_Change_Request
*)fFeatures
[kFeatureIdCtrlInPortChangeReq
]->data
;
828 for (uint32_t i
=0; i
< kFeatureCountAll
; ++i
)
830 if (fFeatures
[i
] != nullptr)
833 fFeatures
[i
] = nullptr;
837 if (fStateFeatures
[kStateFeatureIdMakePath
] != nullptr && fStateFeatures
[kStateFeatureIdMakePath
]->data
!= nullptr)
838 delete (LV2_State_Make_Path
*)fStateFeatures
[kStateFeatureIdMakePath
]->data
;
840 if (fStateFeatures
[kStateFeatureIdMapPath
] != nullptr && fStateFeatures
[kStateFeatureIdMapPath
]->data
!= nullptr)
841 delete (LV2_State_Map_Path
*)fStateFeatures
[kStateFeatureIdMapPath
]->data
;
843 for (uint32_t i
=0; i
< kStateFeatureCountAll
; ++i
)
845 if (fStateFeatures
[i
] != nullptr)
847 delete fStateFeatures
[i
];
848 fStateFeatures
[i
] = nullptr;
852 if (fLastStateChunk
!= nullptr)
854 std::free(fLastStateChunk
);
855 fLastStateChunk
= nullptr;
858 if (fAtomBufferUiOutTmpData
!= nullptr)
860 delete[] fAtomBufferUiOutTmpData
;
861 fAtomBufferUiOutTmpData
= nullptr;
864 if (fAtomBufferWorkerInTmpData
!= nullptr)
866 delete[] fAtomBufferWorkerInTmpData
;
867 fAtomBufferWorkerInTmpData
= nullptr;
870 if (fAtomBufferRealtime
!= nullptr)
872 std::free(fAtomBufferRealtime
);
873 fAtomBufferRealtime
= nullptr;
879 // -------------------------------------------------------------------
880 // Information (base)
882 PluginType
getType() const noexcept override
887 PluginCategory
getCategory() const noexcept override
889 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, CarlaPlugin::getCategory());
891 const LV2_Property
cat1(fRdfDescriptor
->Type
[0]);
892 const LV2_Property
cat2(fRdfDescriptor
->Type
[1]);
894 if (LV2_IS_DELAY(cat1
, cat2
))
895 return PLUGIN_CATEGORY_DELAY
;
896 if (LV2_IS_DISTORTION(cat1
, cat2
))
897 return PLUGIN_CATEGORY_OTHER
;
898 if (LV2_IS_DYNAMICS(cat1
, cat2
))
899 return PLUGIN_CATEGORY_DYNAMICS
;
900 if (LV2_IS_EQ(cat1
, cat2
))
901 return PLUGIN_CATEGORY_EQ
;
902 if (LV2_IS_FILTER(cat1
, cat2
))
903 return PLUGIN_CATEGORY_FILTER
;
904 if (LV2_IS_GENERATOR(cat1
, cat2
))
905 return PLUGIN_CATEGORY_SYNTH
;
906 if (LV2_IS_MODULATOR(cat1
, cat2
))
907 return PLUGIN_CATEGORY_MODULATOR
;
908 if (LV2_IS_REVERB(cat1
, cat2
))
909 return PLUGIN_CATEGORY_DELAY
;
910 if (LV2_IS_SIMULATOR(cat1
, cat2
))
911 return PLUGIN_CATEGORY_OTHER
;
912 if (LV2_IS_SPATIAL(cat1
, cat2
))
913 return PLUGIN_CATEGORY_OTHER
;
914 if (LV2_IS_SPECTRAL(cat1
, cat2
))
915 return PLUGIN_CATEGORY_UTILITY
;
916 if (LV2_IS_UTILITY(cat1
, cat2
))
917 return PLUGIN_CATEGORY_UTILITY
;
919 return CarlaPlugin::getCategory();
922 uint32_t getLatencyInFrames() const noexcept override
924 if (fLatencyIndex
< 0 || fParamBuffers
== nullptr)
927 const float latency(fParamBuffers
[fLatencyIndex
]);
928 CARLA_SAFE_ASSERT_RETURN(latency
>= 0.0f
, 0);
930 return static_cast<uint32_t>(latency
);
933 // -------------------------------------------------------------------
934 // Information (count)
936 uint32_t getMidiInCount() const noexcept override
938 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, 0);
942 for (uint32_t i
=0; i
< fRdfDescriptor
->PortCount
; ++i
)
944 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[i
].Types
);
946 if (LV2_IS_PORT_INPUT(portTypes
) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes
))
953 uint32_t getMidiOutCount() const noexcept override
955 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, 0);
959 for (uint32_t i
=0; i
< fRdfDescriptor
->PortCount
; ++i
)
961 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[i
].Types
);
963 if (LV2_IS_PORT_OUTPUT(portTypes
) && LV2_PORT_SUPPORTS_MIDI_EVENT(portTypes
))
970 uint32_t getParameterScalePointCount(const uint32_t parameterId
) const noexcept override
972 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, 0);
973 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, 0);
975 const int32_t rindex(pData
->param
.data
[parameterId
].rindex
);
977 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
979 const LV2_RDF_Port
* const port(&fRdfDescriptor
->Ports
[rindex
]);
980 return port
->ScalePointCount
;
986 // -------------------------------------------------------------------
987 // Information (current data)
989 uint
getAudioPortHints(bool isOutput
, uint32_t portIndex
) const noexcept override
993 for (uint32_t i
=0, j
=0; i
<fRdfDescriptor
->PortCount
; ++i
)
995 LV2_RDF_Port
& port(fRdfDescriptor
->Ports
[i
]);
997 if (! LV2_IS_PORT_AUDIO(port
.Types
))
1002 if (! LV2_IS_PORT_OUTPUT(port
.Types
))
1007 if (! LV2_IS_PORT_INPUT(port
.Types
))
1011 if (j
++ != portIndex
)
1014 if (LV2_IS_PORT_SIDECHAIN(port
.Properties
))
1015 hints
|= AUDIO_PORT_IS_SIDECHAIN
;
1023 // -------------------------------------------------------------------
1024 // Information (per-plugin data)
1026 uint
getOptionsAvailable() const noexcept override
1030 // can't disable fixed buffers if using latency or MIDI output
1031 if (fLatencyIndex
== -1 && getMidiOutCount() == 0 && ! fNeedsFixedBuffers
)
1032 options
|= PLUGIN_OPTION_FIXED_BUFFERS
;
1034 // can't disable forced stereo if enabled in the engine
1035 if (pData
->engine
->getOptions().forceStereo
)
1037 // if there are event outputs, we can't force stereo
1038 else if (fEventsOut
.count
!= 0)
1040 // if inputs or outputs are just 1, then yes we can force stereo
1041 else if ((pData
->audioIn
.count
== 1 || pData
->audioOut
.count
== 1) || fHandle2
!= nullptr)
1042 options
|= PLUGIN_OPTION_FORCE_STEREO
;
1044 if (fExt
.programs
!= nullptr)
1045 options
|= PLUGIN_OPTION_MAP_PROGRAM_CHANGES
;
1047 if (getMidiInCount() != 0)
1049 options
|= PLUGIN_OPTION_SEND_CONTROL_CHANGES
;
1050 options
|= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE
;
1051 options
|= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH
;
1052 options
|= PLUGIN_OPTION_SEND_PITCHBEND
;
1053 options
|= PLUGIN_OPTION_SEND_ALL_SOUND_OFF
;
1054 options
|= PLUGIN_OPTION_SEND_PROGRAM_CHANGES
;
1055 options
|= PLUGIN_OPTION_SKIP_SENDING_NOTES
;
1061 float getParameterValue(const uint32_t parameterId
) const noexcept override
1063 CARLA_SAFE_ASSERT_RETURN(fParamBuffers
!= nullptr, 0.0f
);
1064 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, 0.0f
);
1066 if (pData
->param
.data
[parameterId
].type
== PARAMETER_INPUT
)
1068 if (pData
->param
.data
[parameterId
].hints
& PARAMETER_IS_STRICT_BOUNDS
)
1069 pData
->param
.ranges
[parameterId
].fixValue(fParamBuffers
[parameterId
]);
1073 if (fStrictBounds
>= 0 && (pData
->param
.data
[parameterId
].hints
& PARAMETER_IS_STRICT_BOUNDS
) == 0)
1074 pData
->param
.ranges
[parameterId
].fixValue(fParamBuffers
[parameterId
]);
1077 return fParamBuffers
[parameterId
];
1080 float getParameterScalePointValue(const uint32_t parameterId
, const uint32_t scalePointId
) const noexcept override
1082 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, 0.0f
);
1083 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, 0.0f
);
1085 const int32_t rindex(pData
->param
.data
[parameterId
].rindex
);
1087 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1089 const LV2_RDF_Port
* const port(&fRdfDescriptor
->Ports
[rindex
]);
1090 CARLA_SAFE_ASSERT_RETURN(scalePointId
< port
->ScalePointCount
, 0.0f
);
1092 const LV2_RDF_PortScalePoint
* const portScalePoint(&port
->ScalePoints
[scalePointId
]);
1093 return portScalePoint
->Value
;
1099 bool getLabel(char* const strBuf
) const noexcept override
1101 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1102 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
->URI
!= nullptr, false);
1104 std::strncpy(strBuf
, fRdfDescriptor
->URI
, STR_MAX
);
1108 bool getMaker(char* const strBuf
) const noexcept override
1110 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1112 if (fRdfDescriptor
->Author
!= nullptr)
1114 std::strncpy(strBuf
, fRdfDescriptor
->Author
, STR_MAX
);
1121 bool getCopyright(char* const strBuf
) const noexcept override
1123 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1125 if (fRdfDescriptor
->License
!= nullptr)
1127 std::strncpy(strBuf
, fRdfDescriptor
->License
, STR_MAX
);
1134 bool getRealName(char* const strBuf
) const noexcept override
1136 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1138 if (fRdfDescriptor
->Name
!= nullptr)
1140 std::strncpy(strBuf
, fRdfDescriptor
->Name
, STR_MAX
);
1147 bool getParameterName(const uint32_t parameterId
, char* const strBuf
) const noexcept override
1149 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1150 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1152 int32_t rindex
= pData
->param
.data
[parameterId
].rindex
;
1153 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1155 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1157 std::strncpy(strBuf
, fRdfDescriptor
->Ports
[rindex
].Name
, STR_MAX
);
1161 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1163 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
))
1165 std::strncpy(strBuf
, fRdfDescriptor
->Parameters
[rindex
].Label
, STR_MAX
);
1169 return CarlaPlugin::getParameterName(parameterId
, strBuf
);
1172 bool getParameterSymbol(const uint32_t parameterId
, char* const strBuf
) const noexcept override
1174 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1175 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1177 int32_t rindex
= pData
->param
.data
[parameterId
].rindex
;
1178 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1180 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1182 std::strncpy(strBuf
, fRdfDescriptor
->Ports
[rindex
].Symbol
, STR_MAX
);
1186 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1188 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
))
1190 std::strncpy(strBuf
, fRdfDescriptor
->Parameters
[rindex
].URI
, STR_MAX
);
1194 return CarlaPlugin::getParameterSymbol(parameterId
, strBuf
);
1197 bool getParameterUnit(const uint32_t parameterId
, char* const strBuf
) const noexcept override
1199 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1200 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1202 LV2_RDF_PortUnit
* portUnit
= nullptr;
1204 int32_t rindex
= pData
->param
.data
[parameterId
].rindex
;
1205 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1207 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1209 portUnit
= &fRdfDescriptor
->Ports
[rindex
].Unit
;
1213 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1215 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
))
1217 portUnit
= &fRdfDescriptor
->Parameters
[rindex
].Unit
;
1221 if (portUnit
!= nullptr)
1223 if (LV2_HAVE_PORT_UNIT_SYMBOL(portUnit
->Hints
) && portUnit
->Symbol
!= nullptr)
1225 std::strncpy(strBuf
, portUnit
->Symbol
, STR_MAX
);
1229 if (LV2_HAVE_PORT_UNIT_UNIT(portUnit
->Hints
))
1231 switch (portUnit
->Unit
)
1233 case LV2_PORT_UNIT_BAR
:
1234 std::strncpy(strBuf
, "bars", STR_MAX
);
1236 case LV2_PORT_UNIT_BEAT
:
1237 std::strncpy(strBuf
, "beats", STR_MAX
);
1239 case LV2_PORT_UNIT_BPM
:
1240 std::strncpy(strBuf
, "BPM", STR_MAX
);
1242 case LV2_PORT_UNIT_CENT
:
1243 std::strncpy(strBuf
, "ct", STR_MAX
);
1245 case LV2_PORT_UNIT_CM
:
1246 std::strncpy(strBuf
, "cm", STR_MAX
);
1248 case LV2_PORT_UNIT_COEF
:
1249 std::strncpy(strBuf
, "(coef)", STR_MAX
);
1251 case LV2_PORT_UNIT_DB
:
1252 std::strncpy(strBuf
, "dB", STR_MAX
);
1254 case LV2_PORT_UNIT_DEGREE
:
1255 std::strncpy(strBuf
, "deg", STR_MAX
);
1257 case LV2_PORT_UNIT_FRAME
:
1258 std::strncpy(strBuf
, "frames", STR_MAX
);
1260 case LV2_PORT_UNIT_HZ
:
1261 std::strncpy(strBuf
, "Hz", STR_MAX
);
1263 case LV2_PORT_UNIT_INCH
:
1264 std::strncpy(strBuf
, "in", STR_MAX
);
1266 case LV2_PORT_UNIT_KHZ
:
1267 std::strncpy(strBuf
, "kHz", STR_MAX
);
1269 case LV2_PORT_UNIT_KM
:
1270 std::strncpy(strBuf
, "km", STR_MAX
);
1272 case LV2_PORT_UNIT_M
:
1273 std::strncpy(strBuf
, "m", STR_MAX
);
1275 case LV2_PORT_UNIT_MHZ
:
1276 std::strncpy(strBuf
, "MHz", STR_MAX
);
1278 case LV2_PORT_UNIT_MIDINOTE
:
1279 std::strncpy(strBuf
, "note", STR_MAX
);
1281 case LV2_PORT_UNIT_MILE
:
1282 std::strncpy(strBuf
, "mi", STR_MAX
);
1284 case LV2_PORT_UNIT_MIN
:
1285 std::strncpy(strBuf
, "min", STR_MAX
);
1287 case LV2_PORT_UNIT_MM
:
1288 std::strncpy(strBuf
, "mm", STR_MAX
);
1290 case LV2_PORT_UNIT_MS
:
1291 std::strncpy(strBuf
, "ms", STR_MAX
);
1293 case LV2_PORT_UNIT_OCT
:
1294 std::strncpy(strBuf
, "oct", STR_MAX
);
1296 case LV2_PORT_UNIT_PC
:
1297 std::strncpy(strBuf
, "%", STR_MAX
);
1299 case LV2_PORT_UNIT_S
:
1300 std::strncpy(strBuf
, "s", STR_MAX
);
1302 case LV2_PORT_UNIT_SEMITONE
:
1303 std::strncpy(strBuf
, "semi", STR_MAX
);
1305 case LV2_PORT_UNIT_VOLTS
:
1306 std::strncpy(strBuf
, "v", STR_MAX
);
1312 return CarlaPlugin::getParameterUnit(parameterId
, strBuf
);
1315 bool getParameterComment(const uint32_t parameterId
, char* const strBuf
) const noexcept override
1317 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1318 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1320 int32_t rindex
= pData
->param
.data
[parameterId
].rindex
;
1321 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1323 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1325 if (const char* const comment
= fRdfDescriptor
->Ports
[rindex
].Comment
)
1327 std::strncpy(strBuf
, comment
, STR_MAX
);
1333 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1335 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
))
1337 if (const char* const comment
= fRdfDescriptor
->Parameters
[rindex
].Comment
)
1339 std::strncpy(strBuf
, comment
, STR_MAX
);
1345 return CarlaPlugin::getParameterComment(parameterId
, strBuf
);
1348 bool getParameterGroupName(const uint32_t parameterId
, char* const strBuf
) const noexcept override
1350 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1351 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1353 int32_t rindex
= pData
->param
.data
[parameterId
].rindex
;
1354 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1356 const char* uri
= nullptr;
1358 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1360 uri
= fRdfDescriptor
->Ports
[rindex
].GroupURI
;
1364 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1366 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
))
1367 uri
= fRdfDescriptor
->Parameters
[rindex
].GroupURI
;
1373 for (uint32_t i
=0; i
<fRdfDescriptor
->PortGroupCount
; ++i
)
1375 if (std::strcmp(fRdfDescriptor
->PortGroups
[i
].URI
, uri
) == 0)
1377 const char* const name
= fRdfDescriptor
->PortGroups
[i
].Name
;
1378 const char* const symbol
= fRdfDescriptor
->PortGroups
[i
].Symbol
;
1380 if (name
!= nullptr && symbol
!= nullptr)
1382 std::snprintf(strBuf
, STR_MAX
, "%s:%s", symbol
, name
);
1392 bool getParameterScalePointLabel(const uint32_t parameterId
, const uint32_t scalePointId
, char* const strBuf
) const noexcept override
1394 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
1395 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
, false);
1397 const int32_t rindex(pData
->param
.data
[parameterId
].rindex
);
1398 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0, false);
1400 if (rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1402 const LV2_RDF_Port
* const port(&fRdfDescriptor
->Ports
[rindex
]);
1403 CARLA_SAFE_ASSERT_RETURN(scalePointId
< port
->ScalePointCount
, false);
1405 const LV2_RDF_PortScalePoint
* const portScalePoint(&port
->ScalePoints
[scalePointId
]);
1407 if (portScalePoint
->Label
!= nullptr)
1409 std::strncpy(strBuf
, portScalePoint
->Label
, STR_MAX
);
1414 return CarlaPlugin::getParameterScalePointLabel(parameterId
, scalePointId
, strBuf
);
1417 // -------------------------------------------------------------------
1420 void prepareForSave(const bool temporary
) override
1422 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
1424 if (fExt
.state
!= nullptr && fExt
.state
->save
!= nullptr)
1426 // move temporary stuff to main state dir on full save
1429 const File
tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
1431 if (tmpDir
.exists())
1433 const File
stateDir(handleStateMapToAbsolutePath(true, false, false, "."));
1435 if (stateDir
.isNotNull())
1436 tmpDir
.moveFileTo(stateDir
);
1440 fExt
.state
->save(fHandle
, carla_lv2_state_store
, this, LV2_STATE_IS_POD
, fStateFeatures
);
1442 if (fHandle2
!= nullptr)
1443 fExt
.state
->save(fHandle2
, carla_lv2_state_store
, this, LV2_STATE_IS_POD
, fStateFeatures
);
1447 // -------------------------------------------------------------------
1448 // Set data (internal stuff)
1450 void setName(const char* const newName
) override
1452 const File
tmpDir1(handleStateMapToAbsolutePath(false, false, true, "."));
1454 CarlaPlugin::setName(newName
);
1456 if (tmpDir1
.exists())
1458 const File
tmpDir2(handleStateMapToAbsolutePath(false, false, true, "."));
1460 carla_stdout("dir1 %s, dir2 %s",
1461 tmpDir1
.getFullPathName().toRawUTF8(),
1462 tmpDir2
.getFullPathName().toRawUTF8());
1464 if (tmpDir2
.isNotNull())
1466 if (tmpDir2
.exists())
1467 tmpDir2
.deleteRecursively();
1469 tmpDir1
.moveFileTo(tmpDir2
);
1473 if (fLv2Options
.windowTitle
!= nullptr && pData
->uiTitle
.isEmpty())
1474 setWindowTitle(nullptr);
1477 void setWindowTitle(const char* const title
) noexcept
1479 CarlaString uiTitle
;
1481 if (title
!= nullptr)
1487 uiTitle
= pData
->name
;
1488 uiTitle
+= " (GUI)";
1491 std::free(const_cast<char*>(fLv2Options
.windowTitle
));
1492 fLv2Options
.windowTitle
= uiTitle
.releaseBufferPointer();
1494 fLv2Options
.opts
[CarlaPluginLV2Options::WindowTitle
].size
= (uint32_t)std::strlen(fLv2Options
.windowTitle
);
1495 fLv2Options
.opts
[CarlaPluginLV2Options::WindowTitle
].value
= fLv2Options
.windowTitle
;
1497 if (fFeatures
[kFeatureIdExternalUi
] != nullptr && fFeatures
[kFeatureIdExternalUi
]->data
!= nullptr)
1498 ((LV2_External_UI_Host
*)fFeatures
[kFeatureIdExternalUi
]->data
)->plugin_human_id
= fLv2Options
.windowTitle
;
1500 #ifndef LV2_UIS_ONLY_INPROCESS
1501 if (fPipeServer
.isPipeRunning())
1502 fPipeServer
.writeUiTitleMessage(fLv2Options
.windowTitle
);
1505 #ifndef LV2_UIS_ONLY_BRIDGES
1506 if (fUI
.window
!= nullptr)
1509 fUI
.window
->setTitle(fLv2Options
.windowTitle
);
1510 } CARLA_SAFE_EXCEPTION("set custom title");
1515 // -------------------------------------------------------------------
1516 // Set data (plugin-specific stuff)
1518 float setParamterValueCommon(const uint32_t parameterId
, const float value
) noexcept
1520 const float fixedValue(pData
->param
.getFixedValue(parameterId
, value
));
1521 fParamBuffers
[parameterId
] = fixedValue
;
1523 if (pData
->param
.data
[parameterId
].rindex
>= static_cast<int32_t>(fRdfDescriptor
->PortCount
))
1525 const uint32_t rparamId
= static_cast<uint32_t>(pData
->param
.data
[parameterId
].rindex
) - fRdfDescriptor
->PortCount
;
1526 CARLA_SAFE_ASSERT_UINT2_RETURN(rparamId
< fRdfDescriptor
->ParameterCount
,
1527 rparamId
, fRdfDescriptor
->PortCount
, fixedValue
);
1529 uint8_t atomBuf
[256];
1530 LV2_Atom_Forge atomForge
;
1531 initAtomForge(atomForge
);
1532 lv2_atom_forge_set_buffer(&atomForge
, atomBuf
, sizeof(atomBuf
));
1534 LV2_Atom_Forge_Frame forgeFrame
;
1535 lv2_atom_forge_object(&atomForge
, &forgeFrame
, kUridNull
, kUridPatchSet
);
1537 lv2_atom_forge_key(&atomForge
, kUridCarlaParameterChange
);
1538 lv2_atom_forge_bool(&atomForge
, true);
1540 lv2_atom_forge_key(&atomForge
, kUridPatchProperty
);
1541 lv2_atom_forge_urid(&atomForge
, getCustomURID(fRdfDescriptor
->Parameters
[rparamId
].URI
));
1543 lv2_atom_forge_key(&atomForge
, kUridPatchValue
);
1545 switch (fRdfDescriptor
->Parameters
[rparamId
].Type
)
1547 case LV2_PARAMETER_TYPE_BOOL
:
1548 lv2_atom_forge_bool(&atomForge
, fixedValue
> 0.5f
);
1550 case LV2_PARAMETER_TYPE_INT
:
1551 lv2_atom_forge_int(&atomForge
, static_cast<int32_t>(fixedValue
+ 0.5f
));
1553 case LV2_PARAMETER_TYPE_LONG
:
1554 lv2_atom_forge_long(&atomForge
, static_cast<int64_t>(fixedValue
+ 0.5f
));
1556 case LV2_PARAMETER_TYPE_FLOAT
:
1557 lv2_atom_forge_float(&atomForge
, fixedValue
);
1559 case LV2_PARAMETER_TYPE_DOUBLE
:
1560 lv2_atom_forge_double(&atomForge
, fixedValue
);
1563 carla_stderr2("setParameterValue called for invalid parameter, expect issues!");
1567 lv2_atom_forge_pop(&atomForge
, &forgeFrame
);
1569 LV2_Atom
* const atom((LV2_Atom
*)atomBuf
);
1570 CARLA_SAFE_ASSERT(atom
->size
< sizeof(atomBuf
));
1572 fAtomBufferEvIn
.put(atom
, fEventsIn
.ctrlIndex
);
1578 void setParameterValue(const uint32_t parameterId
, const float value
, const bool sendGui
, const bool sendOsc
, const bool sendCallback
) noexcept override
1580 CARLA_SAFE_ASSERT_RETURN(fParamBuffers
!= nullptr,);
1581 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
,);
1583 const float fixedValue
= setParamterValueCommon(parameterId
, value
);
1585 CarlaPlugin::setParameterValue(parameterId
, fixedValue
, sendGui
, sendOsc
, sendCallback
);
1588 void setParameterValueRT(const uint32_t parameterId
, const float value
, const uint32_t frameOffset
, const bool sendCallbackLater
) noexcept override
1590 CARLA_SAFE_ASSERT_RETURN(fParamBuffers
!= nullptr,);
1591 CARLA_SAFE_ASSERT_RETURN(parameterId
< pData
->param
.count
,);
1593 const float fixedValue
= setParamterValueCommon(parameterId
, value
);
1595 CarlaPlugin::setParameterValueRT(parameterId
, fixedValue
, frameOffset
, sendCallbackLater
);
1598 void setCustomData(const char* const type
, const char* const key
, const char* const value
, const bool sendGui
) override
1600 CARLA_SAFE_ASSERT_RETURN(fDescriptor
!= nullptr,);
1601 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
1602 CARLA_SAFE_ASSERT_RETURN(type
!= nullptr && type
[0] != '\0',);
1603 CARLA_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0',);
1604 CARLA_SAFE_ASSERT_RETURN(value
!= nullptr,);
1605 carla_debug("CarlaPluginLV2::setCustomData(\"%s\", \"%s\", \"%s\", %s)", type
, key
, value
, bool2str(sendGui
));
1607 if (std::strcmp(type
, CUSTOM_DATA_TYPE_PATH
) == 0)
1609 if (std::strcmp(key
, "file") != 0)
1612 CARLA_SAFE_ASSERT_RETURN(fFilePathURI
.isNotEmpty(),);
1613 CARLA_SAFE_ASSERT_RETURN(value
[0] != '\0',);
1615 carla_stdout("LV2 file path to send: '%s'", value
);
1616 writeAtomPath(value
, getCustomURID(fFilePathURI
));
1620 if (std::strcmp(type
, CUSTOM_DATA_TYPE_PROPERTY
) == 0)
1621 return CarlaPlugin::setCustomData(type
, key
, value
, sendGui
);
1623 // See if this key is from a parameter exposed by carla, apply value if yes
1624 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
1626 const LV2_RDF_Parameter
& rdfParam(fRdfDescriptor
->Parameters
[i
]);
1628 if (std::strcmp(rdfParam
.URI
, key
) == 0)
1630 uint32_t parameterId
= UINT32_MAX
;
1631 const int32_t rindex
= static_cast<int32_t>(fRdfDescriptor
->PortCount
+ i
);
1633 switch (rdfParam
.Type
)
1635 case LV2_PARAMETER_TYPE_BOOL
:
1636 case LV2_PARAMETER_TYPE_INT
:
1637 // case LV2_PARAMETER_TYPE_LONG:
1638 case LV2_PARAMETER_TYPE_FLOAT
:
1639 case LV2_PARAMETER_TYPE_DOUBLE
:
1640 for (uint32_t j
=0; j
< pData
->param
.count
; ++j
)
1642 if (pData
->param
.data
[j
].rindex
== rindex
)
1651 if (parameterId
== UINT32_MAX
)
1654 std::vector
<uint8_t> chunk(carla_getChunkFromBase64String(value
));
1655 CARLA_SAFE_ASSERT_RETURN(chunk
.size() > 0,);
1657 #ifdef CARLA_PROPER_CPP11_SUPPORT
1658 const uint8_t* const valueptr
= chunk
.data();
1660 const uint8_t* const valueptr
= &chunk
.front();
1664 switch (rdfParam
.Type
)
1666 case LV2_PARAMETER_TYPE_BOOL
:
1667 rvalue
= *(const int32_t*)valueptr
!= 0 ? 1.0f
: 0.0f
;
1669 case LV2_PARAMETER_TYPE_INT
:
1670 rvalue
= static_cast<float>(*(const int32_t*)valueptr
);
1672 case LV2_PARAMETER_TYPE_FLOAT
:
1673 rvalue
= *(const float*)valueptr
;
1675 case LV2_PARAMETER_TYPE_DOUBLE
:
1676 rvalue
= static_cast<float>(*(const double*)valueptr
);
1679 // making compilers happy
1680 rvalue
= pData
->param
.ranges
[parameterId
].def
;
1684 fParamBuffers
[parameterId
] = pData
->param
.getFixedValue(parameterId
, rvalue
);
1689 CarlaPlugin::setCustomData(type
, key
, value
, sendGui
);
1692 void setProgram(const int32_t index
, const bool sendGui
, const bool sendOsc
, const bool sendCallback
, const bool doingInit
) noexcept override
1694 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
1695 CARLA_SAFE_ASSERT_RETURN(index
>= -1 && index
< static_cast<int32_t>(pData
->prog
.count
),);
1696 CARLA_SAFE_ASSERT_RETURN(sendGui
|| sendOsc
|| sendCallback
,);
1698 if (index
>= 0 && index
< static_cast<int32_t>(fRdfDescriptor
->PresetCount
))
1700 const LV2_URID_Map
* const uridMap
= (const LV2_URID_Map
*)fFeatures
[kFeatureIdUridMap
]->data
;
1702 LilvState
* const state
= Lv2WorldClass::getInstance().getStateFromURI(fRdfDescriptor
->Presets
[index
].URI
,
1704 CARLA_SAFE_ASSERT_RETURN(state
!= nullptr,);
1706 // invalidate midi-program selection
1707 CarlaPlugin::setMidiProgram(-1, false, false, sendCallback
, false);
1709 if (fExt
.state
!= nullptr)
1711 const bool block
= (sendGui
|| sendOsc
|| sendCallback
) && !fHasThreadSafeRestore
;
1712 const ScopedSingleProcessLocker
spl(this, block
);
1714 lilv_state_restore(state
, fExt
.state
, fHandle
, carla_lilv_set_port_value
, this, 0, fFeatures
);
1716 if (fHandle2
!= nullptr)
1717 lilv_state_restore(state
, fExt
.state
, fHandle2
, carla_lilv_set_port_value
, this, 0, fFeatures
);
1721 lilv_state_emit_port_values(state
, carla_lilv_set_port_value
, this);
1724 lilv_state_free(state
);
1727 CarlaPlugin::setProgram(index
, sendGui
, sendOsc
, sendCallback
, doingInit
);
1730 void setMidiProgram(const int32_t index
, const bool sendGui
, const bool sendOsc
, const bool sendCallback
, const bool doingInit
) noexcept override
1732 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
1733 CARLA_SAFE_ASSERT_RETURN(index
>= -1 && index
< static_cast<int32_t>(pData
->midiprog
.count
),);
1734 CARLA_SAFE_ASSERT_RETURN(sendGui
|| sendOsc
|| sendCallback
|| doingInit
,);
1736 if (index
>= 0 && fExt
.programs
!= nullptr && fExt
.programs
->select_program
!= nullptr)
1738 const uint32_t bank(pData
->midiprog
.data
[index
].bank
);
1739 const uint32_t program(pData
->midiprog
.data
[index
].program
);
1741 const ScopedSingleProcessLocker
spl(this, (sendGui
|| sendOsc
|| sendCallback
));
1744 fExt
.programs
->select_program(fHandle
, bank
, program
);
1745 } CARLA_SAFE_EXCEPTION("select program");
1747 if (fHandle2
!= nullptr)
1750 fExt
.programs
->select_program(fHandle2
, bank
, program
);
1751 } CARLA_SAFE_EXCEPTION("select program 2");
1755 CarlaPlugin::setMidiProgram(index
, sendGui
, sendOsc
, sendCallback
, doingInit
);
1758 void setMidiProgramRT(const uint32_t uindex
, const bool sendCallbackLater
) noexcept override
1760 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
1761 CARLA_SAFE_ASSERT_RETURN(uindex
< pData
->midiprog
.count
,);
1763 if (fExt
.programs
!= nullptr && fExt
.programs
->select_program
!= nullptr)
1765 const uint32_t bank(pData
->midiprog
.data
[uindex
].bank
);
1766 const uint32_t program(pData
->midiprog
.data
[uindex
].program
);
1769 fExt
.programs
->select_program(fHandle
, bank
, program
);
1770 } CARLA_SAFE_EXCEPTION("select program RT");
1772 if (fHandle2
!= nullptr)
1775 fExt
.programs
->select_program(fHandle2
, bank
, program
);
1776 } CARLA_SAFE_EXCEPTION("select program RT 2");
1780 CarlaPlugin::setMidiProgramRT(uindex
, sendCallbackLater
);
1783 // -------------------------------------------------------------------
1786 void setCustomUITitle(const char* const title
) noexcept override
1788 setWindowTitle(title
);
1789 CarlaPlugin::setCustomUITitle(title
);
1792 void showCustomUI(const bool yesNo
) override
1794 if (fUI
.type
== UI::TYPE_NULL
)
1796 if (yesNo
&& fFilePathURI
.isNotEmpty())
1798 const char* const path
= pData
->engine
->runFileCallback(FILE_CALLBACK_OPEN
, false, "Open File", "");
1800 if (path
!= nullptr && path
[0] != '\0')
1802 carla_stdout("LV2 file path to send: '%s'", path
);
1803 writeAtomPath(path
, getCustomURID(fFilePathURI
));
1808 CARLA_SAFE_ASSERT(!yesNo
);
1810 pData
->engine
->callback(true, true,
1811 ENGINE_CALLBACK_UI_STATE_CHANGED
, pData
->id
, 0, 0, 0, 0.0f
, nullptr);
1815 const uintptr_t frontendWinId
= pData
->engine
->getOptions().frontendWinId
;
1817 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
1819 pData
->transientTryCounter
= 0;
1822 #ifndef LV2_UIS_ONLY_INPROCESS
1823 if (fUI
.type
== UI::TYPE_BRIDGE
)
1827 if (fPipeServer
.isPipeRunning())
1829 fPipeServer
.writeFocusMessage();
1833 if (! fPipeServer
.startPipeServer(std::min(fLv2Options
.sequenceSize
, 819200)))
1835 pData
->engine
->callback(true, true,
1836 ENGINE_CALLBACK_UI_STATE_CHANGED
, pData
->id
, 0, 0, 0, 0.0f
, nullptr);
1840 // manually write messages so we can take the lock for ourselves
1843 tmpBuf
[0xfe] = '\0';
1845 const CarlaMutexLocker
cml(fPipeServer
.getPipeLock());
1846 const CarlaScopedLocale csl
;
1848 // write URI mappings
1850 for (std::vector
<std::string
>::iterator it
=fCustomURIDs
.begin(), end
=fCustomURIDs
.end(); it
!= end
; ++it
, ++u
)
1854 const std::string
& uri(*it
);
1856 if (! fPipeServer
.writeMessage("urid\n", 5))
1859 std::snprintf(tmpBuf
, 0xfe, "%u\n", u
);
1860 if (! fPipeServer
.writeMessage(tmpBuf
))
1863 std::snprintf(tmpBuf
, 0xfe, "%lu\n", static_cast<long unsigned>(uri
.length()));
1864 if (! fPipeServer
.writeMessage(tmpBuf
))
1867 if (! fPipeServer
.writeAndFixMessage(uri
.c_str()))
1872 if (! fPipeServer
.writeMessage("uiOptions\n", 10))
1875 const EngineOptions
& opts(pData
->engine
->getOptions());
1877 std::snprintf(tmpBuf
, 0xff, "%g\n", pData
->engine
->getSampleRate());
1878 if (! fPipeServer
.writeMessage(tmpBuf
))
1881 std::snprintf(tmpBuf
, 0xff, "%u\n", opts
.bgColor
);
1882 if (! fPipeServer
.writeMessage(tmpBuf
))
1885 std::snprintf(tmpBuf
, 0xff, "%u\n", opts
.fgColor
);
1886 if (! fPipeServer
.writeMessage(tmpBuf
))
1889 std::snprintf(tmpBuf
, 0xff, "%.12g\n", static_cast<double>(opts
.uiScale
));
1890 if (! fPipeServer
.writeMessage(tmpBuf
))
1893 std::snprintf(tmpBuf
, 0xff, "%s\n", bool2str(true)); // useTheme
1894 if (! fPipeServer
.writeMessage(tmpBuf
))
1897 std::snprintf(tmpBuf
, 0xff, "%s\n", bool2str(true)); // useThemeColors
1898 if (! fPipeServer
.writeMessage(tmpBuf
))
1901 if (! fPipeServer
.writeAndFixMessage(fLv2Options
.windowTitle
!= nullptr
1902 ? fLv2Options
.windowTitle
1906 std::snprintf(tmpBuf
, 0xff, P_INTPTR
"\n", frontendWinId
);
1907 if (! fPipeServer
.writeMessage(tmpBuf
))
1910 // write parameter values
1911 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
1913 ParameterData
& pdata(pData
->param
.data
[i
]);
1915 if (pdata
.hints
& PARAMETER_IS_NOT_SAVED
)
1917 int32_t rindex
= pdata
.rindex
;
1918 CARLA_SAFE_ASSERT_CONTINUE(rindex
- static_cast<int32_t>(fRdfDescriptor
->PortCount
) >= 0);
1920 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
1921 CARLA_SAFE_ASSERT_CONTINUE(rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
));
1923 if (! fPipeServer
.writeLv2ParameterMessage(fRdfDescriptor
->Parameters
[rindex
].URI
,
1924 getParameterValue(i
), false))
1929 if (! fPipeServer
.writeControlMessage(static_cast<uint32_t>(pData
->param
.data
[i
].rindex
),
1930 getParameterValue(i
), false))
1936 if (! fPipeServer
.writeMessage("show\n", 5))
1939 fPipeServer
.syncMessages();
1942 #ifndef BUILD_BRIDGE
1943 if (fUI
.rdfDescriptor
->Type
== LV2_UI_MOD
)
1944 pData
->tryTransient();
1949 fPipeServer
.stopPipeServer(pData
->engine
->getOptions().uiBridgesTimeout
);
1955 // take some precautions
1956 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
!= nullptr,);
1957 CARLA_SAFE_ASSERT_RETURN(fUI
.rdfDescriptor
!= nullptr,);
1961 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
->instantiate
!= nullptr,);
1962 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
->cleanup
!= nullptr,);
1966 if (fUI
.handle
== nullptr)
1972 if (fUI
.handle
== nullptr)
1974 #ifndef LV2_UIS_ONLY_BRIDGES
1975 if (fUI
.type
== UI::TYPE_EMBED
&& fUI
.rdfDescriptor
->Type
!= LV2_UI_NONE
&& fUI
.window
== nullptr)
1977 const char* msg
= nullptr;
1978 const bool isStandalone
= pData
->engine
->getOptions().pluginsAreStandalone
;
1980 switch (fUI
.rdfDescriptor
->Type
)
1986 case LV2_UI_EXTERNAL
:
1987 case LV2_UI_OLD_EXTERNAL
:
1988 msg
= "Invalid UI type";
1992 # ifdef CARLA_OS_MAC
1993 fUI
.window
= CarlaPluginUI::newCocoa(this, frontendWinId
, isStandalone
, isUiResizable());
1995 msg
= "UI is for MacOS only";
1999 case LV2_UI_WINDOWS
:
2000 # ifdef CARLA_OS_WIN
2001 fUI
.window
= CarlaPluginUI::newWindows(this, frontendWinId
, isStandalone
, isUiResizable());
2003 msg
= "UI is for Windows only";
2009 fUI
.window
= CarlaPluginUI::newX11(this, frontendWinId
, isStandalone
, isUiResizable(), true);
2011 msg
= "UI is only for systems with X11";
2016 msg
= "Unknown UI type";
2020 if (fUI
.window
== nullptr && fExt
.uishow
== nullptr)
2021 return pData
->engine
->callback(true, true,
2022 ENGINE_CALLBACK_UI_STATE_CHANGED
, pData
->id
, -1, 0, 0, 0.0f
, msg
);
2024 if (fUI
.window
!= nullptr)
2025 fFeatures
[kFeatureIdUiParent
]->data
= fUI
.window
->getPtr();
2028 fUI
.widget
= nullptr;
2029 fUI
.handle
= fUI
.descriptor
->instantiate(fUI
.descriptor
, fRdfDescriptor
->URI
, fUI
.rdfDescriptor
->Bundle
,
2030 carla_lv2_ui_write_function
, this, &fUI
.widget
, fFeatures
);
2032 if (fUI
.window
!= nullptr)
2034 if (fUI
.widget
!= nullptr)
2035 fUI
.window
->setChildWindow(fUI
.widget
);
2036 fUI
.window
->setTitle(fLv2Options
.windowTitle
);
2040 CARLA_SAFE_ASSERT(fUI
.handle
!= nullptr);
2041 CARLA_SAFE_ASSERT(fUI
.type
!= UI::TYPE_EXTERNAL
|| fUI
.widget
!= nullptr);
2043 if (fUI
.handle
== nullptr || (fUI
.type
== UI::TYPE_EXTERNAL
&& fUI
.widget
== nullptr))
2045 fUI
.widget
= nullptr;
2047 if (fUI
.handle
!= nullptr)
2049 fUI
.descriptor
->cleanup(fUI
.handle
);
2050 fUI
.handle
= nullptr;
2053 return pData
->engine
->callback(true, true,
2054 ENGINE_CALLBACK_UI_STATE_CHANGED
,
2058 "Plugin refused to open its own UI");
2063 #ifndef LV2_UIS_ONLY_BRIDGES
2064 if (fUI
.type
== UI::TYPE_EMBED
)
2066 if (fUI
.window
!= nullptr)
2070 else if (fExt
.uishow
!= nullptr)
2072 fExt
.uishow
->show(fUI
.handle
);
2073 # ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2074 pData
->tryTransient();
2081 LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget
*)fUI
.widget
);
2082 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2083 pData
->tryTransient();
2089 #ifndef LV2_UIS_ONLY_BRIDGES
2090 if (fUI
.type
== UI::TYPE_EMBED
)
2092 if (fUI
.window
!= nullptr)
2094 else if (fExt
.uishow
!= nullptr)
2095 fExt
.uishow
->hide(fUI
.handle
);
2100 CARLA_SAFE_ASSERT(fUI
.widget
!= nullptr);
2102 if (fUI
.widget
!= nullptr)
2103 LV2_EXTERNAL_UI_HIDE((LV2_External_UI_Widget
*)fUI
.widget
);
2106 fUI
.descriptor
->cleanup(fUI
.handle
);
2107 fUI
.handle
= nullptr;
2108 fUI
.widget
= nullptr;
2110 if (fUI
.type
== UI::TYPE_EMBED
&& fUI
.window
!= nullptr)
2113 fUI
.window
= nullptr;
2118 #ifndef LV2_UIS_ONLY_BRIDGES
2119 void* embedCustomUI(void* const ptr
) override
2121 CARLA_SAFE_ASSERT_RETURN(fUI
.type
== UI::TYPE_EMBED
, nullptr);
2122 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
!= nullptr, nullptr);
2123 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
->instantiate
!= nullptr, nullptr);
2124 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
->cleanup
!= nullptr, nullptr);
2125 CARLA_SAFE_ASSERT_RETURN(fUI
.rdfDescriptor
->Type
!= LV2_UI_NONE
, nullptr);
2126 CARLA_SAFE_ASSERT_RETURN(fUI
.window
== nullptr, nullptr);
2128 fFeatures
[kFeatureIdUiParent
]->data
= ptr
;
2130 fUI
.embedded
= true;
2131 fUI
.widget
= nullptr;
2132 fUI
.handle
= fUI
.descriptor
->instantiate(fUI
.descriptor
, fRdfDescriptor
->URI
, fUI
.rdfDescriptor
->Bundle
,
2133 carla_lv2_ui_write_function
, this, &fUI
.widget
, fFeatures
);
2141 void idle() override
2143 if (fAtomBufferWorkerIn
.isDataAvailableForReading())
2145 Lv2AtomRingBuffer
tmpRingBuffer(fAtomBufferWorkerIn
, fAtomBufferWorkerInTmpData
);
2146 CARLA_SAFE_ASSERT_RETURN(tmpRingBuffer
.isDataAvailableForReading(),);
2147 CARLA_SAFE_ASSERT_RETURN(fExt
.worker
!= nullptr && fExt
.worker
->work
!= nullptr,);
2149 const size_t localSize
= fAtomBufferWorkerIn
.getSize();
2150 uint8_t* const localData
= new uint8_t[localSize
];
2151 LV2_Atom
* const localAtom
= static_cast<LV2_Atom
*>(static_cast<void*>(localData
));
2152 localAtom
->size
= localSize
;
2155 for (; tmpRingBuffer
.get(portIndex
, localAtom
); localAtom
->size
= localSize
)
2157 CARLA_SAFE_ASSERT_CONTINUE(localAtom
->type
== kUridCarlaAtomWorkerIn
);
2158 fExt
.worker
->work(fHandle
, carla_lv2_worker_respond
, this, localAtom
->size
, LV2_ATOM_BODY_CONST(localAtom
));
2164 if (fInlineDisplayNeedsRedraw
)
2167 CARLA_SAFE_ASSERT(pData
->enabled
)
2168 CARLA_SAFE_ASSERT(!pData
->engine
->isAboutToClose());
2169 CARLA_SAFE_ASSERT(pData
->client
->isActive());
2171 if (pData
->enabled
&& !pData
->engine
->isAboutToClose() && pData
->client
->isActive())
2173 const int64_t timeNow
= water::Time::currentTimeMillis();
2175 if (timeNow
- fInlineDisplayLastRedrawTime
> (1000 / 30))
2177 fInlineDisplayNeedsRedraw
= false;
2178 fInlineDisplayLastRedrawTime
= timeNow
;
2179 pData
->engine
->callback(true, true,
2180 ENGINE_CALLBACK_INLINE_DISPLAY_REDRAW
,
2182 0, 0, 0, 0.0f
, nullptr);
2187 fInlineDisplayNeedsRedraw
= false;
2191 CarlaPlugin::idle();
2194 void uiIdle() override
2196 if (const char* const fileNeededForURI
= fUI
.fileNeededForURI
)
2198 fUI
.fileBrowserOpen
= true;
2199 fUI
.fileNeededForURI
= nullptr;
2201 const char* const path
= pData
->engine
->runFileCallback(FILE_CALLBACK_OPEN
,
2203 /* title */ "File open",
2206 fUI
.fileBrowserOpen
= false;
2208 if (path
!= nullptr)
2210 carla_stdout("LV2 requested path to send: '%s'", path
);
2211 writeAtomPath(path
, getCustomURID(fileNeededForURI
));
2214 // this function will be called recursively, stop here
2218 if (fAtomBufferUiOut
.isDataAvailableForReading())
2220 Lv2AtomRingBuffer
tmpRingBuffer(fAtomBufferUiOut
, fAtomBufferUiOutTmpData
);
2221 CARLA_SAFE_ASSERT(tmpRingBuffer
.isDataAvailableForReading());
2223 const size_t localSize
= fAtomBufferUiOut
.getSize();
2224 uint8_t* const localData
= new uint8_t[localSize
];
2225 LV2_Atom
* const localAtom
= static_cast<LV2_Atom
*>(static_cast<void*>(localData
));
2226 localAtom
->size
= localSize
;
2229 const bool hasPortEvent(fUI
.handle
!= nullptr &&
2230 fUI
.descriptor
!= nullptr &&
2231 fUI
.descriptor
->port_event
!= nullptr);
2233 for (; tmpRingBuffer
.get(portIndex
, localAtom
); localAtom
->size
= localSize
)
2235 #ifndef LV2_UIS_ONLY_INPROCESS
2236 if (fUI
.type
== UI::TYPE_BRIDGE
)
2238 if (fPipeServer
.isPipeRunning())
2239 fPipeServer
.writeLv2AtomMessage(portIndex
, localAtom
);
2244 if (hasPortEvent
&& ! fNeedsUiClose
)
2245 fUI
.descriptor
->port_event(fUI
.handle
, portIndex
, lv2_atom_total_size(localAtom
), kUridAtomTransferEvent
, localAtom
);
2248 inspectAtomForParameterChange(localAtom
);
2254 #ifndef LV2_UIS_ONLY_INPROCESS
2255 if (fPipeServer
.isPipeRunning())
2257 fPipeServer
.idlePipe();
2259 switch (fPipeServer
.getAndResetUiState())
2261 case CarlaPipeServerLV2::UiNone
:
2262 case CarlaPipeServerLV2::UiShow
:
2264 case CarlaPipeServerLV2::UiHide
:
2265 fPipeServer
.stopPipeServer(2000);
2267 case CarlaPipeServerLV2::UiCrashed
:
2268 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
2269 pData
->transientTryCounter
= 0;
2271 pData
->engine
->callback(true, true,
2272 ENGINE_CALLBACK_UI_STATE_CHANGED
,
2275 0, 0, 0.0f
, nullptr);
2281 // TODO - detect if ui-bridge crashed
2287 fNeedsUiClose
= false;
2288 showCustomUI(false);
2289 pData
->engine
->callback(true, true,
2290 ENGINE_CALLBACK_UI_STATE_CHANGED
,
2293 0, 0, 0.0f
, nullptr);
2295 else if (fUI
.handle
!= nullptr && fUI
.descriptor
!= nullptr)
2297 if (fUI
.type
== UI::TYPE_EXTERNAL
&& fUI
.widget
!= nullptr)
2298 LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget
*)fUI
.widget
);
2299 #ifndef LV2_UIS_ONLY_BRIDGES
2300 else if (fUI
.type
== UI::TYPE_EMBED
&& fUI
.window
!= nullptr)
2303 // note: UI might have been closed by window idle
2308 else if (fUI
.handle
!= nullptr && fExt
.uiidle
!= nullptr && fExt
.uiidle
->idle(fUI
.handle
) != 0)
2310 showCustomUI(false);
2311 pData
->engine
->callback(true, true,
2312 ENGINE_CALLBACK_UI_STATE_CHANGED
,
2315 0, 0, 0.0f
, nullptr);
2316 CARLA_SAFE_ASSERT(fUI
.handle
== nullptr);
2321 CarlaPlugin::uiIdle();
2324 // -------------------------------------------------------------------
2327 void reload() override
2329 CARLA_SAFE_ASSERT_RETURN(pData
->engine
!= nullptr,);
2330 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
2331 CARLA_SAFE_ASSERT_RETURN(fDescriptor
!= nullptr,);
2332 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr,);
2333 carla_debug("CarlaPluginLV2::reload() - start");
2335 const EngineProcessMode
processMode(pData
->engine
->getProccessMode());
2337 // Safely disable plugin for reload
2338 const ScopedDisabler
sd(this);
2345 const float sampleRate(static_cast<float>(pData
->engine
->getSampleRate()));
2346 const uint32_t portCount(fRdfDescriptor
->PortCount
);
2348 uint32_t aIns
, aOuts
, cvIns
, cvOuts
, params
;
2349 aIns
= aOuts
= cvIns
= cvOuts
= params
= 0;
2350 LinkedList
<uint
> evIns
, evOuts
;
2352 const uint32_t eventBufferSize
= static_cast<uint32_t>(fLv2Options
.sequenceSize
) + 0xff;
2354 bool forcedStereoIn
, forcedStereoOut
;
2355 forcedStereoIn
= forcedStereoOut
= false;
2357 bool needsCtrlIn
, needsCtrlOut
, hasPatchParameterOutputs
;
2358 needsCtrlIn
= needsCtrlOut
= hasPatchParameterOutputs
= false;
2360 for (uint32_t i
=0; i
< portCount
; ++i
)
2362 const LV2_Property portTypes
= fRdfDescriptor
->Ports
[i
].Types
;
2364 if (LV2_IS_PORT_AUDIO(portTypes
))
2366 if (LV2_IS_PORT_INPUT(portTypes
))
2368 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2371 else if (LV2_IS_PORT_CV(portTypes
))
2373 if (LV2_IS_PORT_INPUT(portTypes
))
2375 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2378 else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes
))
2380 if (LV2_IS_PORT_INPUT(portTypes
))
2381 evIns
.append(CARLA_EVENT_DATA_ATOM
);
2382 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2383 evOuts
.append(CARLA_EVENT_DATA_ATOM
);
2385 else if (LV2_IS_PORT_EVENT(portTypes
))
2387 if (LV2_IS_PORT_INPUT(portTypes
))
2388 evIns
.append(CARLA_EVENT_DATA_EVENT
);
2389 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2390 evOuts
.append(CARLA_EVENT_DATA_EVENT
);
2392 else if (LV2_IS_PORT_MIDI_LL(portTypes
))
2394 if (LV2_IS_PORT_INPUT(portTypes
))
2395 evIns
.append(CARLA_EVENT_DATA_MIDI_LL
);
2396 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2397 evOuts
.append(CARLA_EVENT_DATA_MIDI_LL
);
2399 else if (LV2_IS_PORT_CONTROL(portTypes
))
2403 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
2405 switch (fRdfDescriptor
->Parameters
[i
].Type
)
2407 case LV2_PARAMETER_TYPE_BOOL
:
2408 case LV2_PARAMETER_TYPE_INT
:
2409 // case LV2_PARAMETER_TYPE_LONG:
2410 case LV2_PARAMETER_TYPE_FLOAT
:
2411 case LV2_PARAMETER_TYPE_DOUBLE
:
2414 case LV2_PARAMETER_TYPE_PATH
:
2415 if (fFilePathURI
.isEmpty())
2416 fFilePathURI
= fRdfDescriptor
->Parameters
[i
].URI
;
2421 if ((pData
->options
& PLUGIN_OPTION_FORCE_STEREO
) != 0 && aIns
<= 1 && aOuts
<= 1 && evOuts
.count() == 0 && fExt
.state
== nullptr && fExt
.worker
== nullptr)
2423 if (fHandle2
== nullptr)
2426 fHandle2
= fDescriptor
->instantiate(fDescriptor
, sampleRate
, fRdfDescriptor
->Bundle
, fFeatures
);
2430 if (fHandle2
!= nullptr)
2435 forcedStereoIn
= true;
2441 forcedStereoOut
= true;
2448 pData
->audioIn
.createNew(aIns
);
2449 fAudioInBuffers
= new float*[aIns
];
2451 for (uint32_t i
=0; i
< aIns
; ++i
)
2452 fAudioInBuffers
[i
] = nullptr;
2457 pData
->audioOut
.createNew(aOuts
);
2458 fAudioOutBuffers
= new float*[aOuts
];
2461 for (uint32_t i
=0; i
< aOuts
; ++i
)
2462 fAudioOutBuffers
[i
] = nullptr;
2467 pData
->cvIn
.createNew(cvIns
);
2468 fCvInBuffers
= new float*[cvIns
];
2470 for (uint32_t i
=0; i
< cvIns
; ++i
)
2471 fCvInBuffers
[i
] = nullptr;
2476 pData
->cvOut
.createNew(cvOuts
);
2477 fCvOutBuffers
= new float*[cvOuts
];
2479 for (uint32_t i
=0; i
< cvOuts
; ++i
)
2480 fCvOutBuffers
[i
] = nullptr;
2485 pData
->param
.createNew(params
, true);
2486 fParamBuffers
= new float[params
];
2487 carla_zeroFloats(fParamBuffers
, params
);
2490 if (const uint32_t count
= static_cast<uint32_t>(evIns
.count()))
2492 fEventsIn
.createNew(count
);
2494 for (uint32_t i
=0; i
< count
; ++i
)
2496 const uint32_t type
= evIns
.getAt(i
, 0x0);
2498 if (type
== CARLA_EVENT_DATA_ATOM
)
2500 fEventsIn
.data
[i
].type
= CARLA_EVENT_DATA_ATOM
;
2501 fEventsIn
.data
[i
].atom
= lv2_atom_buffer_new(eventBufferSize
, kUridNull
, kUridAtomSequence
, true);
2503 else if (type
== CARLA_EVENT_DATA_EVENT
)
2505 fEventsIn
.data
[i
].type
= CARLA_EVENT_DATA_EVENT
;
2506 fEventsIn
.data
[i
].event
= lv2_event_buffer_new(eventBufferSize
, LV2_EVENT_AUDIO_STAMP
);
2508 else if (type
== CARLA_EVENT_DATA_MIDI_LL
)
2510 fEventsIn
.data
[i
].type
= CARLA_EVENT_DATA_MIDI_LL
;
2511 fEventsIn
.data
[i
].midi
.capacity
= eventBufferSize
;
2512 fEventsIn
.data
[i
].midi
.data
= new uchar
[eventBufferSize
];
2518 fEventsIn
.createNew(1);
2519 fEventsIn
.ctrl
= &fEventsIn
.data
[0];
2522 if (const uint32_t count
= static_cast<uint32_t>(evOuts
.count()))
2524 fEventsOut
.createNew(count
);
2526 for (uint32_t i
=0; i
< count
; ++i
)
2528 const uint32_t type
= evOuts
.getAt(i
, 0x0);
2530 if (type
== CARLA_EVENT_DATA_ATOM
)
2532 fEventsOut
.data
[i
].type
= CARLA_EVENT_DATA_ATOM
;
2533 fEventsOut
.data
[i
].atom
= lv2_atom_buffer_new(eventBufferSize
, kUridNull
, kUridAtomSequence
, false);
2535 else if (type
== CARLA_EVENT_DATA_EVENT
)
2537 fEventsOut
.data
[i
].type
= CARLA_EVENT_DATA_EVENT
;
2538 fEventsOut
.data
[i
].event
= lv2_event_buffer_new(eventBufferSize
, LV2_EVENT_AUDIO_STAMP
);
2540 else if (type
== CARLA_EVENT_DATA_MIDI_LL
)
2542 fEventsOut
.data
[i
].type
= CARLA_EVENT_DATA_MIDI_LL
;
2543 fEventsOut
.data
[i
].midi
.capacity
= eventBufferSize
;
2544 fEventsOut
.data
[i
].midi
.data
= new uchar
[eventBufferSize
];
2549 const uint
portNameSize(pData
->engine
->getMaxPortNameSize());
2550 CarlaString portName
;
2553 for (uint32_t i
=0, iAudioIn
=0, iAudioOut
=0, iCvIn
=0, iCvOut
=0, iEvIn
=0, iEvOut
=0; i
< portCount
; ++i
)
2555 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[i
].Types
);
2559 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
))
2561 if (processMode
== ENGINE_PROCESS_MODE_SINGLE_CLIENT
)
2563 portName
= pData
->name
;
2567 portName
+= fRdfDescriptor
->Ports
[i
].Name
;
2568 portName
.truncate(portNameSize
);
2571 if (LV2_IS_PORT_AUDIO(portTypes
))
2573 if (LV2_IS_PORT_INPUT(portTypes
))
2575 const uint32_t j
= iAudioIn
++;
2576 pData
->audioIn
.ports
[j
].port
= (CarlaEngineAudioPort
*)pData
->client
->addPort(kEnginePortTypeAudio
, portName
, true, j
);
2577 pData
->audioIn
.ports
[j
].rindex
= i
;
2582 pData
->audioIn
.ports
[1].port
= (CarlaEngineAudioPort
*)pData
->client
->addPort(kEnginePortTypeAudio
, portName
, true, 1);
2583 pData
->audioIn
.ports
[1].rindex
= i
;
2586 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2588 const uint32_t j
= iAudioOut
++;
2589 pData
->audioOut
.ports
[j
].port
= (CarlaEngineAudioPort
*)pData
->client
->addPort(kEnginePortTypeAudio
, portName
, false, j
);
2590 pData
->audioOut
.ports
[j
].rindex
= i
;
2592 if (forcedStereoOut
)
2595 pData
->audioOut
.ports
[1].port
= (CarlaEngineAudioPort
*)pData
->client
->addPort(kEnginePortTypeAudio
, portName
, false, 1);
2596 pData
->audioOut
.ports
[1].rindex
= i
;
2600 carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
2602 else if (LV2_IS_PORT_CV(portTypes
))
2604 const LV2_RDF_PortPoints
portPoints(fRdfDescriptor
->Ports
[i
].Points
);
2608 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints
.Hints
))
2609 min
= portPoints
.Minimum
;
2614 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints
.Hints
))
2615 max
= portPoints
.Maximum
;
2619 if (LV2_IS_PORT_INPUT(portTypes
))
2621 const uint32_t j
= iCvIn
++;
2622 pData
->cvIn
.ports
[j
].port
= (CarlaEngineCVPort
*)pData
->client
->addPort(kEnginePortTypeCV
, portName
, true, j
);
2623 pData
->cvIn
.ports
[j
].rindex
= i
;
2624 pData
->cvIn
.ports
[j
].port
->setRange(min
, max
);
2626 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2628 const uint32_t j
= iCvOut
++;
2629 pData
->cvOut
.ports
[j
].port
= (CarlaEngineCVPort
*)pData
->client
->addPort(kEnginePortTypeCV
, portName
, false, j
);
2630 pData
->cvOut
.ports
[j
].rindex
= i
;
2631 pData
->cvOut
.ports
[j
].port
->setRange(min
, max
);
2634 carla_stderr("WARNING - Got a broken Port (CV, but not input or output)");
2636 else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes
))
2638 if (LV2_IS_PORT_INPUT(portTypes
))
2640 const uint32_t j
= iEvIn
++;
2642 fDescriptor
->connect_port(fHandle
, i
, &fEventsIn
.data
[j
].atom
->atoms
);
2644 if (fHandle2
!= nullptr)
2645 fDescriptor
->connect_port(fHandle2
, i
, &fEventsIn
.data
[j
].atom
->atoms
);
2647 fEventsIn
.data
[j
].rindex
= i
;
2649 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2650 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2651 if (portTypes
& LV2_PORT_DATA_PATCH_MESSAGE
)
2652 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_MESSAGE
;
2653 if (portTypes
& LV2_PORT_DATA_TIME_POSITION
)
2654 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_TIME
;
2656 if (evIns
.count() == 1)
2658 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2659 fEventsIn
.ctrlIndex
= j
;
2661 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2666 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2667 fEventsIn
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, true, j
);
2669 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2671 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2672 fEventsIn
.ctrlIndex
= j
;
2676 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2678 const uint32_t j
= iEvOut
++;
2680 fDescriptor
->connect_port(fHandle
, i
, &fEventsOut
.data
[j
].atom
->atoms
);
2682 if (fHandle2
!= nullptr)
2683 fDescriptor
->connect_port(fHandle2
, i
, &fEventsOut
.data
[j
].atom
->atoms
);
2685 fEventsOut
.data
[j
].rindex
= i
;
2687 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2688 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2689 if (portTypes
& LV2_PORT_DATA_PATCH_MESSAGE
)
2690 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_MESSAGE
;
2691 if (portTypes
& LV2_PORT_DATA_TIME_POSITION
)
2692 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_TIME
;
2694 if (evOuts
.count() == 1)
2696 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2697 fEventsOut
.ctrlIndex
= j
;
2699 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2700 needsCtrlOut
= true;
2704 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2705 fEventsOut
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, false, j
);
2707 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2709 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2710 fEventsOut
.ctrlIndex
= j
;
2715 carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
2717 else if (LV2_IS_PORT_EVENT(portTypes
))
2719 if (LV2_IS_PORT_INPUT(portTypes
))
2721 const uint32_t j
= iEvIn
++;
2723 fDescriptor
->connect_port(fHandle
, i
, fEventsIn
.data
[j
].event
);
2725 if (fHandle2
!= nullptr)
2726 fDescriptor
->connect_port(fHandle2
, i
, fEventsIn
.data
[j
].event
);
2728 fEventsIn
.data
[j
].rindex
= i
;
2730 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2731 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2732 if (portTypes
& LV2_PORT_DATA_PATCH_MESSAGE
)
2733 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_MESSAGE
;
2734 if (portTypes
& LV2_PORT_DATA_TIME_POSITION
)
2735 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_TIME
;
2737 if (evIns
.count() == 1)
2739 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2740 fEventsIn
.ctrlIndex
= j
;
2742 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2747 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2748 fEventsIn
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, true, j
);
2750 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2752 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2753 fEventsIn
.ctrlIndex
= j
;
2757 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2759 const uint32_t j
= iEvOut
++;
2761 fDescriptor
->connect_port(fHandle
, i
, fEventsOut
.data
[j
].event
);
2763 if (fHandle2
!= nullptr)
2764 fDescriptor
->connect_port(fHandle2
, i
, fEventsOut
.data
[j
].event
);
2766 fEventsOut
.data
[j
].rindex
= i
;
2768 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2769 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2770 if (portTypes
& LV2_PORT_DATA_PATCH_MESSAGE
)
2771 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_MESSAGE
;
2772 if (portTypes
& LV2_PORT_DATA_TIME_POSITION
)
2773 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_TIME
;
2775 if (evOuts
.count() == 1)
2777 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2778 fEventsOut
.ctrlIndex
= j
;
2780 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2781 needsCtrlOut
= true;
2785 if (portTypes
& LV2_PORT_DATA_MIDI_EVENT
)
2786 fEventsOut
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, false, j
);
2788 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2790 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2791 fEventsOut
.ctrlIndex
= j
;
2796 carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
2798 else if (LV2_IS_PORT_MIDI_LL(portTypes
))
2800 if (LV2_IS_PORT_INPUT(portTypes
))
2802 const uint32_t j
= iEvIn
++;
2804 fDescriptor
->connect_port(fHandle
, i
, &fEventsIn
.data
[j
].midi
);
2806 if (fHandle2
!= nullptr)
2807 fDescriptor
->connect_port(fHandle2
, i
, &fEventsIn
.data
[j
].midi
);
2809 fEventsIn
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2810 fEventsIn
.data
[j
].rindex
= i
;
2812 if (evIns
.count() == 1)
2815 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2816 fEventsIn
.ctrlIndex
= j
;
2820 fEventsIn
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, true, j
);
2822 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2824 fEventsIn
.ctrl
= &fEventsIn
.data
[j
];
2825 fEventsIn
.ctrlIndex
= j
;
2829 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2831 const uint32_t j
= iEvOut
++;
2833 fDescriptor
->connect_port(fHandle
, i
, &fEventsOut
.data
[j
].midi
);
2835 if (fHandle2
!= nullptr)
2836 fDescriptor
->connect_port(fHandle2
, i
, &fEventsOut
.data
[j
].midi
);
2838 fEventsOut
.data
[j
].type
|= CARLA_EVENT_TYPE_MIDI
;
2839 fEventsOut
.data
[j
].rindex
= i
;
2841 if (evOuts
.count() == 1)
2843 needsCtrlOut
= true;
2844 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2845 fEventsOut
.ctrlIndex
= j
;
2849 fEventsOut
.data
[j
].port
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, false, j
);
2851 if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor
->Ports
[i
].Designation
))
2853 fEventsOut
.ctrl
= &fEventsOut
.data
[j
];
2854 fEventsOut
.ctrlIndex
= j
;
2859 carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
2861 else if (LV2_IS_PORT_CONTROL(portTypes
))
2863 const LV2_Property
portProps(fRdfDescriptor
->Ports
[i
].Properties
);
2864 const LV2_Property
portDesignation(fRdfDescriptor
->Ports
[i
].Designation
);
2865 const LV2_RDF_PortPoints
portPoints(fRdfDescriptor
->Ports
[i
].Points
);
2867 const uint32_t j
= iCtrl
++;
2868 pData
->param
.data
[j
].index
= static_cast<int32_t>(j
);
2869 pData
->param
.data
[j
].rindex
= static_cast<int32_t>(i
);
2871 float min
, max
, def
, step
, stepSmall
, stepLarge
;
2874 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints
.Hints
))
2875 min
= portPoints
.Minimum
;
2880 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints
.Hints
))
2881 max
= portPoints
.Maximum
;
2885 if (LV2_IS_PORT_SAMPLE_RATE(portProps
))
2889 pData
->param
.data
[j
].hints
|= PARAMETER_USES_SAMPLERATE
;
2892 // stupid hack for ir.lv2 (broken plugin)
2893 if (std::strcmp(fRdfDescriptor
->URI
, "http://factorial.hu/plugins/lv2/ir") == 0 && std::strncmp(fRdfDescriptor
->Ports
[i
].Name
, "FileHash", 8) == 0)
2896 max
= (float)0xffffff;
2901 carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", fRdfDescriptor
->Ports
[i
].Name
);
2906 if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints
.Hints
))
2908 def
= portPoints
.Default
;
2913 if (min
< 0.0f
&& max
> 0.0f
)
2924 if (LV2_IS_PORT_TOGGLED(portProps
))
2929 pData
->param
.data
[j
].hints
|= PARAMETER_IS_BOOLEAN
;
2931 else if (LV2_IS_PORT_INTEGER(portProps
))
2936 pData
->param
.data
[j
].hints
|= PARAMETER_IS_INTEGER
;
2940 float range
= max
- min
;
2941 step
= range
/100.0f
;
2942 stepSmall
= range
/1000.0f
;
2943 stepLarge
= range
/10.0f
;
2946 if (LV2_IS_PORT_INPUT(portTypes
))
2948 pData
->param
.data
[j
].type
= PARAMETER_INPUT
;
2950 if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation
))
2952 carla_stderr("Plugin has latency input port, this should not happen!");
2954 else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation
))
2960 pData
->param
.special
[j
] = PARAMETER_SPECIAL_SAMPLE_RATE
;
2962 else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation
))
2964 pData
->param
.special
[j
] = PARAMETER_SPECIAL_FREEWHEEL
;
2966 else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation
))
2968 pData
->param
.special
[j
] = PARAMETER_SPECIAL_TIME
;
2972 pData
->param
.data
[j
].hints
|= PARAMETER_IS_ENABLED
;
2973 pData
->param
.data
[j
].hints
|= PARAMETER_IS_AUTOMATABLE
;
2976 if (! LV2_IS_PORT_CAUSES_ARTIFACTS(portProps
) &&
2977 ! LV2_IS_PORT_ENUMERATION(portProps
) &&
2978 ! LV2_IS_PORT_EXPENSIVE(portProps
) &&
2979 ! LV2_IS_PORT_NOT_AUTOMATIC(portProps
) &&
2980 ! LV2_IS_PORT_NOT_ON_GUI(portProps
) &&
2981 ! LV2_IS_PORT_TRIGGER(portProps
))
2983 pData
->param
.data
[j
].hints
|= PARAMETER_CAN_BE_CV_CONTROLLED
;
2988 const LV2_RDF_PortMidiMap
& portMidiMap(fRdfDescriptor
->Ports
[i
].MidiMap
);
2990 if (LV2_IS_PORT_MIDI_MAP_CC(portMidiMap
.Type
))
2992 if (portMidiMap
.Number
< MAX_MIDI_CONTROL
&& ! MIDI_IS_CONTROL_BANK_SELECT(portMidiMap
.Number
))
2993 pData
->param
.data
[j
].mappedControlIndex
= static_cast<int16_t>(portMidiMap
.Number
);
2996 else if (LV2_IS_PORT_OUTPUT(portTypes
))
2998 pData
->param
.data
[j
].type
= PARAMETER_OUTPUT
;
3000 if (LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation
))
3008 pData
->param
.special
[j
] = PARAMETER_SPECIAL_LATENCY
;
3009 CARLA_SAFE_ASSERT_INT2(fLatencyIndex
== static_cast<int32_t>(j
), fLatencyIndex
, j
);
3011 else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(portDesignation
))
3017 pData
->param
.special
[j
] = PARAMETER_SPECIAL_SAMPLE_RATE
;
3019 else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(portDesignation
))
3021 carla_stderr("Plugin has freewheeling output port, this should not happen!");
3023 else if (LV2_IS_PORT_DESIGNATION_TIME(portDesignation
))
3025 pData
->param
.special
[j
] = PARAMETER_SPECIAL_TIME
;
3029 pData
->param
.data
[j
].hints
|= PARAMETER_IS_ENABLED
;
3030 pData
->param
.data
[j
].hints
|= PARAMETER_IS_AUTOMATABLE
;
3031 needsCtrlOut
= true;
3036 pData
->param
.data
[j
].type
= PARAMETER_UNKNOWN
;
3037 carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)");
3040 // extra parameter hints
3041 if (LV2_IS_PORT_LOGARITHMIC(portProps
))
3042 pData
->param
.data
[j
].hints
|= PARAMETER_IS_LOGARITHMIC
;
3044 if (LV2_IS_PORT_TRIGGER(portProps
))
3045 pData
->param
.data
[j
].hints
|= PARAMETER_IS_TRIGGER
;
3047 if (LV2_IS_PORT_STRICT_BOUNDS(portProps
))
3048 pData
->param
.data
[j
].hints
|= PARAMETER_IS_STRICT_BOUNDS
;
3050 if (LV2_IS_PORT_ENUMERATION(portProps
))
3051 pData
->param
.data
[j
].hints
|= PARAMETER_USES_SCALEPOINTS
;
3053 // check if parameter is not enabled or automatable
3054 if (LV2_IS_PORT_NOT_ON_GUI(portProps
))
3055 pData
->param
.data
[j
].hints
&= ~(PARAMETER_IS_ENABLED
|PARAMETER_IS_AUTOMATABLE
);
3056 else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps
) || LV2_IS_PORT_EXPENSIVE(portProps
))
3057 pData
->param
.data
[j
].hints
&= ~PARAMETER_IS_AUTOMATABLE
;
3058 else if (LV2_IS_PORT_NOT_AUTOMATIC(portProps
) || LV2_IS_PORT_NON_AUTOMATABLE(portProps
))
3059 pData
->param
.data
[j
].hints
&= ~PARAMETER_IS_AUTOMATABLE
;
3061 pData
->param
.ranges
[j
].min
= min
;
3062 pData
->param
.ranges
[j
].max
= max
;
3063 pData
->param
.ranges
[j
].def
= def
;
3064 pData
->param
.ranges
[j
].step
= step
;
3065 pData
->param
.ranges
[j
].stepSmall
= stepSmall
;
3066 pData
->param
.ranges
[j
].stepLarge
= stepLarge
;
3068 // Start parameters in their default values (except freewheel, which is off by default)
3069 if (pData
->param
.data
[j
].type
== PARAMETER_INPUT
&& pData
->param
.special
[j
] == PARAMETER_SPECIAL_FREEWHEEL
)
3070 fParamBuffers
[j
] = min
;
3072 fParamBuffers
[j
] = def
;
3074 fDescriptor
->connect_port(fHandle
, i
, &fParamBuffers
[j
]);
3076 if (fHandle2
!= nullptr)
3077 fDescriptor
->connect_port(fHandle2
, i
, &fParamBuffers
[j
]);
3081 // Port Type not supported, but it's optional anyway
3082 fDescriptor
->connect_port(fHandle
, i
, nullptr);
3084 if (fHandle2
!= nullptr)
3085 fDescriptor
->connect_port(fHandle2
, i
, nullptr);
3089 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
3091 const LV2_RDF_Parameter
& rdfParam(fRdfDescriptor
->Parameters
[i
]);
3093 switch (rdfParam
.Type
)
3095 case LV2_PARAMETER_TYPE_BOOL
:
3096 case LV2_PARAMETER_TYPE_INT
:
3097 // case LV2_PARAMETER_TYPE_LONG:
3098 case LV2_PARAMETER_TYPE_FLOAT
:
3099 case LV2_PARAMETER_TYPE_DOUBLE
:
3105 const LV2_RDF_PortPoints
& portPoints(rdfParam
.Points
);
3107 const uint32_t j
= iCtrl
++;
3108 pData
->param
.data
[j
].index
= static_cast<int32_t>(j
);
3109 pData
->param
.data
[j
].rindex
= static_cast<int32_t>(fRdfDescriptor
->PortCount
+ i
);
3111 float min
, max
, def
, step
, stepSmall
, stepLarge
;
3114 if (LV2_HAVE_MINIMUM_PORT_POINT(portPoints
.Hints
))
3115 min
= portPoints
.Minimum
;
3120 if (LV2_HAVE_MAXIMUM_PORT_POINT(portPoints
.Hints
))
3121 max
= portPoints
.Maximum
;
3127 carla_stderr2("WARNING - Broken plugin parameter '%s': min >= max", rdfParam
.Label
);
3132 if (LV2_HAVE_DEFAULT_PORT_POINT(portPoints
.Hints
))
3134 def
= portPoints
.Default
;
3139 if (min
< 0.0f
&& max
> 0.0f
)
3150 switch (rdfParam
.Type
)
3152 case LV2_PARAMETER_TYPE_BOOL
:
3156 pData
->param
.data
[j
].hints
|= PARAMETER_IS_BOOLEAN
;
3159 case LV2_PARAMETER_TYPE_INT
:
3160 case LV2_PARAMETER_TYPE_LONG
:
3164 pData
->param
.data
[j
].hints
|= PARAMETER_IS_INTEGER
;
3168 const float range
= max
- min
;
3169 step
= range
/100.0f
;
3170 stepSmall
= range
/1000.0f
;
3171 stepLarge
= range
/10.0f
;
3175 if (rdfParam
.Flags
& LV2_PARAMETER_FLAG_INPUT
)
3177 pData
->param
.data
[j
].type
= PARAMETER_INPUT
;
3178 pData
->param
.data
[j
].hints
|= PARAMETER_IS_ENABLED
;
3179 pData
->param
.data
[j
].hints
|= PARAMETER_IS_AUTOMATABLE
;
3180 pData
->param
.data
[j
].hints
|= PARAMETER_IS_NOT_SAVED
;
3183 if (rdfParam
.Flags
& LV2_PARAMETER_FLAG_OUTPUT
)
3184 hasPatchParameterOutputs
= true;
3186 if (LV2_IS_PORT_MIDI_MAP_CC(rdfParam
.MidiMap
.Type
))
3188 if (rdfParam
.MidiMap
.Number
< MAX_MIDI_CONTROL
&& ! MIDI_IS_CONTROL_BANK_SELECT(rdfParam
.MidiMap
.Number
))
3189 pData
->param
.data
[j
].mappedControlIndex
= static_cast<int16_t>(rdfParam
.MidiMap
.Number
);
3192 else if (rdfParam
.Flags
& LV2_PARAMETER_FLAG_OUTPUT
)
3194 pData
->param
.data
[j
].type
= PARAMETER_OUTPUT
;
3195 pData
->param
.data
[j
].hints
|= PARAMETER_IS_ENABLED
;
3196 pData
->param
.data
[j
].hints
|= PARAMETER_IS_AUTOMATABLE
;
3197 needsCtrlOut
= true;
3198 hasPatchParameterOutputs
= true;
3201 pData
->param
.ranges
[j
].min
= min
;
3202 pData
->param
.ranges
[j
].max
= max
;
3203 pData
->param
.ranges
[j
].def
= def
;
3204 pData
->param
.ranges
[j
].step
= step
;
3205 pData
->param
.ranges
[j
].stepSmall
= stepSmall
;
3206 pData
->param
.ranges
[j
].stepLarge
= stepLarge
;
3208 fParamBuffers
[j
] = def
;
3215 if (processMode
== ENGINE_PROCESS_MODE_SINGLE_CLIENT
)
3217 portName
= pData
->name
;
3221 portName
+= "events-in";
3222 portName
.truncate(portNameSize
);
3224 pData
->event
.portIn
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, true, 0);
3225 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3226 pData
->event
.cvSourcePorts
= pData
->client
->createCVSourcePorts();
3234 if (processMode
== ENGINE_PROCESS_MODE_SINGLE_CLIENT
)
3236 portName
= pData
->name
;
3240 portName
+= "events-out";
3241 portName
.truncate(portNameSize
);
3243 pData
->event
.portOut
= (CarlaEngineEventPort
*)pData
->client
->addPort(kEnginePortTypeEvent
, portName
, false, 0);
3246 if (fExt
.worker
!= nullptr && fEventsIn
.ctrl
!= nullptr)
3248 fAtomBufferWorkerIn
.createBuffer(eventBufferSize
, true);
3249 fAtomBufferWorkerResp
.createBuffer(eventBufferSize
, true);
3250 fAtomBufferRealtimeSize
= fAtomBufferWorkerIn
.getSize(); // actual buffer size will be next power of 2
3251 fAtomBufferRealtime
= static_cast<LV2_Atom
*>(std::malloc(fAtomBufferRealtimeSize
));
3252 fAtomBufferWorkerInTmpData
= new uint8_t[fAtomBufferRealtimeSize
];
3253 carla_mlock(fAtomBufferRealtime
, fAtomBufferRealtimeSize
);
3256 if (fRdfDescriptor
->ParameterCount
> 0 ||
3257 (fUI
.type
!= UI::TYPE_NULL
&& fEventsIn
.count
> 0 && (fEventsIn
.data
[0].type
& CARLA_EVENT_DATA_ATOM
) != 0))
3259 fAtomBufferEvIn
.createBuffer(eventBufferSize
, true);
3261 if (fAtomBufferRealtimeSize
== 0)
3263 fAtomBufferRealtimeSize
= fAtomBufferEvIn
.getSize(); // actual buffer size will be next power of 2
3264 fAtomBufferRealtime
= static_cast<LV2_Atom
*>(std::malloc(fAtomBufferRealtimeSize
));
3265 carla_mlock(fAtomBufferRealtime
, fAtomBufferRealtimeSize
);
3269 if (hasPatchParameterOutputs
||
3270 (fUI
.type
!= UI::TYPE_NULL
&& fEventsOut
.count
> 0 && (fEventsOut
.data
[0].type
& CARLA_EVENT_DATA_ATOM
) != 0))
3272 fAtomBufferUiOut
.createBuffer(std::min(eventBufferSize
*32, 1638400U), true);
3273 fAtomBufferUiOutTmpData
= new uint8_t[fAtomBufferUiOut
.getSize()];
3276 if (fEventsIn
.ctrl
!= nullptr && fEventsIn
.ctrl
->port
== nullptr)
3277 fEventsIn
.ctrl
->port
= pData
->event
.portIn
;
3279 if (fEventsOut
.ctrl
!= nullptr && fEventsOut
.ctrl
->port
== nullptr)
3280 fEventsOut
.ctrl
->port
= pData
->event
.portOut
;
3282 if (fEventsIn
.ctrl
!= nullptr && fExt
.midnam
!= nullptr)
3284 if (char* const midnam
= fExt
.midnam
->midnam(fHandle
))
3286 fEventsIn
.ctrl
->port
->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd",
3287 midnam
, "text/xml");
3288 if (fExt
.midnam
->free
!= nullptr)
3289 fExt
.midnam
->free(midnam
);
3293 if (forcedStereoIn
|| forcedStereoOut
)
3294 pData
->options
|= PLUGIN_OPTION_FORCE_STEREO
;
3296 pData
->options
&= ~PLUGIN_OPTION_FORCE_STEREO
;
3299 pData
->hints
= (pData
->hints
& PLUGIN_HAS_INLINE_DISPLAY
) ? PLUGIN_HAS_INLINE_DISPLAY
: 0
3300 | (pData
->hints
& PLUGIN_NEEDS_UI_MAIN_THREAD
) ? PLUGIN_NEEDS_UI_MAIN_THREAD
: 0;
3302 if (isRealtimeSafe())
3303 pData
->hints
|= PLUGIN_IS_RTSAFE
;
3305 if (fUI
.type
!= UI::TYPE_NULL
|| fFilePathURI
.isNotEmpty())
3307 pData
->hints
|= PLUGIN_HAS_CUSTOM_UI
;
3309 if (fUI
.type
== UI::TYPE_EMBED
)
3311 switch (fUI
.rdfDescriptor
->Type
)
3317 case LV2_UI_EXTERNAL
:
3318 case LV2_UI_OLD_EXTERNAL
:
3321 pData
->hints
|= PLUGIN_HAS_CUSTOM_EMBED_UI
;
3326 if (fUI
.type
== UI::TYPE_EMBED
|| fUI
.type
== UI::TYPE_EXTERNAL
)
3327 pData
->hints
|= PLUGIN_NEEDS_UI_MAIN_THREAD
;
3328 else if (fFilePathURI
.isNotEmpty())
3329 pData
->hints
|= PLUGIN_HAS_CUSTOM_UI_USING_FILE_OPEN
;
3332 if (LV2_IS_GENERATOR(fRdfDescriptor
->Type
[0], fRdfDescriptor
->Type
[1]))
3333 pData
->hints
|= PLUGIN_IS_SYNTH
;
3335 if (aOuts
> 0 && (aIns
== aOuts
|| aIns
== 1))
3336 pData
->hints
|= PLUGIN_CAN_DRYWET
;
3339 pData
->hints
|= PLUGIN_CAN_VOLUME
;
3341 if (aOuts
>= 2 && aOuts
% 2 == 0)
3342 pData
->hints
|= PLUGIN_CAN_BALANCE
;
3344 // extra plugin hints
3345 pData
->extraHints
= 0x0;
3347 // check initial latency
3348 findInitialLatencyValue(aIns
, cvIns
, aOuts
, cvOuts
);
3350 bufferSizeChanged(pData
->engine
->getBufferSize());
3351 reloadPrograms(true);
3359 carla_debug("CarlaPluginLV2::reload() - end");
3362 void findInitialLatencyValue(const uint32_t aIns
,
3363 const uint32_t cvIns
,
3364 const uint32_t aOuts
,
3365 const uint32_t cvOuts
) const
3367 if (fLatencyIndex
< 0)
3370 // we need to pre-run the plugin so it can update its latency control-port
3371 const uint32_t bufferSize
= static_cast<uint32_t>(fLv2Options
.nominalBufferSize
);
3378 for (; i
< aIns
; ++i
)
3380 tmpIn
[i
] = new float[bufferSize
];
3381 carla_zeroFloats(tmpIn
[i
], bufferSize
);
3384 fDescriptor
->connect_port(fHandle
, pData
->audioIn
.ports
[i
].rindex
, tmpIn
[i
]);
3385 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio input");
3388 for (uint32_t j
=0; j
< cvIns
; ++i
, ++j
)
3390 tmpIn
[i
] = new float[bufferSize
];
3391 carla_zeroFloats(tmpIn
[i
], bufferSize
);
3394 fDescriptor
->connect_port(fHandle
, pData
->cvIn
.ports
[j
].rindex
, tmpIn
[i
]);
3395 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv input");
3401 for (; i
< aOuts
; ++i
)
3403 tmpOut
[i
] = new float[bufferSize
];
3404 carla_zeroFloats(tmpOut
[i
], bufferSize
);
3407 fDescriptor
->connect_port(fHandle
, pData
->audioOut
.ports
[i
].rindex
, tmpOut
[i
]);
3408 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency audio output");
3411 for (uint32_t j
=0; j
< cvOuts
; ++i
, ++j
)
3413 tmpOut
[i
] = new float[bufferSize
];
3414 carla_zeroFloats(tmpOut
[i
], bufferSize
);
3417 fDescriptor
->connect_port(fHandle
, pData
->cvOut
.ports
[j
].rindex
, tmpOut
[i
]);
3418 } CARLA_SAFE_EXCEPTION("LV2 connect_port latency cv output");
3422 if (fDescriptor
->activate
!= nullptr)
3425 fDescriptor
->activate(fHandle
);
3426 } CARLA_SAFE_EXCEPTION("LV2 latency activate");
3430 fDescriptor
->run(fHandle
, bufferSize
);
3431 } CARLA_SAFE_EXCEPTION("LV2 latency run");
3433 if (fDescriptor
->deactivate
!= nullptr)
3436 fDescriptor
->deactivate(fHandle
);
3437 } CARLA_SAFE_EXCEPTION("LV2 latency deactivate");
3440 // done, let's get the value
3441 if (const uint32_t latency
= getLatencyInFrames())
3443 pData
->client
->setLatency(latency
);
3444 #ifndef BUILD_BRIDGE
3445 pData
->latency
.recreateBuffers(std::max(aIns
, aOuts
), latency
);
3449 for (uint32_t i
=0; i
< aIns
+ cvIns
; ++i
)
3452 for (uint32_t i
=0; i
< aOuts
+ cvOuts
; ++i
)
3456 void reloadPrograms(const bool doInit
) override
3458 carla_debug("CarlaPluginLV2::reloadPrograms(%s)", bool2str(doInit
));
3459 const uint32_t oldCount
= pData
->midiprog
.count
;
3460 const int32_t current
= pData
->midiprog
.current
;
3462 // special LV2 programs handling
3465 pData
->prog
.clear();
3467 const uint32_t presetCount(fRdfDescriptor
->PresetCount
);
3469 if (presetCount
> 0)
3471 pData
->prog
.createNew(presetCount
);
3473 for (uint32_t i
=0; i
< presetCount
; ++i
)
3474 pData
->prog
.names
[i
] = carla_strdup(fRdfDescriptor
->Presets
[i
].Label
);
3478 // Delete old programs
3479 pData
->midiprog
.clear();
3481 // Query new programs
3482 uint32_t newCount
= 0;
3483 if (fExt
.programs
!= nullptr && fExt
.programs
->get_program
!= nullptr && fExt
.programs
->select_program
!= nullptr)
3485 for (; fExt
.programs
->get_program(fHandle
, newCount
);)
3491 pData
->midiprog
.createNew(newCount
);
3494 for (uint32_t i
=0; i
< newCount
; ++i
)
3496 const LV2_Program_Descriptor
* const pdesc(fExt
.programs
->get_program(fHandle
, i
));
3497 CARLA_SAFE_ASSERT_CONTINUE(pdesc
!= nullptr);
3498 CARLA_SAFE_ASSERT(pdesc
->name
!= nullptr);
3500 pData
->midiprog
.data
[i
].bank
= pdesc
->bank
;
3501 pData
->midiprog
.data
[i
].program
= pdesc
->program
;
3502 pData
->midiprog
.data
[i
].name
= carla_strdup(pdesc
->name
);
3510 setMidiProgram(0, false, false, false, true);
3512 else if (fHasLoadDefaultState
)
3514 // load default state
3515 if (LilvState
* const state
= Lv2WorldClass::getInstance().getStateFromURI(fDescriptor
->URI
,
3516 (const LV2_URID_Map
*)fFeatures
[kFeatureIdUridMap
]->data
))
3518 lilv_state_restore(state
, fExt
.state
, fHandle
, carla_lilv_set_port_value
, this, 0, fFeatures
);
3520 if (fHandle2
!= nullptr)
3521 lilv_state_restore(state
, fExt
.state
, fHandle2
, carla_lilv_set_port_value
, this, 0, fFeatures
);
3523 lilv_state_free(state
);
3529 // Check if current program is invalid
3530 bool programChanged
= false;
3532 if (newCount
== oldCount
+1)
3534 // one midi program added, probably created by user
3535 pData
->midiprog
.current
= static_cast<int32_t>(oldCount
);
3536 programChanged
= true;
3538 else if (current
< 0 && newCount
> 0)
3540 // programs exist now, but not before
3541 pData
->midiprog
.current
= 0;
3542 programChanged
= true;
3544 else if (current
>= 0 && newCount
== 0)
3546 // programs existed before, but not anymore
3547 pData
->midiprog
.current
= -1;
3548 programChanged
= true;
3550 else if (current
>= static_cast<int32_t>(newCount
))
3552 // current midi program > count
3553 pData
->midiprog
.current
= 0;
3554 programChanged
= true;
3559 pData
->midiprog
.current
= current
;
3563 setMidiProgram(pData
->midiprog
.current
, true, true, true, false);
3565 pData
->engine
->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS
, pData
->id
, 0, 0, 0, 0.0f
, nullptr);
3569 // -------------------------------------------------------------------
3570 // Plugin processing
3572 void activate() noexcept override
3574 CARLA_SAFE_ASSERT_RETURN(fDescriptor
!= nullptr,);
3575 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
3577 if (fDescriptor
->activate
!= nullptr)
3580 fDescriptor
->activate(fHandle
);
3581 } CARLA_SAFE_EXCEPTION("LV2 activate");
3583 if (fHandle2
!= nullptr)
3586 fDescriptor
->activate(fHandle2
);
3587 } CARLA_SAFE_EXCEPTION("LV2 activate #2");
3591 fFirstActive
= true;
3594 void deactivate() noexcept override
3596 CARLA_SAFE_ASSERT_RETURN(fDescriptor
!= nullptr,);
3597 CARLA_SAFE_ASSERT_RETURN(fHandle
!= nullptr,);
3599 if (fDescriptor
->deactivate
!= nullptr)
3602 fDescriptor
->deactivate(fHandle
);
3603 } CARLA_SAFE_EXCEPTION("LV2 deactivate");
3605 if (fHandle2
!= nullptr)
3608 fDescriptor
->deactivate(fHandle2
);
3609 } CARLA_SAFE_EXCEPTION("LV2 deactivate #2");
3614 void process(const float* const* const audioIn
, float** const audioOut
,
3615 const float* const* const cvIn
, float** const cvOut
, const uint32_t frames
) override
3617 // --------------------------------------------------------------------------------------------------------
3620 if (! pData
->active
)
3622 // disable any output sound
3623 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
3624 carla_zeroFloats(audioOut
[i
], frames
);
3625 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
3626 carla_zeroFloats(cvOut
[i
], frames
);
3630 // --------------------------------------------------------------------------------------------------------
3631 // Event itenerators from different APIs (input)
3633 for (uint32_t i
=0; i
< fEventsIn
.count
; ++i
)
3635 if (fEventsIn
.data
[i
].type
& CARLA_EVENT_DATA_ATOM
)
3637 lv2_atom_buffer_reset(fEventsIn
.data
[i
].atom
, true);
3638 lv2_atom_buffer_begin(&fEventsIn
.iters
[i
].atom
, fEventsIn
.data
[i
].atom
);
3640 else if (fEventsIn
.data
[i
].type
& CARLA_EVENT_DATA_EVENT
)
3642 lv2_event_buffer_reset(fEventsIn
.data
[i
].event
, LV2_EVENT_AUDIO_STAMP
, fEventsIn
.data
[i
].event
->data
);
3643 lv2_event_begin(&fEventsIn
.iters
[i
].event
, fEventsIn
.data
[i
].event
);
3645 else if (fEventsIn
.data
[i
].type
& CARLA_EVENT_DATA_MIDI_LL
)
3647 fEventsIn
.data
[i
].midi
.event_count
= 0;
3648 fEventsIn
.data
[i
].midi
.size
= 0;
3649 LV2_MIDIState
& midiState(fEventsIn
.iters
[i
].midiState
);
3650 midiState
.midi
= &fEventsIn
.data
[i
].midi
;
3651 midiState
.frame_count
= frames
;
3652 midiState
.position
= 0;
3656 for (uint32_t i
=0; i
< fEventsOut
.count
; ++i
)
3658 if (fEventsOut
.data
[i
].type
& CARLA_EVENT_DATA_ATOM
)
3660 lv2_atom_buffer_reset(fEventsOut
.data
[i
].atom
, false);
3662 else if (fEventsOut
.data
[i
].type
& CARLA_EVENT_DATA_EVENT
)
3664 lv2_event_buffer_reset(fEventsOut
.data
[i
].event
, LV2_EVENT_AUDIO_STAMP
, fEventsOut
.data
[i
].event
->data
);
3666 else if (fEventsOut
.data
[i
].type
& CARLA_EVENT_DATA_MIDI_LL
)
3672 // --------------------------------------------------------------------------------------------------------
3673 // Check if needs reset
3675 if (pData
->needsReset
)
3677 if (fEventsIn
.ctrl
!= nullptr && (fEventsIn
.ctrl
->type
& CARLA_EVENT_TYPE_MIDI
) != 0)
3679 const uint32_t j
= fEventsIn
.ctrlIndex
;
3680 CARLA_ASSERT(j
< fEventsIn
.count
);
3682 uint8_t midiData
[3] = { 0, 0, 0 };
3684 if (pData
->options
& PLUGIN_OPTION_SEND_ALL_SOUND_OFF
)
3686 for (uint8_t i
=0; i
< MAX_MIDI_CHANNELS
; ++i
)
3688 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (i
& MIDI_CHANNEL_BIT
));
3689 midiData
[1] = MIDI_CONTROL_ALL_NOTES_OFF
;
3691 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
3692 lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, 0, 0, kUridMidiEvent
, 3, midiData
);
3694 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
3695 lv2_event_write(&fEventsIn
.iters
[j
].event
, 0, 0, kUridMidiEvent
, 3, midiData
);
3697 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
3698 lv2midi_put_event(&fEventsIn
.iters
[j
].midiState
, 0.0, 3, midiData
);
3700 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (i
& MIDI_CHANNEL_BIT
));
3701 midiData
[1] = MIDI_CONTROL_ALL_SOUND_OFF
;
3703 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
3704 lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, 0, 0, kUridMidiEvent
, 3, midiData
);
3706 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
3707 lv2_event_write(&fEventsIn
.iters
[j
].event
, 0, 0, kUridMidiEvent
, 3, midiData
);
3709 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
3710 lv2midi_put_event(&fEventsIn
.iters
[j
].midiState
, 0.0, 3, midiData
);
3713 else if (pData
->ctrlChannel
>= 0 && pData
->ctrlChannel
< MAX_MIDI_CHANNELS
)
3715 for (uint8_t k
=0; k
< MAX_MIDI_NOTE
; ++k
)
3717 midiData
[0] = uint8_t(MIDI_STATUS_NOTE_OFF
| (pData
->ctrlChannel
& MIDI_CHANNEL_BIT
));
3720 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
3721 lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, 0, 0, kUridMidiEvent
, 3, midiData
);
3723 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
3724 lv2_event_write(&fEventsIn
.iters
[j
].event
, 0, 0, kUridMidiEvent
, 3, midiData
);
3726 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
3727 lv2midi_put_event(&fEventsIn
.iters
[j
].midiState
, 0.0, 3, midiData
);
3732 pData
->needsReset
= false;
3735 // --------------------------------------------------------------------------------------------------------
3738 const EngineTimeInfo
timeInfo(pData
->engine
->getTimeInfo());
3740 if (fFirstActive
|| fLastTimeInfo
!= timeInfo
)
3745 const double barBeat
= static_cast<double>(timeInfo
.bbt
.beat
- 1)
3746 + (timeInfo
.bbt
.tick
/ timeInfo
.bbt
.ticksPerBeat
);
3748 // update input ports
3749 for (uint32_t k
=0; k
< pData
->param
.count
; ++k
)
3751 if (pData
->param
.data
[k
].type
!= PARAMETER_INPUT
)
3753 if (pData
->param
.special
[k
] != PARAMETER_SPECIAL_TIME
)
3757 rindex
= pData
->param
.data
[k
].rindex
;
3759 CARLA_SAFE_ASSERT_CONTINUE(rindex
>= 0 && rindex
< static_cast<int32_t>(fRdfDescriptor
->PortCount
));
3761 switch (fRdfDescriptor
->Ports
[rindex
].Designation
)
3764 case LV2_PORT_DESIGNATION_TIME_SPEED
:
3765 if (fLastTimeInfo
.playing
!= timeInfo
.playing
)
3767 fParamBuffers
[k
] = timeInfo
.playing
? 1.0f
: 0.0f
;
3772 case LV2_PORT_DESIGNATION_TIME_FRAME
:
3773 if (fLastTimeInfo
.frame
!= timeInfo
.frame
)
3775 fParamBuffers
[k
] = static_cast<float>(timeInfo
.frame
);
3780 case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND
:
3784 case LV2_PORT_DESIGNATION_TIME_BAR
:
3785 if (timeInfo
.bbt
.valid
&& fLastTimeInfo
.bbt
.bar
!= timeInfo
.bbt
.bar
)
3787 fParamBuffers
[k
] = static_cast<float>(timeInfo
.bbt
.bar
- 1);
3792 case LV2_PORT_DESIGNATION_TIME_BAR_BEAT
:
3793 if (timeInfo
.bbt
.valid
&& (carla_isNotEqual(fLastTimeInfo
.bbt
.tick
, timeInfo
.bbt
.tick
) ||
3794 fLastTimeInfo
.bbt
.beat
!= timeInfo
.bbt
.beat
))
3796 fParamBuffers
[k
] = static_cast<float>(barBeat
);
3801 case LV2_PORT_DESIGNATION_TIME_BEAT
:
3802 if (timeInfo
.bbt
.valid
&& fLastTimeInfo
.bbt
.beat
!= timeInfo
.bbt
.beat
)
3804 fParamBuffers
[k
] = static_cast<float>(timeInfo
.bbt
.beat
- 1);
3809 case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT
:
3810 if (timeInfo
.bbt
.valid
&& carla_isNotEqual(fLastTimeInfo
.bbt
.beatType
, timeInfo
.bbt
.beatType
))
3812 fParamBuffers
[k
] = timeInfo
.bbt
.beatType
;
3816 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR
:
3817 if (timeInfo
.bbt
.valid
&& carla_isNotEqual(fLastTimeInfo
.bbt
.beatsPerBar
, timeInfo
.bbt
.beatsPerBar
))
3819 fParamBuffers
[k
] = timeInfo
.bbt
.beatsPerBar
;
3824 case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE
:
3825 if (timeInfo
.bbt
.valid
&& carla_isNotEqual(fLastTimeInfo
.bbt
.beatsPerMinute
, timeInfo
.bbt
.beatsPerMinute
))
3827 fParamBuffers
[k
] = static_cast<float>(timeInfo
.bbt
.beatsPerMinute
);
3832 case LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT
:
3833 if (timeInfo
.bbt
.valid
&& carla_isNotEqual(fLastTimeInfo
.bbt
.ticksPerBeat
, timeInfo
.bbt
.ticksPerBeat
))
3835 fParamBuffers
[k
] = static_cast<float>(timeInfo
.bbt
.ticksPerBeat
);
3842 pData
->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k
), fParamBuffers
[k
]);
3845 for (uint32_t i
=0; i
< fEventsIn
.count
; ++i
)
3847 if ((fEventsIn
.data
[i
].type
& CARLA_EVENT_DATA_ATOM
) == 0 || (fEventsIn
.data
[i
].type
& CARLA_EVENT_TYPE_TIME
) == 0)
3850 uint8_t timeInfoBuf
[256];
3851 LV2_Atom_Forge atomForge
;
3852 initAtomForge(atomForge
);
3853 lv2_atom_forge_set_buffer(&atomForge
, timeInfoBuf
, sizeof(timeInfoBuf
));
3855 LV2_Atom_Forge_Frame forgeFrame
;
3856 lv2_atom_forge_object(&atomForge
, &forgeFrame
, kUridNull
, kUridTimePosition
);
3858 lv2_atom_forge_key(&atomForge
, kUridTimeSpeed
);
3859 lv2_atom_forge_float(&atomForge
, timeInfo
.playing
? 1.0f
: 0.0f
);
3861 lv2_atom_forge_key(&atomForge
, kUridTimeFrame
);
3862 lv2_atom_forge_long(&atomForge
, static_cast<int64_t>(timeInfo
.frame
));
3864 if (timeInfo
.bbt
.valid
)
3866 lv2_atom_forge_key(&atomForge
, kUridTimeBar
);
3867 lv2_atom_forge_long(&atomForge
, timeInfo
.bbt
.bar
- 1);
3869 lv2_atom_forge_key(&atomForge
, kUridTimeBarBeat
);
3870 lv2_atom_forge_float(&atomForge
, static_cast<float>(barBeat
));
3872 lv2_atom_forge_key(&atomForge
, kUridTimeBeat
);
3873 lv2_atom_forge_double(&atomForge
, timeInfo
.bbt
.beat
- 1);
3875 lv2_atom_forge_key(&atomForge
, kUridTimeBeatUnit
);
3876 lv2_atom_forge_int(&atomForge
, static_cast<int32_t>(timeInfo
.bbt
.beatType
));
3878 lv2_atom_forge_key(&atomForge
, kUridTimeBeatsPerBar
);
3879 lv2_atom_forge_float(&atomForge
, timeInfo
.bbt
.beatsPerBar
);
3881 lv2_atom_forge_key(&atomForge
, kUridTimeBeatsPerMinute
);
3882 lv2_atom_forge_float(&atomForge
, static_cast<float>(timeInfo
.bbt
.beatsPerMinute
));
3884 lv2_atom_forge_key(&atomForge
, kUridTimeTicksPerBeat
);
3885 lv2_atom_forge_double(&atomForge
, timeInfo
.bbt
.ticksPerBeat
);
3888 lv2_atom_forge_pop(&atomForge
, &forgeFrame
);
3890 LV2_Atom
* const atom((LV2_Atom
*)timeInfoBuf
);
3891 CARLA_SAFE_ASSERT_BREAK(atom
->size
< 256);
3893 // send only deprecated blank object for now
3894 lv2_atom_buffer_write(&fEventsIn
.iters
[i
].atom
, 0, 0, kUridAtomBlank
, atom
->size
, LV2_ATOM_BODY_CONST(atom
));
3897 //lv2_atom_buffer_write(&fEventsIn.iters[i].atom, 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom));
3900 pData
->postRtEvents
.trySplice();
3902 fLastTimeInfo
= timeInfo
;
3905 // --------------------------------------------------------------------------------------------------------
3906 // Event Input and Processing
3908 if (fEventsIn
.ctrl
!= nullptr)
3910 // ----------------------------------------------------------------------------------------------------
3913 if (fAtomBufferEvIn
.tryLock())
3915 if (fAtomBufferEvIn
.isDataAvailableForReading())
3917 uint32_t j
, portIndex
;
3918 LV2_Atom
* const atom
= fAtomBufferRealtime
;
3919 atom
->size
= fAtomBufferRealtimeSize
;
3921 for (; fAtomBufferEvIn
.get(portIndex
, atom
); atom
->size
= fAtomBufferRealtimeSize
)
3923 j
= (portIndex
< fEventsIn
.count
) ? portIndex
: fEventsIn
.ctrlIndex
;
3925 if (! lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, 0, 0, atom
->type
, atom
->size
, LV2_ATOM_BODY_CONST(atom
)))
3927 carla_stderr2("Event input buffer full, at least 1 message lost");
3931 inspectAtomForParameterChange(atom
);
3935 fAtomBufferEvIn
.unlock();
3938 // ----------------------------------------------------------------------------------------------------
3939 // MIDI Input (External)
3941 if (pData
->extNotes
.mutex
.tryLock())
3943 if ((fEventsIn
.ctrl
->type
& CARLA_EVENT_TYPE_MIDI
) == 0)
3945 // does not handle MIDI
3946 pData
->extNotes
.data
.clear();
3950 const uint32_t j
= fEventsIn
.ctrlIndex
;
3952 for (RtLinkedList
<ExternalMidiNote
>::Itenerator it
= pData
->extNotes
.data
.begin2(); it
.valid(); it
.next())
3954 const ExternalMidiNote
& note(it
.getValue(kExternalMidiNoteFallback
));
3955 CARLA_SAFE_ASSERT_CONTINUE(note
.channel
>= 0 && note
.channel
< MAX_MIDI_CHANNELS
);
3957 uint8_t midiEvent
[3];
3958 midiEvent
[0] = uint8_t((note
.velo
> 0 ? MIDI_STATUS_NOTE_ON
: MIDI_STATUS_NOTE_OFF
) | (note
.channel
& MIDI_CHANNEL_BIT
));
3959 midiEvent
[1] = note
.note
;
3960 midiEvent
[2] = note
.velo
;
3962 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
3963 lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, 0, 0, kUridMidiEvent
, 3, midiEvent
);
3965 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
3966 lv2_event_write(&fEventsIn
.iters
[j
].event
, 0, 0, kUridMidiEvent
, 3, midiEvent
);
3968 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
3969 lv2midi_put_event(&fEventsIn
.iters
[j
].midiState
, 0.0, 3, midiEvent
);
3972 pData
->extNotes
.data
.clear();
3975 pData
->extNotes
.mutex
.unlock();
3977 } // End of MIDI Input (External)
3979 // ----------------------------------------------------------------------------------------------------
3980 // Event Input (System)
3982 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3983 bool allNotesOffSent
= false;
3985 bool isSampleAccurate
= (pData
->options
& PLUGIN_OPTION_FIXED_BUFFERS
) == 0;
3987 uint32_t startTime
= 0;
3988 uint32_t timeOffset
= 0;
3989 uint32_t nextBankId
;
3991 if (pData
->midiprog
.current
>= 0 && pData
->midiprog
.count
> 0)
3992 nextBankId
= pData
->midiprog
.data
[pData
->midiprog
.current
].bank
;
3996 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
3997 if (cvIn
!= nullptr && pData
->event
.cvSourcePorts
!= nullptr)
3998 pData
->event
.cvSourcePorts
->initPortBuffers(cvIn
+ pData
->cvIn
.count
, frames
, isSampleAccurate
, pData
->event
.portIn
);
4001 const uint32_t numEvents
= (fEventsIn
.ctrl
->port
!= nullptr) ? fEventsIn
.ctrl
->port
->getEventCount() : 0;
4003 for (uint32_t i
=0; i
< numEvents
; ++i
)
4005 EngineEvent
& event(fEventsIn
.ctrl
->port
->getEvent(i
));
4007 uint32_t eventTime
= event
.time
;
4008 CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime
< frames
, eventTime
, frames
);
4010 if (eventTime
< timeOffset
)
4012 carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
4013 eventTime
, timeOffset
, pData
->name
);
4014 eventTime
= timeOffset
;
4017 if (isSampleAccurate
&& eventTime
> timeOffset
)
4019 if (processSingle(audioIn
, audioOut
, cvIn
, cvOut
, eventTime
- timeOffset
, timeOffset
))
4022 timeOffset
= eventTime
;
4024 if (pData
->midiprog
.current
>= 0 && pData
->midiprog
.count
> 0)
4025 nextBankId
= pData
->midiprog
.data
[pData
->midiprog
.current
].bank
;
4029 for (uint32_t j
=0; j
< fEventsIn
.count
; ++j
)
4031 if (fEventsIn
.data
[j
].type
& CARLA_EVENT_DATA_ATOM
)
4033 lv2_atom_buffer_reset(fEventsIn
.data
[j
].atom
, true);
4034 lv2_atom_buffer_begin(&fEventsIn
.iters
[j
].atom
, fEventsIn
.data
[j
].atom
);
4036 else if (fEventsIn
.data
[j
].type
& CARLA_EVENT_DATA_EVENT
)
4038 lv2_event_buffer_reset(fEventsIn
.data
[j
].event
, LV2_EVENT_AUDIO_STAMP
, fEventsIn
.data
[j
].event
->data
);
4039 lv2_event_begin(&fEventsIn
.iters
[j
].event
, fEventsIn
.data
[j
].event
);
4041 else if (fEventsIn
.data
[j
].type
& CARLA_EVENT_DATA_MIDI_LL
)
4043 fEventsIn
.data
[j
].midi
.event_count
= 0;
4044 fEventsIn
.data
[j
].midi
.size
= 0;
4045 fEventsIn
.iters
[j
].midiState
.position
= eventTime
;
4049 for (uint32_t j
=0; j
< fEventsOut
.count
; ++j
)
4051 if (fEventsOut
.data
[j
].type
& CARLA_EVENT_DATA_ATOM
)
4053 lv2_atom_buffer_reset(fEventsOut
.data
[j
].atom
, false);
4055 else if (fEventsOut
.data
[j
].type
& CARLA_EVENT_DATA_EVENT
)
4057 lv2_event_buffer_reset(fEventsOut
.data
[j
].event
, LV2_EVENT_AUDIO_STAMP
, fEventsOut
.data
[j
].event
->data
);
4059 else if (fEventsOut
.data
[j
].type
& CARLA_EVENT_DATA_MIDI_LL
)
4067 startTime
+= timeOffset
;
4073 case kEngineEventTypeNull
:
4076 case kEngineEventTypeControl
: {
4077 EngineControlEvent
& ctrlEvent(event
.ctrl
);
4079 switch (ctrlEvent
.type
)
4081 case kEngineControlEventTypeNull
:
4084 case kEngineControlEventTypeParameter
: {
4087 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4089 if (event
.channel
== kEngineEventNonMidiChannel
)
4091 const uint32_t k
= ctrlEvent
.param
;
4092 CARLA_SAFE_ASSERT_CONTINUE(k
< pData
->param
.count
);
4094 ctrlEvent
.handled
= true;
4095 value
= pData
->param
.getFinalUnnormalizedValue(k
, ctrlEvent
.normalizedValue
);
4096 setParameterValueRT(k
, value
, event
.time
, true);
4100 // Control backend stuff
4101 if (event
.channel
== pData
->ctrlChannel
)
4103 if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent
.param
) && (pData
->hints
& PLUGIN_CAN_DRYWET
) != 0)
4105 ctrlEvent
.handled
= true;
4106 value
= ctrlEvent
.normalizedValue
;
4107 setDryWetRT(value
, true);
4109 else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent
.param
) && (pData
->hints
& PLUGIN_CAN_VOLUME
) != 0)
4111 ctrlEvent
.handled
= true;
4112 value
= ctrlEvent
.normalizedValue
*127.0f
/100.0f
;
4113 setVolumeRT(value
, true);
4115 else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent
.param
) && (pData
->hints
& PLUGIN_CAN_BALANCE
) != 0)
4118 value
= ctrlEvent
.normalizedValue
/0.5f
- 1.0f
;
4123 right
= (value
*2.0f
)+1.0f
;
4125 else if (value
> 0.0f
)
4127 left
= (value
*2.0f
)-1.0f
;
4136 ctrlEvent
.handled
= true;
4137 setBalanceLeftRT(left
, true);
4138 setBalanceRightRT(right
, true);
4142 // Control plugin parameters
4144 for (k
=0; k
< pData
->param
.count
; ++k
)
4146 if (pData
->param
.data
[k
].midiChannel
!= event
.channel
)
4148 if (pData
->param
.data
[k
].mappedControlIndex
!= ctrlEvent
.param
)
4150 if (pData
->param
.data
[k
].type
!= PARAMETER_INPUT
)
4152 if ((pData
->param
.data
[k
].hints
& PARAMETER_IS_AUTOMATABLE
) == 0)
4155 ctrlEvent
.handled
= true;
4157 if (pData
->param
.data
[k
].mappedFlags
& PARAMETER_MAPPING_MIDI_DELTA
)
4158 value
= pData
->param
.getFinalValueWithMidiDelta(k
, fParamBuffers
[k
], ctrlEvent
.midiValue
);
4160 value
= pData
->param
.getFinalUnnormalizedValue(k
, ctrlEvent
.normalizedValue
);
4162 setParameterValueRT(k
, value
, event
.time
, true);
4165 if ((pData
->options
& PLUGIN_OPTION_SEND_CONTROL_CHANGES
) != 0 && ctrlEvent
.param
< MAX_MIDI_VALUE
)
4167 uint8_t midiData
[3];
4168 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (event
.channel
& MIDI_CHANNEL_BIT
));
4169 midiData
[1] = uint8_t(ctrlEvent
.param
);
4170 midiData
[2] = uint8_t(ctrlEvent
.normalizedValue
*127.0f
+ 0.5f
);
4172 const uint32_t mtime(isSampleAccurate
? startTime
: eventTime
);
4174 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4175 lv2_atom_buffer_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].atom
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4177 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4178 lv2_event_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].event
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4180 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4181 lv2midi_put_event(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].midiState
, mtime
, 3, midiData
);
4184 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4185 if (! ctrlEvent
.handled
)
4186 checkForMidiLearn(event
);
4189 } // case kEngineControlEventTypeParameter
4191 case kEngineControlEventTypeMidiBank
:
4192 if (pData
->options
& PLUGIN_OPTION_MAP_PROGRAM_CHANGES
)
4194 if (event
.channel
== pData
->ctrlChannel
)
4195 nextBankId
= ctrlEvent
.param
;
4197 else if (pData
->options
& PLUGIN_OPTION_SEND_PROGRAM_CHANGES
)
4199 uint8_t midiData
[3];
4200 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (event
.channel
& MIDI_CHANNEL_BIT
));
4201 midiData
[1] = MIDI_CONTROL_BANK_SELECT
;
4202 midiData
[2] = uint8_t(ctrlEvent
.param
);
4204 const uint32_t mtime(isSampleAccurate
? startTime
: eventTime
);
4206 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4207 lv2_atom_buffer_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].atom
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4209 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4210 lv2_event_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].event
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4212 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4213 lv2midi_put_event(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].midiState
, mtime
, 3, midiData
);
4217 case kEngineControlEventTypeMidiProgram
:
4218 if (pData
->options
& PLUGIN_OPTION_MAP_PROGRAM_CHANGES
)
4220 if (event
.channel
== pData
->ctrlChannel
)
4222 const uint32_t nextProgramId(ctrlEvent
.param
);
4224 for (uint32_t k
=0; k
< pData
->midiprog
.count
; ++k
)
4226 if (pData
->midiprog
.data
[k
].bank
== nextBankId
&& pData
->midiprog
.data
[k
].program
== nextProgramId
)
4228 setMidiProgramRT(k
, true);
4234 else if (pData
->options
& PLUGIN_OPTION_SEND_PROGRAM_CHANGES
)
4236 uint8_t midiData
[2];
4237 midiData
[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE
| (event
.channel
& MIDI_CHANNEL_BIT
));
4238 midiData
[1] = uint8_t(ctrlEvent
.param
);
4240 const uint32_t mtime(isSampleAccurate
? startTime
: eventTime
);
4242 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4243 lv2_atom_buffer_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].atom
, mtime
, 0, kUridMidiEvent
, 2, midiData
);
4245 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4246 lv2_event_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].event
, mtime
, 0, kUridMidiEvent
, 2, midiData
);
4248 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4249 lv2midi_put_event(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].midiState
, mtime
, 2, midiData
);
4253 case kEngineControlEventTypeAllSoundOff
:
4254 if (pData
->options
& PLUGIN_OPTION_SEND_ALL_SOUND_OFF
)
4256 const uint32_t mtime(isSampleAccurate
? startTime
: eventTime
);
4258 uint8_t midiData
[3];
4259 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (event
.channel
& MIDI_CHANNEL_BIT
));
4260 midiData
[1] = MIDI_CONTROL_ALL_SOUND_OFF
;
4263 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4264 lv2_atom_buffer_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].atom
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4266 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4267 lv2_event_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].event
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4269 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4270 lv2midi_put_event(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].midiState
, mtime
, 3, midiData
);
4274 case kEngineControlEventTypeAllNotesOff
:
4275 if (pData
->options
& PLUGIN_OPTION_SEND_ALL_SOUND_OFF
)
4277 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4278 if (event
.channel
== pData
->ctrlChannel
&& ! allNotesOffSent
)
4280 allNotesOffSent
= true;
4281 postponeRtAllNotesOff();
4285 const uint32_t mtime(isSampleAccurate
? startTime
: eventTime
);
4287 uint8_t midiData
[3];
4288 midiData
[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE
| (event
.channel
& MIDI_CHANNEL_BIT
));
4289 midiData
[1] = MIDI_CONTROL_ALL_NOTES_OFF
;
4292 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4293 lv2_atom_buffer_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].atom
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4295 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4296 lv2_event_write(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].event
, mtime
, 0, kUridMidiEvent
, 3, midiData
);
4298 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4299 lv2midi_put_event(&fEventsIn
.iters
[fEventsIn
.ctrlIndex
].midiState
, mtime
, 3, midiData
);
4302 } // switch (ctrlEvent.type)
4304 } // case kEngineEventTypeControl
4306 case kEngineEventTypeMidi
: {
4307 const EngineMidiEvent
& midiEvent(event
.midi
);
4309 const uint8_t* const midiData
= midiEvent
.size
> EngineMidiEvent::kDataSize
? midiEvent
.dataExt
: midiEvent
.data
;
4311 uint8_t status
= uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData
));
4313 if ((status
== MIDI_STATUS_NOTE_OFF
|| status
== MIDI_STATUS_NOTE_ON
) && (pData
->options
& PLUGIN_OPTION_SKIP_SENDING_NOTES
))
4315 if (status
== MIDI_STATUS_CHANNEL_PRESSURE
&& (pData
->options
& PLUGIN_OPTION_SEND_CHANNEL_PRESSURE
) == 0)
4317 if (status
== MIDI_STATUS_CONTROL_CHANGE
&& (pData
->options
& PLUGIN_OPTION_SEND_CONTROL_CHANGES
) == 0)
4319 if (status
== MIDI_STATUS_POLYPHONIC_AFTERTOUCH
&& (pData
->options
& PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH
) == 0)
4321 if (status
== MIDI_STATUS_PITCH_WHEEL_CONTROL
&& (pData
->options
& PLUGIN_OPTION_SEND_PITCHBEND
) == 0)
4324 // Fix bad note-off (per LV2 spec)
4325 if (status
== MIDI_STATUS_NOTE_ON
&& midiData
[2] == 0)
4326 status
= MIDI_STATUS_NOTE_OFF
;
4328 const uint32_t j
= fEventsIn
.ctrlIndex
;
4329 const uint32_t mtime
= isSampleAccurate
? startTime
: eventTime
;
4331 // put back channel in data
4332 uint8_t midiData2
[4]; // FIXME
4333 if (midiEvent
.size
> 4)
4336 midiData2
[0] = uint8_t(status
| (event
.channel
& MIDI_CHANNEL_BIT
));
4337 std::memcpy(midiData2
+1, midiData
+1, static_cast<std::size_t>(midiEvent
.size
-1));
4340 if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_ATOM
)
4341 lv2_atom_buffer_write(&fEventsIn
.iters
[j
].atom
, mtime
, 0, kUridMidiEvent
, midiEvent
.size
, midiData2
);
4343 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_EVENT
)
4344 lv2_event_write(&fEventsIn
.iters
[j
].event
, mtime
, 0, kUridMidiEvent
, midiEvent
.size
, midiData2
);
4346 else if (fEventsIn
.ctrl
->type
& CARLA_EVENT_DATA_MIDI_LL
)
4347 lv2midi_put_event(&fEventsIn
.iters
[j
].midiState
, mtime
, midiEvent
.size
, midiData2
);
4349 if (status
== MIDI_STATUS_NOTE_ON
)
4351 pData
->postponeNoteOnRtEvent(true, event
.channel
, midiData
[1], midiData
[2]);
4353 else if (status
== MIDI_STATUS_NOTE_OFF
)
4355 pData
->postponeNoteOffRtEvent(true, event
.channel
, midiData
[1]);
4358 } // switch (event.type)
4361 pData
->postRtEvents
.trySplice();
4363 if (frames
> timeOffset
)
4364 processSingle(audioIn
, audioOut
, cvIn
, cvOut
, frames
- timeOffset
, timeOffset
);
4366 } // End of Event Input and Processing
4368 // --------------------------------------------------------------------------------------------------------
4369 // Plugin processing (no events)
4373 processSingle(audioIn
, audioOut
, cvIn
, cvOut
, frames
, 0);
4375 } // End of Plugin processing (no events)
4377 // --------------------------------------------------------------------------------------------------------
4380 if (fEventsIn
.ctrl
!= nullptr && fExt
.worker
!= nullptr && fAtomBufferWorkerResp
.tryLock())
4382 if (fAtomBufferWorkerResp
.isDataAvailableForReading())
4385 LV2_Atom
* const atom
= fAtomBufferRealtime
;
4386 atom
->size
= fAtomBufferRealtimeSize
;
4388 for (; fAtomBufferWorkerResp
.get(portIndex
, atom
); atom
->size
= fAtomBufferRealtimeSize
)
4390 CARLA_SAFE_ASSERT_CONTINUE(atom
->type
== kUridCarlaAtomWorkerResp
);
4391 fExt
.worker
->work_response(fHandle
, atom
->size
, LV2_ATOM_BODY_CONST(atom
));
4395 fAtomBufferWorkerResp
.unlock();
4398 if (fExt
.worker
!= nullptr && fExt
.worker
->end_run
!= nullptr)
4400 fExt
.worker
->end_run(fHandle
);
4402 if (fHandle2
!= nullptr)
4403 fExt
.worker
->end_run(fHandle2
);
4406 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4407 // --------------------------------------------------------------------------------------------------------
4410 if (pData
->event
.portOut
!= nullptr)
4416 for (uint32_t k
=0; k
< pData
->param
.count
; ++k
)
4418 if (pData
->param
.data
[k
].type
!= PARAMETER_OUTPUT
)
4421 if (fStrictBounds
>= 0 && (pData
->param
.data
[k
].hints
& PARAMETER_IS_STRICT_BOUNDS
) != 0)
4422 // plugin is responsible to ensure correct bounds
4423 pData
->param
.ranges
[k
].fixValue(fParamBuffers
[k
]);
4425 if (pData
->param
.data
[k
].mappedControlIndex
> 0)
4427 channel
= pData
->param
.data
[k
].midiChannel
;
4428 param
= static_cast<uint16_t>(pData
->param
.data
[k
].mappedControlIndex
);
4429 value
= pData
->param
.ranges
[k
].getNormalizedValue(fParamBuffers
[k
]);
4430 pData
->event
.portOut
->writeControlEvent(0, channel
, kEngineControlEventTypeParameter
,
4434 } // End of Control Output
4437 // --------------------------------------------------------------------------------------------------------
4438 // Events/MIDI Output
4440 for (uint32_t i
=0; i
< fEventsOut
.count
; ++i
)
4442 uint32_t lastFrame
= 0;
4443 Lv2EventData
& evData(fEventsOut
.data
[i
]);
4445 if (evData
.type
& CARLA_EVENT_DATA_ATOM
)
4447 const LV2_Atom_Event
* ev
;
4448 LV2_Atom_Buffer_Iterator iter
;
4451 lv2_atom_buffer_begin(&iter
, evData
.atom
);
4456 ev
= lv2_atom_buffer_get(&iter
, &data
);
4458 if (ev
== nullptr || ev
->body
.size
== 0 || data
== nullptr)
4461 if (ev
->body
.type
== kUridMidiEvent
)
4463 if (evData
.port
!= nullptr)
4465 CARLA_SAFE_ASSERT_CONTINUE(ev
->time
.frames
>= 0);
4466 CARLA_SAFE_ASSERT_CONTINUE(ev
->body
.size
< 0xFF);
4468 uint32_t currentFrame
= static_cast<uint32_t>(ev
->time
.frames
);
4469 if (currentFrame
< lastFrame
)
4470 currentFrame
= lastFrame
;
4471 else if (currentFrame
>= frames
)
4472 currentFrame
= frames
- 1;
4474 evData
.port
->writeMidiEvent(currentFrame
, static_cast<uint8_t>(ev
->body
.size
), data
);
4477 else if (fAtomBufferUiOutTmpData
!= nullptr)
4479 fAtomBufferUiOut
.put(&ev
->body
, evData
.rindex
);
4482 lv2_atom_buffer_increment(&iter
);
4485 else if ((evData
.type
& CARLA_EVENT_DATA_EVENT
) != 0 && evData
.port
!= nullptr)
4487 const LV2_Event
* ev
;
4488 LV2_Event_Iterator iter
;
4491 lv2_event_begin(&iter
, evData
.event
);
4496 ev
= lv2_event_get(&iter
, &data
);
4498 if (ev
== nullptr || data
== nullptr)
4501 uint32_t currentFrame
= ev
->frames
;
4502 if (currentFrame
< lastFrame
)
4503 currentFrame
= lastFrame
;
4504 else if (currentFrame
>= frames
)
4505 currentFrame
= frames
- 1;
4507 if (ev
->type
== kUridMidiEvent
)
4509 CARLA_SAFE_ASSERT_CONTINUE(ev
->size
< 0xFF);
4510 evData
.port
->writeMidiEvent(currentFrame
, static_cast<uint8_t>(ev
->size
), data
);
4513 lv2_event_increment(&iter
);
4516 else if ((evData
.type
& CARLA_EVENT_DATA_MIDI_LL
) != 0 && evData
.port
!= nullptr)
4518 LV2_MIDIState state
= { &evData
.midi
, frames
, 0 };
4528 eventData
= nullptr;
4529 lv2midi_get_event(&state
, &eventTime
, &eventSize
, &eventData
);
4531 if (eventData
== nullptr || eventSize
== 0)
4534 CARLA_SAFE_ASSERT_CONTINUE(eventSize
< 0xFF);
4535 CARLA_SAFE_ASSERT_CONTINUE(eventTime
>= 0.0);
4537 evData
.port
->writeMidiEvent(static_cast<uint32_t>(eventTime
), static_cast<uint8_t>(eventSize
), eventData
);
4538 lv2midi_step(&state
);
4543 fFirstActive
= false;
4545 // --------------------------------------------------------------------------------------------------------
4548 bool processSingle(const float* const* const audioIn
, float** const audioOut
,
4549 const float* const* const cvIn
, float** const cvOut
,
4550 const uint32_t frames
, const uint32_t timeOffset
)
4552 CARLA_SAFE_ASSERT_RETURN(frames
> 0, false);
4554 if (pData
->audioIn
.count
> 0)
4556 CARLA_SAFE_ASSERT_RETURN(audioIn
!= nullptr, false);
4557 CARLA_SAFE_ASSERT_RETURN(fAudioInBuffers
!= nullptr, false);
4559 if (pData
->audioOut
.count
> 0)
4561 CARLA_SAFE_ASSERT_RETURN(audioOut
!= nullptr, false);
4562 CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers
!= nullptr, false);
4564 if (pData
->cvIn
.count
> 0)
4566 CARLA_SAFE_ASSERT_RETURN(cvIn
!= nullptr, false);
4568 if (pData
->cvOut
.count
> 0)
4570 CARLA_SAFE_ASSERT_RETURN(cvOut
!= nullptr, false);
4573 // --------------------------------------------------------------------------------------------------------
4574 // Try lock, silence otherwise
4576 #ifndef STOAT_TEST_BUILD
4577 if (pData
->engine
->isOffline())
4579 pData
->singleMutex
.lock();
4583 if (! pData
->singleMutex
.tryLock())
4585 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4587 for (uint32_t k
=0; k
< frames
; ++k
)
4588 audioOut
[i
][k
+timeOffset
] = 0.0f
;
4590 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
4592 for (uint32_t k
=0; k
< frames
; ++k
)
4593 cvOut
[i
][k
+timeOffset
] = 0.0f
;
4599 // --------------------------------------------------------------------------------------------------------
4600 // Set audio buffers
4602 for (uint32_t i
=0; i
< pData
->audioIn
.count
; ++i
)
4603 carla_copyFloats(fAudioInBuffers
[i
], audioIn
[i
]+timeOffset
, frames
);
4605 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4606 carla_zeroFloats(fAudioOutBuffers
[i
], frames
);
4608 // --------------------------------------------------------------------------------------------------------
4611 for (uint32_t i
=0; i
< pData
->cvIn
.count
; ++i
)
4612 carla_copyFloats(fCvInBuffers
[i
], cvIn
[i
]+timeOffset
, frames
);
4614 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
4615 carla_zeroFloats(fCvOutBuffers
[i
], frames
);
4617 // --------------------------------------------------------------------------------------------------------
4620 fDescriptor
->run(fHandle
, frames
);
4622 if (fHandle2
!= nullptr)
4623 fDescriptor
->run(fHandle2
, frames
);
4625 // --------------------------------------------------------------------------------------------------------
4626 // Handle trigger parameters
4628 for (uint32_t k
=0; k
< pData
->param
.count
; ++k
)
4630 if (pData
->param
.data
[k
].type
!= PARAMETER_INPUT
)
4633 if (pData
->param
.data
[k
].hints
& PARAMETER_IS_TRIGGER
)
4635 if (carla_isNotEqual(fParamBuffers
[k
], pData
->param
.ranges
[k
].def
))
4637 fParamBuffers
[k
] = pData
->param
.ranges
[k
].def
;
4638 pData
->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k
), fParamBuffers
[k
]);
4643 pData
->postRtEvents
.trySplice();
4645 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
4646 // --------------------------------------------------------------------------------------------------------
4647 // Post-processing (dry/wet, volume and balance)
4650 const bool doDryWet
= (pData
->hints
& PLUGIN_CAN_DRYWET
) != 0 && carla_isNotEqual(pData
->postProc
.dryWet
, 1.0f
);
4651 const bool doBalance
= (pData
->hints
& PLUGIN_CAN_BALANCE
) != 0 && ! (carla_isEqual(pData
->postProc
.balanceLeft
, -1.0f
) && carla_isEqual(pData
->postProc
.balanceRight
, 1.0f
));
4652 const bool isMono
= (pData
->audioIn
.count
== 1);
4656 float* const oldBufLeft
= pData
->postProc
.extraBuffer
;
4658 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4663 const uint32_t c
= isMono
? 0 : i
;
4665 for (uint32_t k
=0; k
< frames
; ++k
)
4667 # ifndef BUILD_BRIDGE
4668 if (k
< pData
->latency
.frames
&& pData
->latency
.buffers
!= nullptr)
4669 bufValue
= pData
->latency
.buffers
[c
][k
];
4670 else if (pData
->latency
.frames
< frames
)
4671 bufValue
= fAudioInBuffers
[c
][k
-pData
->latency
.frames
];
4674 bufValue
= fAudioInBuffers
[c
][k
];
4676 fAudioOutBuffers
[i
][k
] = (fAudioOutBuffers
[i
][k
] * pData
->postProc
.dryWet
) + (bufValue
* (1.0f
- pData
->postProc
.dryWet
));
4683 isPair
= (i
% 2 == 0);
4687 CARLA_ASSERT(i
+1 < pData
->audioOut
.count
);
4688 carla_copyFloats(oldBufLeft
, fAudioOutBuffers
[i
], frames
);
4691 float balRangeL
= (pData
->postProc
.balanceLeft
+ 1.0f
)/2.0f
;
4692 float balRangeR
= (pData
->postProc
.balanceRight
+ 1.0f
)/2.0f
;
4694 for (uint32_t k
=0; k
< frames
; ++k
)
4699 fAudioOutBuffers
[i
][k
] = oldBufLeft
[k
] * (1.0f
- balRangeL
);
4700 fAudioOutBuffers
[i
][k
] += fAudioOutBuffers
[i
+1][k
] * (1.0f
- balRangeR
);
4705 fAudioOutBuffers
[i
][k
] = fAudioOutBuffers
[i
][k
] * balRangeR
;
4706 fAudioOutBuffers
[i
][k
] += oldBufLeft
[k
] * balRangeL
;
4711 // Volume (and buffer copy)
4713 for (uint32_t k
=0; k
< frames
; ++k
)
4714 audioOut
[i
][k
+timeOffset
] = fAudioOutBuffers
[i
][k
] * pData
->postProc
.volume
;
4717 } // End of Post-processing
4719 # ifndef BUILD_BRIDGE
4720 // --------------------------------------------------------------------------------------------------------
4721 // Save latency values for next callback
4723 if (pData
->latency
.frames
!= 0 && pData
->latency
.buffers
!= nullptr)
4725 CARLA_SAFE_ASSERT(timeOffset
== 0);
4726 const uint32_t latframes
= pData
->latency
.frames
;
4728 if (latframes
<= frames
)
4730 for (uint32_t i
=0; i
< pData
->audioIn
.count
; ++i
)
4731 carla_copyFloats(pData
->latency
.buffers
[i
], audioIn
[i
]+(frames
-latframes
), latframes
);
4735 const uint32_t diff
= latframes
- frames
;
4737 for (uint32_t i
=0, k
; i
<pData
->audioIn
.count
; ++i
)
4739 // push back buffer by 'frames'
4740 for (k
=0; k
< diff
; ++k
)
4741 pData
->latency
.buffers
[i
][k
] = pData
->latency
.buffers
[i
][k
+frames
];
4743 // put current input at the end
4744 for (uint32_t j
=0; k
< latframes
; ++j
, ++k
)
4745 pData
->latency
.buffers
[i
][k
] = audioIn
[i
][j
];
4750 #else // BUILD_BRIDGE_ALTERNATIVE_ARCH
4751 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4753 for (uint32_t k
=0; k
< frames
; ++k
)
4754 audioOut
[i
][k
+timeOffset
] = fAudioOutBuffers
[i
][k
];
4758 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
4760 for (uint32_t k
=0; k
< frames
; ++k
)
4761 cvOut
[i
][k
+timeOffset
] = fCvOutBuffers
[i
][k
];
4764 // --------------------------------------------------------------------------------------------------------
4766 pData
->singleMutex
.unlock();
4770 void bufferSizeChanged(const uint32_t newBufferSize
) override
4772 CARLA_ASSERT_INT(newBufferSize
> 0, newBufferSize
);
4773 carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - start", newBufferSize
);
4775 for (uint32_t i
=0; i
< pData
->audioIn
.count
; ++i
)
4777 if (fAudioInBuffers
[i
] != nullptr)
4778 delete[] fAudioInBuffers
[i
];
4779 fAudioInBuffers
[i
] = new float[newBufferSize
];
4782 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4784 if (fAudioOutBuffers
[i
] != nullptr)
4785 delete[] fAudioOutBuffers
[i
];
4786 fAudioOutBuffers
[i
] = new float[newBufferSize
];
4789 if (fHandle2
== nullptr)
4791 for (uint32_t i
=0; i
< pData
->audioIn
.count
; ++i
)
4793 CARLA_ASSERT(fAudioInBuffers
[i
] != nullptr);
4794 fDescriptor
->connect_port(fHandle
, pData
->audioIn
.ports
[i
].rindex
, fAudioInBuffers
[i
]);
4797 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4799 CARLA_ASSERT(fAudioOutBuffers
[i
] != nullptr);
4800 fDescriptor
->connect_port(fHandle
, pData
->audioOut
.ports
[i
].rindex
, fAudioOutBuffers
[i
]);
4805 if (pData
->audioIn
.count
> 0)
4807 CARLA_ASSERT(pData
->audioIn
.count
== 2);
4808 CARLA_ASSERT(fAudioInBuffers
[0] != nullptr);
4809 CARLA_ASSERT(fAudioInBuffers
[1] != nullptr);
4811 fDescriptor
->connect_port(fHandle
, pData
->audioIn
.ports
[0].rindex
, fAudioInBuffers
[0]);
4812 fDescriptor
->connect_port(fHandle2
, pData
->audioIn
.ports
[1].rindex
, fAudioInBuffers
[1]);
4815 if (pData
->audioOut
.count
> 0)
4817 CARLA_ASSERT(pData
->audioOut
.count
== 2);
4818 CARLA_ASSERT(fAudioOutBuffers
[0] != nullptr);
4819 CARLA_ASSERT(fAudioOutBuffers
[1] != nullptr);
4821 fDescriptor
->connect_port(fHandle
, pData
->audioOut
.ports
[0].rindex
, fAudioOutBuffers
[0]);
4822 fDescriptor
->connect_port(fHandle2
, pData
->audioOut
.ports
[1].rindex
, fAudioOutBuffers
[1]);
4826 for (uint32_t i
=0; i
< pData
->cvIn
.count
; ++i
)
4828 if (fCvInBuffers
[i
] != nullptr)
4829 delete[] fCvInBuffers
[i
];
4830 fCvInBuffers
[i
] = new float[newBufferSize
];
4832 fDescriptor
->connect_port(fHandle
, pData
->cvIn
.ports
[i
].rindex
, fCvInBuffers
[i
]);
4834 if (fHandle2
!= nullptr)
4835 fDescriptor
->connect_port(fHandle2
, pData
->cvIn
.ports
[i
].rindex
, fCvInBuffers
[i
]);
4838 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
4840 if (fCvOutBuffers
[i
] != nullptr)
4841 delete[] fCvOutBuffers
[i
];
4842 fCvOutBuffers
[i
] = new float[newBufferSize
];
4844 fDescriptor
->connect_port(fHandle
, pData
->cvOut
.ports
[i
].rindex
, fCvOutBuffers
[i
]);
4846 if (fHandle2
!= nullptr)
4847 fDescriptor
->connect_port(fHandle2
, pData
->cvOut
.ports
[i
].rindex
, fCvOutBuffers
[i
]);
4850 const int newBufferSizeInt(static_cast<int>(newBufferSize
));
4852 if (fLv2Options
.maxBufferSize
!= newBufferSizeInt
|| (fLv2Options
.minBufferSize
!= 1 && fLv2Options
.minBufferSize
!= newBufferSizeInt
))
4854 fLv2Options
.maxBufferSize
= fLv2Options
.nominalBufferSize
= newBufferSizeInt
;
4856 if (fLv2Options
.minBufferSize
!= 1)
4857 fLv2Options
.minBufferSize
= newBufferSizeInt
;
4859 if (fExt
.options
!= nullptr && fExt
.options
->set
!= nullptr)
4861 LV2_Options_Option options
[4];
4862 carla_zeroStructs(options
, 4);
4864 carla_copyStruct(options
[0], fLv2Options
.opts
[CarlaPluginLV2Options::MaxBlockLenth
]);
4865 carla_copyStruct(options
[1], fLv2Options
.opts
[CarlaPluginLV2Options::NominalBlockLenth
]);
4867 if (fLv2Options
.minBufferSize
!= 1)
4868 carla_copyStruct(options
[2], fLv2Options
.opts
[CarlaPluginLV2Options::MinBlockLenth
]);
4870 fExt
.options
->set(fHandle
, options
);
4874 carla_debug("CarlaPluginLV2::bufferSizeChanged(%i) - end", newBufferSize
);
4876 CarlaPlugin::bufferSizeChanged(newBufferSize
);
4879 void sampleRateChanged(const double newSampleRate
) override
4881 CARLA_ASSERT_INT(newSampleRate
> 0.0, newSampleRate
);
4882 carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - start", newSampleRate
);
4884 const float sampleRatef
= static_cast<float>(newSampleRate
);
4886 if (carla_isNotEqual(fLv2Options
.sampleRate
, sampleRatef
))
4888 fLv2Options
.sampleRate
= sampleRatef
;
4890 if (fExt
.options
!= nullptr && fExt
.options
->set
!= nullptr)
4892 LV2_Options_Option options
[2];
4893 carla_copyStruct(options
[0], fLv2Options
.opts
[CarlaPluginLV2Options::SampleRate
]);
4894 carla_zeroStruct(options
[1]);
4896 fExt
.options
->set(fHandle
, options
);
4900 for (uint32_t k
=0; k
< pData
->param
.count
; ++k
)
4902 if (pData
->param
.data
[k
].type
!= PARAMETER_INPUT
)
4904 if (pData
->param
.special
[k
] != PARAMETER_SPECIAL_SAMPLE_RATE
)
4907 fParamBuffers
[k
] = sampleRatef
;
4908 pData
->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k
), fParamBuffers
[k
]);
4912 carla_debug("CarlaPluginLV2::sampleRateChanged(%g) - end", newSampleRate
);
4915 void offlineModeChanged(const bool isOffline
) override
4917 for (uint32_t k
=0; k
< pData
->param
.count
; ++k
)
4919 if (pData
->param
.data
[k
].type
== PARAMETER_INPUT
&& pData
->param
.special
[k
] == PARAMETER_SPECIAL_FREEWHEEL
)
4921 fParamBuffers
[k
] = isOffline
? pData
->param
.ranges
[k
].max
: pData
->param
.ranges
[k
].min
;
4922 pData
->postponeParameterChangeRtEvent(true, static_cast<int32_t>(k
), fParamBuffers
[k
]);
4928 // -------------------------------------------------------------------
4931 void initBuffers() const noexcept override
4933 fEventsIn
.initBuffers();
4934 fEventsOut
.initBuffers();
4936 CarlaPlugin::initBuffers();
4939 void clearBuffers() noexcept override
4941 carla_debug("CarlaPluginLV2::clearBuffers() - start");
4943 if (fAudioInBuffers
!= nullptr)
4945 for (uint32_t i
=0; i
< pData
->audioIn
.count
; ++i
)
4947 if (fAudioInBuffers
[i
] != nullptr)
4949 delete[] fAudioInBuffers
[i
];
4950 fAudioInBuffers
[i
] = nullptr;
4954 delete[] fAudioInBuffers
;
4955 fAudioInBuffers
= nullptr;
4958 if (fAudioOutBuffers
!= nullptr)
4960 for (uint32_t i
=0; i
< pData
->audioOut
.count
; ++i
)
4962 if (fAudioOutBuffers
[i
] != nullptr)
4964 delete[] fAudioOutBuffers
[i
];
4965 fAudioOutBuffers
[i
] = nullptr;
4969 delete[] fAudioOutBuffers
;
4970 fAudioOutBuffers
= nullptr;
4973 if (fCvInBuffers
!= nullptr)
4975 for (uint32_t i
=0; i
< pData
->cvIn
.count
; ++i
)
4977 if (fCvInBuffers
[i
] != nullptr)
4979 delete[] fCvInBuffers
[i
];
4980 fCvInBuffers
[i
] = nullptr;
4984 delete[] fCvInBuffers
;
4985 fCvInBuffers
= nullptr;
4988 if (fCvOutBuffers
!= nullptr)
4990 for (uint32_t i
=0; i
< pData
->cvOut
.count
; ++i
)
4992 if (fCvOutBuffers
[i
] != nullptr)
4994 delete[] fCvOutBuffers
[i
];
4995 fCvOutBuffers
[i
] = nullptr;
4999 delete[] fCvOutBuffers
;
5000 fCvOutBuffers
= nullptr;
5003 if (fParamBuffers
!= nullptr)
5005 delete[] fParamBuffers
;
5006 fParamBuffers
= nullptr;
5009 fEventsIn
.clear(pData
->event
.portIn
);
5010 fEventsOut
.clear(pData
->event
.portOut
);
5012 CarlaPlugin::clearBuffers();
5014 carla_debug("CarlaPluginLV2::clearBuffers() - end");
5017 // -------------------------------------------------------------------
5018 // Post-poned UI Stuff
5020 void uiParameterChange(const uint32_t index
, const float value
) noexcept override
5022 CARLA_SAFE_ASSERT_RETURN(fUI
.type
!= UI::TYPE_NULL
|| fFilePathURI
.isNotEmpty(),);
5023 CARLA_SAFE_ASSERT_RETURN(index
< pData
->param
.count
,);
5024 CARLA_SAFE_ASSERT_RETURN(pData
->param
.data
[index
].rindex
>= 0,);
5026 #ifndef LV2_UIS_ONLY_INPROCESS
5027 if (fUI
.type
== UI::TYPE_BRIDGE
)
5029 if (! fPipeServer
.isPipeRunning())
5035 if (fUI
.handle
== nullptr)
5037 if (fUI
.descriptor
== nullptr || fUI
.descriptor
->port_event
== nullptr)
5043 ParameterData
& pdata(pData
->param
.data
[index
]);
5045 if (pdata
.hints
& PARAMETER_IS_NOT_SAVED
)
5047 int32_t rindex
= pdata
.rindex
;
5048 CARLA_SAFE_ASSERT_RETURN(rindex
- static_cast<int32_t>(fRdfDescriptor
->PortCount
) >= 0,);
5050 rindex
-= static_cast<int32_t>(fRdfDescriptor
->PortCount
);
5051 CARLA_SAFE_ASSERT_RETURN(rindex
< static_cast<int32_t>(fRdfDescriptor
->ParameterCount
),);
5053 const char* const uri
= fRdfDescriptor
->Parameters
[rindex
].URI
;
5055 #ifndef LV2_UIS_ONLY_INPROCESS
5056 if (fUI
.type
== UI::TYPE_BRIDGE
)
5058 fPipeServer
.writeLv2ParameterMessage(uri
, value
);
5062 if (fEventsIn
.ctrl
!= nullptr)
5064 uint8_t atomBuf
[256];
5065 LV2_Atom_Forge atomForge
;
5066 initAtomForge(atomForge
);
5067 lv2_atom_forge_set_buffer(&atomForge
, atomBuf
, sizeof(atomBuf
));
5069 LV2_Atom_Forge_Frame forgeFrame
;
5070 lv2_atom_forge_object(&atomForge
, &forgeFrame
, kUridNull
, kUridPatchSet
);
5072 lv2_atom_forge_key(&atomForge
, kUridCarlaParameterChange
);
5073 lv2_atom_forge_bool(&atomForge
, true);
5075 lv2_atom_forge_key(&atomForge
, kUridPatchProperty
);
5076 lv2_atom_forge_urid(&atomForge
, getCustomURID(uri
));
5078 lv2_atom_forge_key(&atomForge
, kUridPatchValue
);
5080 switch (fRdfDescriptor
->Parameters
[rindex
].Type
)
5082 case LV2_PARAMETER_TYPE_BOOL
:
5083 lv2_atom_forge_bool(&atomForge
, value
> 0.5f
);
5085 case LV2_PARAMETER_TYPE_INT
:
5086 lv2_atom_forge_int(&atomForge
, static_cast<int32_t>(value
+ 0.5f
));
5088 case LV2_PARAMETER_TYPE_LONG
:
5089 lv2_atom_forge_long(&atomForge
, static_cast<int64_t>(value
+ 0.5f
));
5091 case LV2_PARAMETER_TYPE_FLOAT
:
5092 lv2_atom_forge_float(&atomForge
, value
);
5094 case LV2_PARAMETER_TYPE_DOUBLE
:
5095 lv2_atom_forge_double(&atomForge
, value
);
5098 carla_stderr2("uiParameterChange called for invalid parameter, abort!");
5102 lv2_atom_forge_pop(&atomForge
, &forgeFrame
);
5104 LV2_Atom
* const atom((LV2_Atom
*)atomBuf
);
5105 CARLA_SAFE_ASSERT(atom
->size
< sizeof(atomBuf
));
5107 fUI
.descriptor
->port_event(fUI
.handle
,
5108 fEventsIn
.ctrl
->rindex
,
5109 lv2_atom_total_size(atom
),
5110 kUridAtomTransferEvent
,
5116 #ifndef LV2_UIS_ONLY_INPROCESS
5117 if (fUI
.type
== UI::TYPE_BRIDGE
)
5119 fPipeServer
.writeControlMessage(static_cast<uint32_t>(pData
->param
.data
[index
].rindex
), value
);
5124 fUI
.descriptor
->port_event(fUI
.handle
,
5125 static_cast<uint32_t>(pData
->param
.data
[index
].rindex
),
5126 sizeof(float), kUridNull
, &value
);
5131 void uiMidiProgramChange(const uint32_t index
) noexcept override
5133 CARLA_SAFE_ASSERT_RETURN(fUI
.type
!= UI::TYPE_NULL
|| fFilePathURI
.isNotEmpty(),);
5134 CARLA_SAFE_ASSERT_RETURN(index
< pData
->midiprog
.count
,);
5136 #ifndef LV2_UIS_ONLY_INPROCESS
5137 if (fUI
.type
== UI::TYPE_BRIDGE
)
5139 if (fPipeServer
.isPipeRunning())
5140 fPipeServer
.writeMidiProgramMessage(pData
->midiprog
.data
[index
].bank
, pData
->midiprog
.data
[index
].program
);
5145 if (fExt
.uiprograms
!= nullptr && fExt
.uiprograms
->select_program
!= nullptr && ! fNeedsUiClose
)
5146 fExt
.uiprograms
->select_program(fUI
.handle
, pData
->midiprog
.data
[index
].bank
, pData
->midiprog
.data
[index
].program
);
5150 void uiNoteOn(const uint8_t channel
, const uint8_t note
, const uint8_t velo
) noexcept override
5152 CARLA_SAFE_ASSERT_RETURN(fUI
.type
!= UI::TYPE_NULL
|| fFilePathURI
.isNotEmpty(),);
5153 CARLA_SAFE_ASSERT_RETURN(channel
< MAX_MIDI_CHANNELS
,);
5154 CARLA_SAFE_ASSERT_RETURN(note
< MAX_MIDI_NOTE
,);
5155 CARLA_SAFE_ASSERT_RETURN(velo
> 0 && velo
< MAX_MIDI_VALUE
,);
5158 if (fUI
.type
== UI::TYPE_BRIDGE
)
5160 if (fPipeServer
.isPipeRunning())
5161 fPipeServer
.writeMidiNoteMessage(false, channel
, note
, velo
);
5165 if (fUI
.handle
!= nullptr && fUI
.descriptor
!= nullptr && fUI
.descriptor
->port_event
!= nullptr && fEventsIn
.ctrl
!= nullptr && ! fNeedsUiClose
)
5167 LV2_Atom_MidiEvent midiEv
;
5168 midiEv
.atom
.type
= kUridMidiEvent
;
5169 midiEv
.atom
.size
= 3;
5170 midiEv
.data
[0] = uint8_t(MIDI_STATUS_NOTE_ON
| (channel
& MIDI_CHANNEL_BIT
));
5171 midiEv
.data
[1] = note
;
5172 midiEv
.data
[2] = velo
;
5174 fUI
.descriptor
->port_event(fUI
.handle
, fEventsIn
.ctrl
->rindex
, lv2_atom_total_size(midiEv
), kUridAtomTransferEvent
, &midiEv
);
5180 void uiNoteOff(const uint8_t channel
, const uint8_t note
) noexcept override
5182 CARLA_SAFE_ASSERT_RETURN(fUI
.type
!= UI::TYPE_NULL
|| fFilePathURI
.isNotEmpty(),);
5183 CARLA_SAFE_ASSERT_RETURN(channel
< MAX_MIDI_CHANNELS
,);
5184 CARLA_SAFE_ASSERT_RETURN(note
< MAX_MIDI_NOTE
,);
5187 if (fUI
.type
== UI::TYPE_BRIDGE
)
5189 if (fPipeServer
.isPipeRunning())
5190 fPipeServer
.writeMidiNoteMessage(false, channel
, note
, 0);
5194 if (fUI
.handle
!= nullptr && fUI
.descriptor
!= nullptr && fUI
.descriptor
->port_event
!= nullptr && fEventsIn
.ctrl
!= nullptr && ! fNeedsUiClose
)
5196 LV2_Atom_MidiEvent midiEv
;
5197 midiEv
.atom
.type
= kUridMidiEvent
;
5198 midiEv
.atom
.size
= 3;
5199 midiEv
.data
[0] = uint8_t(MIDI_STATUS_NOTE_OFF
| (channel
& MIDI_CHANNEL_BIT
));
5200 midiEv
.data
[1] = note
;
5203 fUI
.descriptor
->port_event(fUI
.handle
, fEventsIn
.ctrl
->rindex
, lv2_atom_total_size(midiEv
), kUridAtomTransferEvent
, &midiEv
);
5209 // -------------------------------------------------------------------
5210 // Internal helper functions
5212 void cloneLV2Files(const CarlaPlugin
& other
) override
5214 CARLA_SAFE_ASSERT_RETURN(other
.getType() == PLUGIN_LV2
,);
5216 const CarlaPluginLV2
& otherLV2((const CarlaPluginLV2
&)other
);
5218 const File
tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5220 if (tmpDir
.exists())
5221 tmpDir
.deleteRecursively();
5223 const File
otherStateDir(otherLV2
.handleStateMapToAbsolutePath(false, false, false, "."));
5225 if (otherStateDir
.exists())
5226 otherStateDir
.copyDirectoryTo(tmpDir
);
5228 const File
otherTmpDir(otherLV2
.handleStateMapToAbsolutePath(false, false, true, "."));
5230 if (otherTmpDir
.exists())
5231 otherTmpDir
.copyDirectoryTo(tmpDir
);
5234 void restoreLV2State(const bool temporary
) noexcept override
5236 if (fExt
.state
== nullptr || fExt
.state
->restore
== nullptr)
5241 const File
tmpDir(handleStateMapToAbsolutePath(false, false, true, "."));
5243 if (tmpDir
.exists())
5244 tmpDir
.deleteRecursively();
5247 LV2_State_Status status
= LV2_STATE_ERR_UNKNOWN
;
5250 const ScopedSingleProcessLocker
spl(this, !fHasThreadSafeRestore
);
5253 status
= fExt
.state
->restore(fHandle
,
5254 carla_lv2_state_retrieve
,
5257 temporary
? fFeatures
: fStateFeatures
);
5260 if (fHandle2
!= nullptr)
5263 fExt
.state
->restore(fHandle
,
5264 carla_lv2_state_retrieve
,
5267 temporary
? fFeatures
: fStateFeatures
);
5274 case LV2_STATE_SUCCESS
:
5275 carla_debug("CarlaPluginLV2::updateLV2State() - success");
5277 case LV2_STATE_ERR_UNKNOWN
:
5278 carla_stderr("CarlaPluginLV2::updateLV2State() - unknown error");
5280 case LV2_STATE_ERR_BAD_TYPE
:
5281 carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad type");
5283 case LV2_STATE_ERR_BAD_FLAGS
:
5284 carla_stderr("CarlaPluginLV2::updateLV2State() - error, bad flags");
5286 case LV2_STATE_ERR_NO_FEATURE
:
5287 carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing feature");
5289 case LV2_STATE_ERR_NO_PROPERTY
:
5290 carla_stderr("CarlaPluginLV2::updateLV2State() - error, missing property");
5292 case LV2_STATE_ERR_NO_SPACE
:
5293 carla_stderr("CarlaPluginLV2::updateLV2State() - error, insufficient space");
5298 // -------------------------------------------------------------------
5300 bool isRealtimeSafe() const noexcept
5302 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr, false);
5304 for (uint32_t i
=0; i
< fRdfDescriptor
->FeatureCount
; ++i
)
5306 if (std::strcmp(fRdfDescriptor
->Features
[i
].URI
, LV2_CORE__hardRTCapable
) == 0)
5313 // -------------------------------------------------------------------
5315 bool isUiBridgeable(const uint32_t uiId
) const noexcept
5317 CARLA_SAFE_ASSERT_RETURN(uiId
< fRdfDescriptor
->UICount
, false);
5319 #ifndef LV2_UIS_ONLY_INPROCESS
5320 const LV2_RDF_UI
* const rdfUI(&fRdfDescriptor
->UIs
[uiId
]);
5322 for (uint32_t i
=0; i
< rdfUI
->FeatureCount
; ++i
)
5324 const LV2_RDF_Feature
& feat(rdfUI
->Features
[i
]);
5326 if (! feat
.Required
)
5328 if (std::strcmp(feat
.URI
, LV2_INSTANCE_ACCESS_URI
) == 0)
5330 if (std::strcmp(feat
.URI
, LV2_DATA_ACCESS_URI
) == 0)
5334 // Calf UIs are mostly useless without their special graphs
5335 // but they can be crashy under certain conditions, so follow user preferences
5336 if (std::strstr(rdfUI
->URI
, "http://calf.sourceforge.net/plugins/gui/") != nullptr)
5337 return pData
->engine
->getOptions().preferUiBridges
;
5339 // LSP-Plugins UIs make heavy use of URIDs, for which carla right now is very slow
5340 // FIXME after some optimization, remove this
5341 if (std::strstr(rdfUI
->URI
, "http://lsp-plug.in/ui/lv2/") != nullptr)
5350 bool isUiResizable() const noexcept
5352 CARLA_SAFE_ASSERT_RETURN(fUI
.rdfDescriptor
!= nullptr, false);
5354 for (uint32_t i
=0; i
< fUI
.rdfDescriptor
->FeatureCount
; ++i
)
5356 if (std::strcmp(fUI
.rdfDescriptor
->Features
[i
].URI
, LV2_UI__fixedSize
) == 0)
5358 if (std::strcmp(fUI
.rdfDescriptor
->Features
[i
].URI
, LV2_UI__noUserResize
) == 0)
5365 const char* getUiBridgeBinary(const LV2_Property type
) const
5367 CarlaString
bridgeBinary(pData
->engine
->getOptions().binaryDir
);
5369 if (bridgeBinary
.isEmpty())
5375 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-gtk2";
5378 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-gtk3";
5381 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-qt4";
5384 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-qt5";
5387 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-cocoa";
5389 case LV2_UI_WINDOWS
:
5390 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-windows";
5393 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-x11";
5396 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-modgui";
5399 case LV2_UI_EXTERNAL
:
5400 case LV2_UI_OLD_EXTERNAL
:
5401 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-lv2-external";
5409 bridgeBinary
+= ".exe";
5412 if (! File(bridgeBinary
.buffer()).existsAsFile())
5415 return bridgeBinary
.dupSafe();
5418 // -------------------------------------------------------------------
5420 void recheckExtensions()
5422 CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor
!= nullptr,);
5423 carla_debug("CarlaPluginLV2::recheckExtensions()");
5425 fExt
.options
= nullptr;
5426 fExt
.programs
= nullptr;
5427 fExt
.state
= nullptr;
5428 fExt
.worker
= nullptr;
5429 fExt
.inlineDisplay
= nullptr;
5431 for (uint32_t i
=0; i
< fRdfDescriptor
->ExtensionCount
; ++i
)
5433 const char* const extension
= fRdfDescriptor
->Extensions
[i
];
5434 CARLA_SAFE_ASSERT_CONTINUE(extension
!= nullptr);
5436 /**/ if (std::strcmp(extension
, LV2_OPTIONS__interface
) == 0)
5437 pData
->hints
|= PLUGIN_HAS_EXTENSION_OPTIONS
;
5438 else if (std::strcmp(extension
, LV2_PROGRAMS__Interface
) == 0)
5439 pData
->hints
|= PLUGIN_HAS_EXTENSION_PROGRAMS
;
5440 else if (std::strcmp(extension
, LV2_STATE__interface
) == 0)
5441 pData
->hints
|= PLUGIN_HAS_EXTENSION_STATE
;
5442 else if (std::strcmp(extension
, LV2_WORKER__interface
) == 0)
5443 pData
->hints
|= PLUGIN_HAS_EXTENSION_WORKER
;
5444 else if (std::strcmp(extension
, LV2_INLINEDISPLAY__interface
) == 0)
5445 pData
->hints
|= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY
;
5446 else if (std::strcmp(extension
, LV2_MIDNAM__interface
) == 0)
5447 pData
->hints
|= PLUGIN_HAS_EXTENSION_MIDNAM
;
5449 carla_stdout("Plugin '%s' has non-supported extension: '%s'", fRdfDescriptor
->URI
, extension
);
5452 // Fix for broken plugins, nasty!
5453 for (uint32_t i
=0; i
< fRdfDescriptor
->FeatureCount
; ++i
)
5455 const LV2_RDF_Feature
& feature(fRdfDescriptor
->Features
[i
]);
5457 if (std::strcmp(feature
.URI
, LV2_INLINEDISPLAY__queue_draw
) == 0)
5459 if (pData
->hints
& PLUGIN_HAS_EXTENSION_INLINE_DISPLAY
)
5462 carla_stdout("Plugin '%s' uses inline-display but does not set extension data, nasty!", fRdfDescriptor
->URI
);
5463 pData
->hints
|= PLUGIN_HAS_EXTENSION_INLINE_DISPLAY
;
5465 else if (std::strcmp(feature
.URI
, LV2_MIDNAM__update
) == 0)
5467 if (pData
->hints
& PLUGIN_HAS_EXTENSION_MIDNAM
)
5470 carla_stdout("Plugin '%s' uses midnam but does not set extension data, nasty!", fRdfDescriptor
->URI
);
5471 pData
->hints
|= PLUGIN_HAS_EXTENSION_MIDNAM
;
5475 if (fDescriptor
->extension_data
!= nullptr)
5477 if (pData
->hints
& PLUGIN_HAS_EXTENSION_OPTIONS
)
5478 fExt
.options
= (const LV2_Options_Interface
*)fDescriptor
->extension_data(LV2_OPTIONS__interface
);
5480 if (pData
->hints
& PLUGIN_HAS_EXTENSION_PROGRAMS
)
5481 fExt
.programs
= (const LV2_Programs_Interface
*)fDescriptor
->extension_data(LV2_PROGRAMS__Interface
);
5483 if (pData
->hints
& PLUGIN_HAS_EXTENSION_STATE
)
5484 fExt
.state
= (const LV2_State_Interface
*)fDescriptor
->extension_data(LV2_STATE__interface
);
5486 if (pData
->hints
& PLUGIN_HAS_EXTENSION_WORKER
)
5487 fExt
.worker
= (const LV2_Worker_Interface
*)fDescriptor
->extension_data(LV2_WORKER__interface
);
5489 if (pData
->hints
& PLUGIN_HAS_EXTENSION_INLINE_DISPLAY
)
5490 fExt
.inlineDisplay
= (const LV2_Inline_Display_Interface
*)fDescriptor
->extension_data(LV2_INLINEDISPLAY__interface
);
5492 if (pData
->hints
& PLUGIN_HAS_EXTENSION_MIDNAM
)
5493 fExt
.midnam
= (const LV2_Midnam_Interface
*)fDescriptor
->extension_data(LV2_MIDNAM__interface
);
5496 if (fExt
.options
!= nullptr && fExt
.options
->get
== nullptr && fExt
.options
->set
== nullptr)
5497 fExt
.options
= nullptr;
5499 if (fExt
.programs
!= nullptr && (fExt
.programs
->get_program
== nullptr || fExt
.programs
->select_program
== nullptr))
5500 fExt
.programs
= nullptr;
5502 if (fExt
.state
!= nullptr && (fExt
.state
->save
== nullptr || fExt
.state
->restore
== nullptr))
5503 fExt
.state
= nullptr;
5505 if (fExt
.worker
!= nullptr && fExt
.worker
->work
== nullptr)
5506 fExt
.worker
= nullptr;
5508 if (fExt
.inlineDisplay
!= nullptr)
5510 if (fExt
.inlineDisplay
->render
!= nullptr)
5512 pData
->hints
|= PLUGIN_HAS_INLINE_DISPLAY
;
5513 pData
->setCanDeleteLib(false);
5517 fExt
.inlineDisplay
= nullptr;
5521 if (fExt
.midnam
!= nullptr && fExt
.midnam
->midnam
== nullptr)
5522 fExt
.midnam
= nullptr;
5525 CARLA_SAFE_ASSERT_RETURN(fLatencyIndex
== -1,);
5528 for (uint32_t i
=0, count
=fRdfDescriptor
->PortCount
; i
<count
; ++i
)
5530 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[i
].Types
);
5532 if (! LV2_IS_PORT_CONTROL(portTypes
))
5535 const CarlaScopedValueSetter
<int32_t> svs(iCtrl
, iCtrl
, iCtrl
+1);
5537 if (! LV2_IS_PORT_OUTPUT(portTypes
))
5540 const LV2_Property
portDesignation(fRdfDescriptor
->Ports
[i
].Designation
);
5542 if (! LV2_IS_PORT_DESIGNATION_LATENCY(portDesignation
))
5545 fLatencyIndex
= iCtrl
;
5550 // -------------------------------------------------------------------
5554 CARLA_SAFE_ASSERT_RETURN(fUI
.handle
!= nullptr,);
5555 CARLA_SAFE_ASSERT_RETURN(fUI
.descriptor
!= nullptr,);
5556 carla_debug("CarlaPluginLV2::updateUi()");
5558 // update midi program
5559 if (fExt
.uiprograms
!= nullptr && pData
->midiprog
.count
> 0 && pData
->midiprog
.current
>= 0)
5561 const MidiProgramData
& curData(pData
->midiprog
.getCurrent());
5562 fExt
.uiprograms
->select_program(fUI
.handle
, curData
.bank
, curData
.program
);
5565 // update control ports
5566 if (fUI
.descriptor
->port_event
!= nullptr)
5569 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
5571 value
= getParameterValue(i
);
5572 fUI
.descriptor
->port_event(fUI
.handle
, static_cast<uint32_t>(pData
->param
.data
[i
].rindex
), sizeof(float), kUridNull
, &value
);
5577 void inspectAtomForParameterChange(const LV2_Atom
* const atom
)
5579 if (atom
->type
!= kUridAtomBlank
&& atom
->type
!= kUridAtomObject
)
5582 const LV2_Atom_Object_Body
* const objbody
= (const LV2_Atom_Object_Body
*)(atom
+ 1);
5584 if (objbody
->otype
!= kUridPatchSet
)
5587 const LV2_Atom_URID
*property
= NULL
;
5588 const LV2_Atom_Bool
*carlaParam
= NULL
;
5589 const LV2_Atom
*value
= NULL
;
5591 lv2_atom_object_body_get(atom
->size
, objbody
,
5592 kUridCarlaParameterChange
, (const LV2_Atom
**)&carlaParam
,
5593 kUridPatchProperty
, (const LV2_Atom
**)&property
,
5594 kUridPatchValue
, &value
,
5597 if (carlaParam
!= nullptr && carlaParam
->body
!= 0)
5600 if (property
== nullptr || value
== nullptr)
5603 switch (value
->type
)
5607 //case kUridAtomLong:
5608 case kUridAtomFloat
:
5609 case kUridAtomDouble
:
5615 uint32_t parameterId
;
5616 if (! getParameterIndexForURID(property
->body
, parameterId
))
5619 const uint8_t* const vbody
= (const uint8_t*)(value
+ 1);
5622 switch (value
->type
)
5625 rvalue
= *(const int32_t*)vbody
!= 0 ? 1.0f
: 0.0f
;
5628 rvalue
= static_cast<float>(*(const int32_t*)vbody
);
5632 rvalue = *(int64_t*)vbody;
5635 case kUridAtomFloat
:
5636 rvalue
= *(const float*)vbody
;
5638 case kUridAtomDouble
:
5639 rvalue
= static_cast<float>(*(const double*)vbody
);
5646 rvalue
= pData
->param
.getFixedValue(parameterId
, rvalue
);
5647 fParamBuffers
[parameterId
] = rvalue
;
5649 CarlaPlugin::setParameterValue(parameterId
, rvalue
, false, true, true);
5652 bool getParameterIndexForURI(const char* const uri
, uint32_t& parameterId
) noexcept
5654 parameterId
= UINT32_MAX
;
5656 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
5658 const LV2_RDF_Parameter
& rdfParam(fRdfDescriptor
->Parameters
[i
]);
5660 switch (rdfParam
.Type
)
5662 case LV2_PARAMETER_TYPE_BOOL
:
5663 case LV2_PARAMETER_TYPE_INT
:
5664 // case LV2_PARAMETER_TYPE_LONG:
5665 case LV2_PARAMETER_TYPE_FLOAT
:
5666 case LV2_PARAMETER_TYPE_DOUBLE
:
5672 if (std::strcmp(rdfParam
.URI
, uri
) == 0)
5674 const int32_t rindex
= static_cast<int32_t>(fRdfDescriptor
->PortCount
+ i
);
5676 for (uint32_t j
=0; j
< pData
->param
.count
; ++j
)
5678 if (pData
->param
.data
[j
].rindex
== rindex
)
5688 return (parameterId
!= UINT32_MAX
);
5691 bool getParameterIndexForURID(const LV2_URID urid
, uint32_t& parameterId
) noexcept
5693 parameterId
= UINT32_MAX
;
5695 if (urid
>= fCustomURIDs
.size())
5698 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
5700 const LV2_RDF_Parameter
& rdfParam(fRdfDescriptor
->Parameters
[i
]);
5702 switch (rdfParam
.Type
)
5704 case LV2_PARAMETER_TYPE_BOOL
:
5705 case LV2_PARAMETER_TYPE_INT
:
5706 // case LV2_PARAMETER_TYPE_LONG:
5707 case LV2_PARAMETER_TYPE_FLOAT
:
5708 case LV2_PARAMETER_TYPE_DOUBLE
:
5714 const std::string
& uri(fCustomURIDs
[urid
]);
5716 if (uri
!= rdfParam
.URI
)
5719 const int32_t rindex
= static_cast<int32_t>(fRdfDescriptor
->PortCount
+ i
);
5721 for (uint32_t j
=0; j
< pData
->param
.count
; ++j
)
5723 if (pData
->param
.data
[j
].rindex
== rindex
)
5732 return (parameterId
!= UINT32_MAX
);
5735 // -------------------------------------------------------------------
5737 LV2_URID
getCustomURID(const char* const uri
)
5739 CARLA_SAFE_ASSERT_RETURN(uri
!= nullptr && uri
[0] != '\0', kUridNull
);
5740 carla_debug("CarlaPluginLV2::getCustomURID(\"%s\")", uri
);
5742 const std::string
s_uri(uri
);
5743 const std::ptrdiff_t s_pos(std::find(fCustomURIDs
.begin(), fCustomURIDs
.end(), s_uri
) - fCustomURIDs
.begin());
5745 if (s_pos
<= 0 || s_pos
>= INT32_MAX
)
5748 const LV2_URID urid
= static_cast<LV2_URID
>(s_pos
);
5749 const LV2_URID uriCount
= static_cast<LV2_URID
>(fCustomURIDs
.size());
5751 if (urid
< uriCount
)
5754 CARLA_SAFE_ASSERT(urid
== uriCount
);
5756 fCustomURIDs
.push_back(uri
);
5758 #ifndef LV2_UIS_ONLY_INPROCESS
5759 if (fUI
.type
== UI::TYPE_BRIDGE
&& fPipeServer
.isPipeRunning())
5760 fPipeServer
.writeLv2UridMessage(urid
, uri
);
5766 const char* getCustomURIDString(const LV2_URID urid
) const noexcept
5768 CARLA_SAFE_ASSERT_RETURN(urid
!= kUridNull
, kUnmapFallback
);
5769 CARLA_SAFE_ASSERT_RETURN(urid
< fCustomURIDs
.size(), kUnmapFallback
);
5770 carla_debug("CarlaPluginLV2::getCustomURIString(%i)", urid
);
5772 return fCustomURIDs
[urid
].c_str();
5775 // -------------------------------------------------------------------
5777 void handleProgramChanged(const int32_t index
)
5779 CARLA_SAFE_ASSERT_RETURN(index
>= -1,);
5780 carla_debug("CarlaPluginLV2::handleProgramChanged(%i)", index
);
5784 const ScopedSingleProcessLocker
spl(this, true);
5785 return reloadPrograms(false);
5788 if (index
< static_cast<int32_t>(pData
->midiprog
.count
) && fExt
.programs
!= nullptr && fExt
.programs
->get_program
!= nullptr)
5790 if (const LV2_Program_Descriptor
* const progDesc
= fExt
.programs
->get_program(fHandle
, static_cast<uint32_t>(index
)))
5792 CARLA_SAFE_ASSERT_RETURN(progDesc
->name
!= nullptr,);
5794 if (pData
->midiprog
.data
[index
].name
!= nullptr)
5795 delete[] pData
->midiprog
.data
[index
].name
;
5797 pData
->midiprog
.data
[index
].name
= carla_strdup(progDesc
->name
);
5799 if (index
== pData
->midiprog
.current
)
5800 pData
->engine
->callback(true, true, ENGINE_CALLBACK_UPDATE
, pData
->id
, 0, 0, 0, 0.0, nullptr);
5802 pData
->engine
->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS
, pData
->id
, 0, 0, 0, 0.0, nullptr);
5807 // -------------------------------------------------------------------
5809 LV2_Resize_Port_Status
handleResizePort(const uint32_t index
, const size_t size
)
5811 CARLA_SAFE_ASSERT_RETURN(size
> 0, LV2_RESIZE_PORT_ERR_UNKNOWN
);
5812 carla_debug("CarlaPluginLV2::handleResizePort(%i, " P_SIZE
")", index
, size
);
5815 return LV2_RESIZE_PORT_ERR_NO_SPACE
;
5819 // -------------------------------------------------------------------
5821 char* handleStateMapToAbstractPath(const bool temporary
, const char* const absolutePath
) const
5823 // may already be an abstract path
5824 if (! File::isAbsolutePath(absolutePath
))
5825 return strdup(absolutePath
);
5827 File projectDir
, targetDir
;
5829 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5830 if (const char* const projFolder
= pData
->engine
->getCurrentProjectFolder())
5831 projectDir
= projFolder
;
5834 projectDir
= File::getCurrentWorkingDirectory();
5836 if (projectDir
.isNull())
5838 carla_stdout("Project directory not set, cannot map absolutePath %s", absolutePath
);
5842 CarlaString
basedir(pData
->engine
->getName());
5847 targetDir
= projectDir
.getChildFile(basedir
)
5848 .getChildFile(getName());
5850 if (! targetDir
.exists())
5851 targetDir
.createDirectory();
5853 const File
wabsolutePath(absolutePath
);
5855 // we may be saving to non-tmp path, let's check
5858 const File tmpDir
= projectDir
.getChildFile(basedir
+ ".tmp")
5859 .getChildFile(getName());
5861 if (wabsolutePath
.getFullPathName().startsWith(tmpDir
.getFullPathName()))
5863 // gotcha, the temporary path is now the real one
5866 else if (! wabsolutePath
.getFullPathName().startsWith(targetDir
.getFullPathName()))
5868 // seems like a normal save, let's be nice and put a symlink
5869 const water::String
abstractFilename(wabsolutePath
.getFileName());
5870 const File
targetPath(targetDir
.getChildFile(abstractFilename
.toRawUTF8()));
5872 wabsolutePath
.createSymbolicLink(targetPath
, true);
5874 carla_stdout("Creating symlink for '%s' in '%s'", absolutePath
, targetDir
.getFullPathName().toRawUTF8());
5875 return strdup(abstractFilename
.toRawUTF8());
5879 carla_stdout("Mapping absolutePath '%s' relative to targetDir '%s'",
5880 absolutePath
, targetDir
.getFullPathName().toRawUTF8());
5882 return strdup(wabsolutePath
.getRelativePathFrom(targetDir
).toRawUTF8());
5885 File
handleStateMapToAbsolutePath(const bool createDirIfNeeded
,
5886 const bool symlinkIfNeeded
,
5887 const bool temporary
,
5888 const char* const abstractPath
) const
5890 File targetDir
, targetPath
;
5892 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
5893 if (const char* const projFolder
= pData
->engine
->getCurrentProjectFolder())
5894 targetDir
= projFolder
;
5897 targetDir
= File::getCurrentWorkingDirectory();
5899 if (targetDir
.isNull())
5901 carla_stdout("Project directory not set, cannot map abstractPath '%s'", abstractPath
);
5905 CarlaString
basedir(pData
->engine
->getName());
5910 targetDir
= targetDir
.getChildFile(basedir
)
5911 .getChildFile(getName());
5913 if (createDirIfNeeded
&& ! targetDir
.exists())
5914 targetDir
.createDirectory();
5916 if (File::isAbsolutePath(abstractPath
))
5918 File
wabstractPath(abstractPath
);
5919 targetPath
= targetDir
.getChildFile(wabstractPath
.getFileName().toRawUTF8());
5921 if (symlinkIfNeeded
)
5923 carla_stdout("Creating symlink for '%s' in '%s'",
5924 abstractPath
, targetDir
.getFullPathName().toRawUTF8());
5925 wabstractPath
.createSymbolicLink(targetPath
, true);
5930 targetPath
= targetDir
.getChildFile(abstractPath
);
5931 targetDir
= targetPath
.getParentDirectory();
5933 if (createDirIfNeeded
&& ! targetDir
.exists())
5934 targetDir
.createDirectory();
5937 if (std::strcmp(abstractPath
, ".") != 0)
5938 carla_stdout("Mapping abstractPath '%s' relative to targetDir '%s'",
5939 abstractPath
, targetDir
.getFullPathName().toRawUTF8());
5944 LV2_State_Status
handleStateStore(const uint32_t key
, const void* const value
, const size_t size
, const uint32_t type
, const uint32_t flags
)
5946 CARLA_SAFE_ASSERT_RETURN(key
!= kUridNull
, LV2_STATE_ERR_NO_PROPERTY
);
5947 CARLA_SAFE_ASSERT_RETURN(value
!= nullptr, LV2_STATE_ERR_NO_PROPERTY
);
5948 CARLA_SAFE_ASSERT_RETURN(size
> 0, LV2_STATE_ERR_NO_PROPERTY
);
5949 CARLA_SAFE_ASSERT_RETURN(type
!= kUridNull
, LV2_STATE_ERR_BAD_TYPE
);
5951 // FIXME linuxsampler does not set POD flag
5952 // CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
5954 carla_debug("CarlaPluginLV2::handleStateStore(%i:\"%s\", %p, " P_SIZE
", %i:\"%s\", %i)",
5955 key
, carla_lv2_urid_unmap(this, key
), value
, size
, type
, carla_lv2_urid_unmap(this, type
), flags
);
5957 const char* const skey(carla_lv2_urid_unmap(this, key
));
5958 const char* const stype(carla_lv2_urid_unmap(this, type
));
5960 CARLA_SAFE_ASSERT_RETURN(skey
!= nullptr && skey
!= kUnmapFallback
, LV2_STATE_ERR_BAD_TYPE
);
5961 CARLA_SAFE_ASSERT_RETURN(stype
!= nullptr && stype
!= kUnmapFallback
, LV2_STATE_ERR_BAD_TYPE
);
5963 // Check if we already have this key
5964 for (LinkedList
<CustomData
>::Itenerator it
= pData
->custom
.begin2(); it
.valid(); it
.next())
5966 CustomData
& cData(it
.getValue(kCustomDataFallbackNC
));
5967 CARLA_SAFE_ASSERT_CONTINUE(cData
.isValid());
5969 if (std::strcmp(cData
.key
, skey
) == 0)
5972 delete[] cData
.value
;
5974 if (type
== kUridAtomString
|| type
== kUridAtomPath
)
5975 cData
.value
= carla_strdup((const char*)value
);
5977 cData
.value
= CarlaString::asBase64(value
, size
).dup();
5979 return LV2_STATE_SUCCESS
;
5983 // Otherwise store it
5985 newData
.type
= carla_strdup(stype
);
5986 newData
.key
= carla_strdup(skey
);
5988 if (type
== kUridAtomString
|| type
== kUridAtomPath
)
5989 newData
.value
= carla_strdup((const char*)value
);
5991 newData
.value
= CarlaString::asBase64(value
, size
).dup();
5993 pData
->custom
.append(newData
);
5995 return LV2_STATE_SUCCESS
;
6001 const void* handleStateRetrieve(const uint32_t key
, size_t* const size
, uint32_t* const type
, uint32_t* const flags
)
6003 CARLA_SAFE_ASSERT_RETURN(key
!= kUridNull
, nullptr);
6004 CARLA_SAFE_ASSERT_RETURN(size
!= nullptr, nullptr);
6005 CARLA_SAFE_ASSERT_RETURN(type
!= nullptr, nullptr);
6006 CARLA_SAFE_ASSERT_RETURN(flags
!= nullptr, nullptr);
6007 carla_debug("CarlaPluginLV2::handleStateRetrieve(%i, %p, %p, %p)", key
, size
, type
, flags
);
6009 const char* const skey(carla_lv2_urid_unmap(this, key
));
6010 CARLA_SAFE_ASSERT_RETURN(skey
!= nullptr && skey
!= kUnmapFallback
, nullptr);
6012 const char* stype
= nullptr;
6013 const char* stringData
= nullptr;
6015 for (LinkedList
<CustomData
>::Itenerator it
= pData
->custom
.begin2(); it
.valid(); it
.next())
6017 const CustomData
& cData(it
.getValue(kCustomDataFallback
));
6018 CARLA_SAFE_ASSERT_CONTINUE(cData
.isValid());
6020 if (std::strcmp(cData
.key
, skey
) == 0)
6023 stringData
= cData
.value
;
6028 if (stype
== nullptr || stringData
== nullptr)
6030 carla_stderr("Plugin requested value for '%s' which is not available", skey
);
6031 *size
= *type
= *flags
= 0;
6035 *type
= carla_lv2_urid_map(this, stype
);
6036 *flags
= LV2_STATE_IS_POD
;
6038 if (*type
== kUridAtomString
|| *type
== kUridAtomPath
)
6040 *size
= std::strlen(stringData
);
6044 if (fLastStateChunk
!= nullptr)
6046 std::free(fLastStateChunk
);
6047 fLastStateChunk
= nullptr;
6050 std::vector
<uint8_t> chunk(carla_getChunkFromBase64String(stringData
));
6051 CARLA_SAFE_ASSERT_RETURN(chunk
.size() > 0, nullptr);
6053 fLastStateChunk
= std::malloc(chunk
.size());
6054 CARLA_SAFE_ASSERT_RETURN(fLastStateChunk
!= nullptr, nullptr);
6056 #ifdef CARLA_PROPER_CPP11_SUPPORT
6057 std::memcpy(fLastStateChunk
, chunk
.data(), chunk
.size());
6059 std::memcpy(fLastStateChunk
, &chunk
.front(), chunk
.size());
6062 *size
= chunk
.size();
6063 return fLastStateChunk
;
6066 // -------------------------------------------------------------------
6068 LV2_Worker_Status
handleWorkerSchedule(const uint32_t size
, const void* const data
)
6070 CARLA_SAFE_ASSERT_RETURN(fExt
.worker
!= nullptr && fExt
.worker
->work
!= nullptr, LV2_WORKER_ERR_UNKNOWN
);
6071 CARLA_SAFE_ASSERT_RETURN(fEventsIn
.ctrl
!= nullptr, LV2_WORKER_ERR_UNKNOWN
);
6072 carla_debug("CarlaPluginLV2::handleWorkerSchedule(%i, %p)", size
, data
);
6074 if (pData
->engine
->isOffline())
6076 fExt
.worker
->work(fHandle
, carla_lv2_worker_respond
, this, size
, data
);
6077 return LV2_WORKER_SUCCESS
;
6082 atom
.type
= kUridCarlaAtomWorkerIn
;
6084 return fAtomBufferWorkerIn
.putChunk(&atom
, data
, fEventsOut
.ctrlIndex
) ? LV2_WORKER_SUCCESS
: LV2_WORKER_ERR_NO_SPACE
;
6087 LV2_Worker_Status
handleWorkerRespond(const uint32_t size
, const void* const data
)
6089 CARLA_SAFE_ASSERT_RETURN(fExt
.worker
!= nullptr && fExt
.worker
->work_response
!= nullptr, LV2_WORKER_ERR_UNKNOWN
);
6090 carla_debug("CarlaPluginLV2::handleWorkerRespond(%i, %p)", size
, data
);
6094 atom
.type
= kUridCarlaAtomWorkerResp
;
6096 return fAtomBufferWorkerResp
.putChunk(&atom
, data
, fEventsIn
.ctrlIndex
) ? LV2_WORKER_SUCCESS
: LV2_WORKER_ERR_NO_SPACE
;
6099 // -------------------------------------------------------------------
6101 void handleInlineDisplayQueueRedraw()
6103 switch (pData
->engine
->getProccessMode())
6105 case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
:
6106 case ENGINE_PROCESS_MODE_PATCHBAY
:
6107 fInlineDisplayNeedsRedraw
= true;
6114 const LV2_Inline_Display_Image_Surface
* renderInlineDisplay(const uint32_t width
, const uint32_t height
) const
6116 CARLA_SAFE_ASSERT_RETURN(fExt
.inlineDisplay
!= nullptr && fExt
.inlineDisplay
->render
!= nullptr, nullptr);
6117 CARLA_SAFE_ASSERT_RETURN(width
> 0, nullptr);
6118 CARLA_SAFE_ASSERT_RETURN(height
> 0, nullptr);
6120 return fExt
.inlineDisplay
->render(fHandle
, width
, height
);
6123 // -------------------------------------------------------------------
6125 void handleMidnamUpdate()
6127 CARLA_SAFE_ASSERT_RETURN(fExt
.midnam
!= nullptr,);
6129 if (fEventsIn
.ctrl
== nullptr)
6132 char* const midnam
= fExt
.midnam
->midnam(fHandle
);
6133 CARLA_SAFE_ASSERT_RETURN(midnam
!= nullptr,);
6135 fEventsIn
.ctrl
->port
->setMetaData("http://www.midi.org/dtds/MIDINameDocument10.dtd", midnam
, "text/xml");
6137 if (fExt
.midnam
->free
!= nullptr)
6138 fExt
.midnam
->free(midnam
);
6141 // -------------------------------------------------------------------
6143 LV2_ControlInputPort_Change_Status
handleCtrlInPortChangeReq(const uint32_t rindex
, const float value
)
6145 CARLA_SAFE_ASSERT_RETURN(fParamBuffers
!= nullptr, LV2_CONTROL_INPUT_PORT_CHANGE_ERR_UNKNOWN
);
6147 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
6149 if (pData
->param
.data
[i
].rindex
!= static_cast<int32_t>(rindex
))
6152 const uint32_t index
= i
;
6153 const float fixedValue
= pData
->param
.getFixedValue(index
, value
);
6154 fParamBuffers
[index
] = fixedValue
;
6156 CarlaPlugin::setParameterValueRT(index
, fixedValue
, 0, true);
6157 return LV2_CONTROL_INPUT_PORT_CHANGE_SUCCESS
;
6160 return LV2_CONTROL_INPUT_PORT_CHANGE_ERR_INVALID_INDEX
;
6163 // -------------------------------------------------------------------
6165 void handleExternalUIClosed()
6167 CARLA_SAFE_ASSERT_RETURN(fUI
.type
== UI::TYPE_EXTERNAL
,);
6168 carla_debug("CarlaPluginLV2::handleExternalUIClosed()");
6170 fNeedsUiClose
= true;
6173 void handlePluginUIClosed() override
6175 CARLA_SAFE_ASSERT_RETURN(fUI
.type
== UI::TYPE_EMBED
,);
6176 CARLA_SAFE_ASSERT_RETURN(fUI
.window
!= nullptr,);
6177 carla_debug("CarlaPluginLV2::handlePluginUIClosed()");
6179 fNeedsUiClose
= true;
6182 void handlePluginUIResized(const uint width
, const uint height
) override
6184 CARLA_SAFE_ASSERT_RETURN(fUI
.type
== UI::TYPE_EMBED
,);
6185 CARLA_SAFE_ASSERT_RETURN(fUI
.window
!= nullptr,);
6186 carla_debug("CarlaPluginLV2::handlePluginUIResized(%u, %u)", width
, height
);
6188 if (fUI
.handle
!= nullptr && fExt
.uiresize
!= nullptr)
6189 fExt
.uiresize
->ui_resize(fUI
.handle
, static_cast<int>(width
), static_cast<int>(height
));
6192 // -------------------------------------------------------------------
6194 uint32_t handleUIPortMap(const char* const symbol
) const noexcept
6196 CARLA_SAFE_ASSERT_RETURN(symbol
!= nullptr && symbol
[0] != '\0', LV2UI_INVALID_PORT_INDEX
);
6197 carla_debug("CarlaPluginLV2::handleUIPortMap(\"%s\")", symbol
);
6199 for (uint32_t i
=0; i
< fRdfDescriptor
->PortCount
; ++i
)
6201 if (std::strcmp(fRdfDescriptor
->Ports
[i
].Symbol
, symbol
) == 0)
6205 return LV2UI_INVALID_PORT_INDEX
;
6208 LV2UI_Request_Value_Status
handleUIRequestValue(const LV2_URID key
,
6209 const LV2_URID type
,
6210 const LV2_Feature
* const* features
)
6212 CARLA_SAFE_ASSERT_RETURN(fUI
.type
!= UI::TYPE_NULL
, LV2UI_REQUEST_VALUE_ERR_UNKNOWN
);
6213 carla_debug("CarlaPluginLV2::handleUIRequestValue(%u, %u, %p)", key
, type
, features
);
6215 if (type
!= kUridAtomPath
)
6216 return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED
;
6218 const char* const uri
= getCustomURIDString(key
);
6219 CARLA_SAFE_ASSERT_RETURN(uri
!= nullptr && uri
!= kUnmapFallback
, LV2UI_REQUEST_VALUE_ERR_UNKNOWN
);
6221 // check if a file browser is already open
6222 if (fUI
.fileNeededForURI
!= nullptr || fUI
.fileBrowserOpen
)
6223 return LV2UI_REQUEST_VALUE_BUSY
;
6225 for (uint32_t i
=0; i
< fRdfDescriptor
->ParameterCount
; ++i
)
6227 if (fRdfDescriptor
->Parameters
[i
].Type
!= LV2_PARAMETER_TYPE_PATH
)
6229 if (std::strcmp(fRdfDescriptor
->Parameters
[i
].URI
, uri
) != 0)
6232 // TODO file browser filters, also store label to use for title
6233 fUI
.fileNeededForURI
= uri
;
6235 return LV2UI_REQUEST_VALUE_SUCCESS
;
6238 return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED
;
6244 int handleUIResize(const int width
, const int height
)
6246 CARLA_SAFE_ASSERT_RETURN(width
> 0, 1);
6247 CARLA_SAFE_ASSERT_RETURN(height
> 0, 1);
6248 carla_debug("CarlaPluginLV2::handleUIResize(%i, %i)", width
, height
);
6252 pData
->engine
->callback(true, true,
6253 ENGINE_CALLBACK_EMBED_UI_RESIZED
,
6254 pData
->id
, width
, height
,
6259 CARLA_SAFE_ASSERT_RETURN(fUI
.window
!= nullptr, 1);
6260 fUI
.window
->setSize(static_cast<uint
>(width
), static_cast<uint
>(height
), true, true);
6266 void handleUITouch(const uint32_t rindex
, const bool touch
)
6268 carla_debug("CarlaPluginLV2::handleUITouch(%u, %s)", rindex
, bool2str(touch
));
6270 uint32_t index
= LV2UI_INVALID_PORT_INDEX
;
6272 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
6274 if (pData
->param
.data
[i
].rindex
!= static_cast<int32_t>(rindex
))
6280 CARLA_SAFE_ASSERT_RETURN(index
!= LV2UI_INVALID_PORT_INDEX
,);
6282 pData
->engine
->touchPluginParameter(pData
->id
, index
, touch
);
6285 void handleUIWrite(const uint32_t rindex
, const uint32_t bufferSize
, const uint32_t format
, const void* const buffer
)
6287 CARLA_SAFE_ASSERT_RETURN(buffer
!= nullptr,);
6288 CARLA_SAFE_ASSERT_RETURN(bufferSize
> 0,);
6289 carla_debug("CarlaPluginLV2::handleUIWrite(%i, %i, %i, %p)", rindex
, bufferSize
, format
, buffer
);
6291 uint32_t index
= LV2UI_INVALID_PORT_INDEX
;
6296 CARLA_SAFE_ASSERT_RETURN(rindex
< fRdfDescriptor
->PortCount
,);
6297 CARLA_SAFE_ASSERT_RETURN(bufferSize
== sizeof(float),);
6299 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
6301 if (pData
->param
.data
[i
].rindex
!= static_cast<int32_t>(rindex
))
6307 CARLA_SAFE_ASSERT_RETURN(index
!= LV2UI_INVALID_PORT_INDEX
,);
6309 const float value(*(const float*)buffer
);
6311 // check if we should feedback message back to UI
6312 bool sendGui
= false;
6314 if (const uint32_t notifCount
= fUI
.rdfDescriptor
->PortNotificationCount
)
6316 const char* const portSymbol
= fRdfDescriptor
->Ports
[rindex
].Symbol
;
6318 for (uint32_t i
=0; i
< notifCount
; ++i
)
6320 const LV2_RDF_UI_PortNotification
& portNotif(fUI
.rdfDescriptor
->PortNotifications
[i
]);
6322 if (portNotif
.Protocol
!= LV2_UI_PORT_PROTOCOL_FLOAT
)
6325 if (portNotif
.Symbol
!= nullptr)
6327 if (std::strcmp(portNotif
.Symbol
, portSymbol
) != 0)
6330 else if (portNotif
.Index
!= rindex
)
6340 setParameterValue(index
, value
, sendGui
, true, true);
6344 case kUridAtomTransferAtom
:
6345 case kUridAtomTransferEvent
: {
6346 CARLA_SAFE_ASSERT_RETURN(bufferSize
>= sizeof(LV2_Atom
),);
6348 const LV2_Atom
* const atom((const LV2_Atom
*)buffer
);
6350 // plugins sometimes fail on this, not good...
6351 const uint32_t totalSize
= lv2_atom_total_size(atom
);
6352 const uint32_t paddedSize
= lv2_atom_pad_size(totalSize
);
6354 if (bufferSize
!= totalSize
&& bufferSize
!= paddedSize
)
6355 carla_stderr2("Warning: LV2 UI sending atom with invalid size %u! size: %u, padded-size: %u",
6356 bufferSize
, totalSize
, paddedSize
);
6358 for (uint32_t i
=0; i
< fEventsIn
.count
; ++i
)
6360 if (fEventsIn
.data
[i
].rindex
!= rindex
)
6367 if (index
== LV2UI_INVALID_PORT_INDEX
)
6369 CARLA_SAFE_ASSERT(index
!= LV2UI_INVALID_PORT_INDEX
); // FIXME
6370 index
= fEventsIn
.ctrlIndex
;
6373 fAtomBufferEvIn
.put(atom
, index
);
6377 carla_stdout("CarlaPluginLV2::handleUIWrite(%i, %i, %i:\"%s\", %p) - unknown format",
6378 rindex
, bufferSize
, format
, carla_lv2_urid_unmap(this, format
), buffer
);
6383 void handleUIBridgeParameter(const char* const uri
, const float value
)
6385 CARLA_SAFE_ASSERT_RETURN(uri
!= nullptr,);
6386 carla_debug("CarlaPluginLV2::handleUIBridgeParameter(%s, %f)", uri
, static_cast<double>(value
));
6388 uint32_t parameterId
;
6390 if (getParameterIndexForURI(uri
, parameterId
))
6391 setParameterValue(parameterId
, value
, false, true, true);
6394 // -------------------------------------------------------------------
6396 void handleLilvSetPortValue(const char* const portSymbol
, const void* const value
, const uint32_t size
, const uint32_t type
)
6398 CARLA_SAFE_ASSERT_RETURN(portSymbol
!= nullptr && portSymbol
[0] != '\0',);
6399 CARLA_SAFE_ASSERT_RETURN(value
!= nullptr,);
6400 CARLA_SAFE_ASSERT_RETURN(size
> 0,);
6401 CARLA_SAFE_ASSERT_RETURN(type
!= kUridNull
,);
6402 carla_debug("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i)", portSymbol
, value
, size
, type
);
6404 int32_t rindex
= -1;
6406 for (uint32_t i
=0; i
< fRdfDescriptor
->PortCount
; ++i
)
6408 if (std::strcmp(fRdfDescriptor
->Ports
[i
].Symbol
, portSymbol
) == 0)
6410 rindex
= static_cast<int32_t>(i
);
6415 CARLA_SAFE_ASSERT_RETURN(rindex
>= 0,);
6422 CARLA_SAFE_ASSERT_RETURN(size
== sizeof(int32_t),);
6423 paramValue
= *(const int32_t*)value
!= 0 ? 1.0f
: 0.0f
;
6425 case kUridAtomDouble
:
6426 CARLA_SAFE_ASSERT_RETURN(size
== sizeof(double),);
6427 paramValue
= static_cast<float>((*(const double*)value
));
6429 case kUridAtomFloat
:
6430 CARLA_SAFE_ASSERT_RETURN(size
== sizeof(float),);
6431 paramValue
= *(const float*)value
;
6434 CARLA_SAFE_ASSERT_RETURN(size
== sizeof(int32_t),);
6435 paramValue
= static_cast<float>(*(const int32_t*)value
);
6438 CARLA_SAFE_ASSERT_RETURN(size
== sizeof(int64_t),);
6439 paramValue
= static_cast<float>(*(const int64_t*)value
);
6442 carla_stdout("CarlaPluginLV2::handleLilvSetPortValue(\"%s\", %p, %i, %i:\"%s\") - unknown type",
6443 portSymbol
, value
, size
, type
, carla_lv2_urid_unmap(this, type
));
6447 for (uint32_t i
=0; i
< pData
->param
.count
; ++i
)
6449 if (pData
->param
.data
[i
].rindex
== rindex
)
6451 setParameterValueRT(i
, paramValue
, 0, true);
6457 // -------------------------------------------------------------------
6459 void* getNativeHandle() const noexcept override
6464 const void* getNativeDescriptor() const noexcept override
6469 #ifndef LV2_UIS_ONLY_INPROCESS
6470 uintptr_t getUiBridgeProcessId() const noexcept override
6472 return fPipeServer
.isPipeRunning() ? fPipeServer
.getPID() : 0;
6476 // -------------------------------------------------------------------
6479 bool init(const CarlaPluginPtr plugin
,
6480 const char* const name
, const char* const uri
, const uint options
,
6481 const char*& needsArchBridge
)
6483 CARLA_SAFE_ASSERT_RETURN(pData
->engine
!= nullptr, false);
6485 // ---------------------------------------------------------------
6488 if (pData
->client
!= nullptr)
6490 pData
->engine
->setLastError("Plugin client is already registered");
6494 if (uri
== nullptr || uri
[0] == '\0')
6496 pData
->engine
->setLastError("null uri");
6500 const EngineOptions
& opts(pData
->engine
->getOptions());
6502 // ---------------------------------------------------------------
6503 // Init LV2 World if needed, sets LV2_PATH for lilv
6505 Lv2WorldClass
& lv2World(Lv2WorldClass::getInstance());
6507 if (opts
.pathLV2
!= nullptr && opts
.pathLV2
[0] != '\0')
6508 lv2World
.initIfNeeded(opts
.pathLV2
);
6509 else if (const char* const LV2_PATH
= std::getenv("LV2_PATH"))
6510 lv2World
.initIfNeeded(LV2_PATH
);
6512 lv2World
.initIfNeeded(LILV_DEFAULT_LV2_PATH
);
6514 // ---------------------------------------------------------------
6515 // get plugin from lv2_rdf (lilv)
6517 fRdfDescriptor
= lv2_rdf_new(uri
, true);
6519 if (fRdfDescriptor
== nullptr)
6521 pData
->engine
->setLastError("Failed to find the requested plugin");
6525 #ifdef ADAPT_FOR_APPLE_SILLICON
6526 // ---------------------------------------------------------------
6527 // check if we can open this binary, might need a bridge
6530 const CarlaMagic magic
;
6532 if (const char* const output
= magic
.getFileDescription(fRdfDescriptor
->Binary
))
6535 if (std::strstr(output
, "arm64") == nullptr && std::strstr(output
, "x86_64") != nullptr)
6536 needsArchBridge
= "x86_64";
6538 if (std::strstr(output
, "x86_64") == nullptr && std::strstr(output
, "arm64") != nullptr)
6539 needsArchBridge
= "arm64";
6541 if (needsArchBridge
!= nullptr)
6545 #endif // ADAPT_FOR_APPLE_SILLICON
6547 // ---------------------------------------------------------------
6551 // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
6552 removeFileFromQuarantine(fRdfDescriptor
->Binary
);
6555 if (! pData
->libOpen(fRdfDescriptor
->Binary
))
6557 pData
->engine
->setLastError(pData
->libError(fRdfDescriptor
->Binary
));
6561 // ---------------------------------------------------------------
6562 // try to get DLL main entry via new mode
6564 if (const LV2_Lib_Descriptor_Function libDescFn
= pData
->libSymbol
<LV2_Lib_Descriptor_Function
>("lv2_lib_descriptor"))
6566 // -----------------------------------------------------------
6567 // all ok, get lib descriptor
6569 const LV2_Lib_Descriptor
* const libDesc
= libDescFn(fRdfDescriptor
->Bundle
, nullptr);
6571 if (libDesc
== nullptr)
6573 pData
->engine
->setLastError("Could not find the LV2 Descriptor");
6577 // -----------------------------------------------------------
6578 // get descriptor that matches URI (new mode)
6581 while ((fDescriptor
= libDesc
->get_plugin(libDesc
->handle
, i
++)))
6583 if (std::strcmp(fDescriptor
->URI
, uri
) == 0)
6589 // -----------------------------------------------------------
6590 // get DLL main entry (old mode)
6592 const LV2_Descriptor_Function descFn
= pData
->libSymbol
<LV2_Descriptor_Function
>("lv2_descriptor");
6594 if (descFn
== nullptr)
6596 pData
->engine
->setLastError("Could not find the LV2 Descriptor in the plugin library");
6600 // -----------------------------------------------------------
6601 // get descriptor that matches URI (old mode)
6604 while ((fDescriptor
= descFn(i
++)))
6606 if (std::strcmp(fDescriptor
->URI
, uri
) == 0)
6611 if (fDescriptor
== nullptr)
6613 pData
->engine
->setLastError("Could not find the requested plugin URI in the plugin library");
6617 // ---------------------------------------------------------------
6618 // check supported port-types and features
6620 bool canContinue
= true;
6622 // Check supported ports
6623 for (uint32_t j
=0; j
< fRdfDescriptor
->PortCount
; ++j
)
6625 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[j
].Types
);
6627 if (! is_lv2_port_supported(portTypes
))
6629 if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor
->Ports
[j
].Properties
))
6631 pData
->engine
->setLastError("Plugin requires a port type that is not currently supported");
6632 canContinue
= false;
6638 // Check supported features
6639 for (uint32_t j
=0; j
< fRdfDescriptor
->FeatureCount
&& canContinue
; ++j
)
6641 const LV2_RDF_Feature
& feature(fRdfDescriptor
->Features
[j
]);
6643 if (std::strcmp(feature
.URI
, LV2_DATA_ACCESS_URI
) == 0 || std::strcmp(feature
.URI
, LV2_INSTANCE_ACCESS_URI
) == 0)
6645 carla_stderr("Plugin DSP wants UI feature '%s', ignoring this", feature
.URI
);
6647 else if (std::strcmp(feature
.URI
, LV2_BUF_SIZE__fixedBlockLength
) == 0)
6649 fNeedsFixedBuffers
= true;
6651 else if (std::strcmp(feature
.URI
, LV2_PORT_PROPS__supportsStrictBounds
) == 0)
6653 fStrictBounds
= feature
.Required
? 1 : 0;
6655 else if (std::strcmp(feature
.URI
, LV2_STATE__loadDefaultState
) == 0)
6657 fHasLoadDefaultState
= true;
6659 else if (std::strcmp(feature
.URI
, LV2_STATE__threadSafeRestore
) == 0)
6661 fHasThreadSafeRestore
= true;
6663 else if (feature
.Required
&& ! is_lv2_feature_supported(feature
.URI
))
6665 CarlaString
msg("Plugin wants a feature that is not supported:\n");
6668 canContinue
= false;
6669 pData
->engine
->setLastError(msg
);
6676 // error already set
6680 if (fNeedsFixedBuffers
&& ! pData
->engine
->usesConstantBufferSize())
6682 pData
->engine
->setLastError("Cannot use this plugin under the current engine.\n"
6683 "The plugin requires a fixed block size which is not possible right now.");
6687 // ---------------------------------------------------------------
6690 if (std::strncmp(fDescriptor
->URI
, "http://distrho.sf.net/", 22) == 0)
6691 pData
->iconName
= carla_strdup_safe("distrho");
6693 // ---------------------------------------------------------------
6696 if (name
!= nullptr && name
[0] != '\0')
6697 pData
->name
= pData
->engine
->getUniquePluginName(name
);
6699 pData
->name
= pData
->engine
->getUniquePluginName(fRdfDescriptor
->Name
);
6701 // ---------------------------------------------------------------
6704 pData
->client
= pData
->engine
->addClient(plugin
);
6706 if (pData
->client
== nullptr || ! pData
->client
->isOk())
6708 pData
->engine
->setLastError("Failed to register plugin client");
6712 // ---------------------------------------------------------------
6713 // initialize options
6715 const int bufferSize
= static_cast<int>(pData
->engine
->getBufferSize());
6717 fLv2Options
.minBufferSize
= fNeedsFixedBuffers
? bufferSize
: 1;
6718 fLv2Options
.maxBufferSize
= bufferSize
;
6719 fLv2Options
.nominalBufferSize
= bufferSize
;
6720 fLv2Options
.sampleRate
= static_cast<float>(pData
->engine
->getSampleRate());
6721 fLv2Options
.transientWinId
= static_cast<int64_t>(opts
.frontendWinId
);
6723 uint32_t eventBufferSize
= MAX_DEFAULT_BUFFER_SIZE
;
6725 for (uint32_t j
=0; j
< fRdfDescriptor
->PortCount
; ++j
)
6727 const LV2_Property
portTypes(fRdfDescriptor
->Ports
[j
].Types
);
6729 if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes
) || LV2_IS_PORT_EVENT(portTypes
) || LV2_IS_PORT_MIDI_LL(portTypes
))
6731 if (fRdfDescriptor
->Ports
[j
].MinimumSize
> eventBufferSize
)
6732 eventBufferSize
= fRdfDescriptor
->Ports
[j
].MinimumSize
;
6736 fLv2Options
.sequenceSize
= static_cast<int>(eventBufferSize
);
6738 fLv2Options
.bgColor
= opts
.bgColor
;
6739 fLv2Options
.fgColor
= opts
.fgColor
;
6740 fLv2Options
.uiScale
= opts
.uiScale
;
6742 // ---------------------------------------------------------------
6743 // initialize features (part 1)
6745 LV2_Event_Feature
* const eventFt
= new LV2_Event_Feature
;
6746 eventFt
->callback_data
= this;
6747 eventFt
->lv2_event_ref
= carla_lv2_event_ref
;
6748 eventFt
->lv2_event_unref
= carla_lv2_event_unref
;
6750 LV2_Log_Log
* const logFt
= new LV2_Log_Log
;
6751 logFt
->handle
= this;
6752 logFt
->printf
= carla_lv2_log_printf
;
6753 logFt
->vprintf
= carla_lv2_log_vprintf
;
6755 LV2_State_Free_Path
* const stateFreePathFt
= new LV2_State_Free_Path
;
6756 stateFreePathFt
->handle
= this;
6757 stateFreePathFt
->free_path
= carla_lv2_state_free_path
;
6759 LV2_State_Make_Path
* const stateMakePathFt
= new LV2_State_Make_Path
;
6760 stateMakePathFt
->handle
= this;
6761 stateMakePathFt
->path
= carla_lv2_state_make_path_tmp
;
6763 LV2_State_Map_Path
* const stateMapPathFt
= new LV2_State_Map_Path
;
6764 stateMapPathFt
->handle
= this;
6765 stateMapPathFt
->abstract_path
= carla_lv2_state_map_to_abstract_path_tmp
;
6766 stateMapPathFt
->absolute_path
= carla_lv2_state_map_to_absolute_path_tmp
;
6768 LV2_Programs_Host
* const programsFt
= new LV2_Programs_Host
;
6769 programsFt
->handle
= this;
6770 programsFt
->program_changed
= carla_lv2_program_changed
;
6772 LV2_Resize_Port_Resize
* const rsPortFt
= new LV2_Resize_Port_Resize
;
6773 rsPortFt
->data
= this;
6774 rsPortFt
->resize
= carla_lv2_resize_port
;
6776 LV2_RtMemPool_Pool
* const rtMemPoolFt
= new LV2_RtMemPool_Pool
;
6777 lv2_rtmempool_init(rtMemPoolFt
);
6779 LV2_RtMemPool_Pool_Deprecated
* const rtMemPoolOldFt
= new LV2_RtMemPool_Pool_Deprecated
;
6780 lv2_rtmempool_init_deprecated(rtMemPoolOldFt
);
6782 LV2_URI_Map_Feature
* const uriMapFt
= new LV2_URI_Map_Feature
;
6783 uriMapFt
->callback_data
= this;
6784 uriMapFt
->uri_to_id
= carla_lv2_uri_to_id
;
6786 LV2_URID_Map
* const uridMapFt
= new LV2_URID_Map
;
6787 uridMapFt
->handle
= this;
6788 uridMapFt
->map
= carla_lv2_urid_map
;
6790 LV2_URID_Unmap
* const uridUnmapFt
= new LV2_URID_Unmap
;
6791 uridUnmapFt
->handle
= this;
6792 uridUnmapFt
->unmap
= carla_lv2_urid_unmap
;
6794 LV2_Worker_Schedule
* const workerFt
= new LV2_Worker_Schedule
;
6795 workerFt
->handle
= this;
6796 workerFt
->schedule_work
= carla_lv2_worker_schedule
;
6798 LV2_Inline_Display
* const inlineDisplay
= new LV2_Inline_Display
;
6799 inlineDisplay
->handle
= this;
6800 inlineDisplay
->queue_draw
= carla_lv2_inline_display_queue_draw
;
6802 LV2_Midnam
* const midnam
= new LV2_Midnam
;
6803 midnam
->handle
= this;
6804 midnam
->update
= carla_lv2_midnam_update
;
6806 LV2_ControlInputPort_Change_Request
* const portChangeReq
= new LV2_ControlInputPort_Change_Request
;
6807 portChangeReq
->handle
= this;
6808 portChangeReq
->request_change
= carla_lv2_ctrl_in_port_change_req
;
6810 // ---------------------------------------------------------------
6811 // initialize features (part 2)
6813 for (uint32_t j
=0; j
< kFeatureCountPlugin
; ++j
)
6814 fFeatures
[j
] = new LV2_Feature
;
6816 fFeatures
[kFeatureIdBufSizeBounded
]->URI
= LV2_BUF_SIZE__boundedBlockLength
;
6817 fFeatures
[kFeatureIdBufSizeBounded
]->data
= nullptr;
6819 fFeatures
[kFeatureIdBufSizeFixed
]->URI
= fNeedsFixedBuffers
6820 ? LV2_BUF_SIZE__fixedBlockLength
6821 : LV2_BUF_SIZE__boundedBlockLength
;
6822 fFeatures
[kFeatureIdBufSizeFixed
]->data
= nullptr;
6824 fFeatures
[kFeatureIdBufSizePowerOf2
]->URI
= LV2_BUF_SIZE__powerOf2BlockLength
;
6825 fFeatures
[kFeatureIdBufSizePowerOf2
]->data
= nullptr;
6827 fFeatures
[kFeatureIdEvent
]->URI
= LV2_EVENT_URI
;
6828 fFeatures
[kFeatureIdEvent
]->data
= eventFt
;
6830 fFeatures
[kFeatureIdHardRtCapable
]->URI
= LV2_CORE__hardRTCapable
;
6831 fFeatures
[kFeatureIdHardRtCapable
]->data
= nullptr;
6833 fFeatures
[kFeatureIdInPlaceBroken
]->URI
= LV2_CORE__inPlaceBroken
;
6834 fFeatures
[kFeatureIdInPlaceBroken
]->data
= nullptr;
6836 fFeatures
[kFeatureIdIsLive
]->URI
= LV2_CORE__isLive
;
6837 fFeatures
[kFeatureIdIsLive
]->data
= nullptr;
6839 fFeatures
[kFeatureIdLogs
]->URI
= LV2_LOG__log
;
6840 fFeatures
[kFeatureIdLogs
]->data
= logFt
;
6842 fFeatures
[kFeatureIdOptions
]->URI
= LV2_OPTIONS__options
;
6843 fFeatures
[kFeatureIdOptions
]->data
= fLv2Options
.opts
;
6845 fFeatures
[kFeatureIdPrograms
]->URI
= LV2_PROGRAMS__Host
;
6846 fFeatures
[kFeatureIdPrograms
]->data
= programsFt
;
6848 fFeatures
[kFeatureIdResizePort
]->URI
= LV2_RESIZE_PORT__resize
;
6849 fFeatures
[kFeatureIdResizePort
]->data
= rsPortFt
;
6851 fFeatures
[kFeatureIdRtMemPool
]->URI
= LV2_RTSAFE_MEMORY_POOL__Pool
;
6852 fFeatures
[kFeatureIdRtMemPool
]->data
= rtMemPoolFt
;
6854 fFeatures
[kFeatureIdRtMemPoolOld
]->URI
= LV2_RTSAFE_MEMORY_POOL_DEPRECATED_URI
;
6855 fFeatures
[kFeatureIdRtMemPoolOld
]->data
= rtMemPoolOldFt
;
6857 fFeatures
[kFeatureIdStateFreePath
]->URI
= LV2_STATE__freePath
;
6858 fFeatures
[kFeatureIdStateFreePath
]->data
= stateFreePathFt
;
6860 fFeatures
[kFeatureIdStateMakePath
]->URI
= LV2_STATE__makePath
;
6861 fFeatures
[kFeatureIdStateMakePath
]->data
= stateMakePathFt
;
6863 fFeatures
[kFeatureIdStateMapPath
]->URI
= LV2_STATE__mapPath
;
6864 fFeatures
[kFeatureIdStateMapPath
]->data
= stateMapPathFt
;
6866 fFeatures
[kFeatureIdStrictBounds
]->URI
= LV2_PORT_PROPS__supportsStrictBounds
;
6867 fFeatures
[kFeatureIdStrictBounds
]->data
= nullptr;
6869 fFeatures
[kFeatureIdUriMap
]->URI
= LV2_URI_MAP_URI
;
6870 fFeatures
[kFeatureIdUriMap
]->data
= uriMapFt
;
6872 fFeatures
[kFeatureIdUridMap
]->URI
= LV2_URID__map
;
6873 fFeatures
[kFeatureIdUridMap
]->data
= uridMapFt
;
6875 fFeatures
[kFeatureIdUridUnmap
]->URI
= LV2_URID__unmap
;
6876 fFeatures
[kFeatureIdUridUnmap
]->data
= uridUnmapFt
;
6878 fFeatures
[kFeatureIdWorker
]->URI
= LV2_WORKER__schedule
;
6879 fFeatures
[kFeatureIdWorker
]->data
= workerFt
;
6881 fFeatures
[kFeatureIdInlineDisplay
]->URI
= LV2_INLINEDISPLAY__queue_draw
;
6882 fFeatures
[kFeatureIdInlineDisplay
]->data
= inlineDisplay
;
6884 fFeatures
[kFeatureIdMidnam
]->URI
= LV2_MIDNAM__update
;
6885 fFeatures
[kFeatureIdMidnam
]->data
= midnam
;
6887 fFeatures
[kFeatureIdCtrlInPortChangeReq
]->URI
= LV2_CONTROL_INPUT_PORT_CHANGE_REQUEST_URI
;
6888 fFeatures
[kFeatureIdCtrlInPortChangeReq
]->data
= portChangeReq
;
6890 // ---------------------------------------------------------------
6891 // initialize features (part 3)
6893 LV2_State_Make_Path
* const stateMakePathFt2
= new LV2_State_Make_Path
;
6894 stateMakePathFt2
->handle
= this;
6895 stateMakePathFt2
->path
= carla_lv2_state_make_path_real
;
6897 LV2_State_Map_Path
* const stateMapPathFt2
= new LV2_State_Map_Path
;
6898 stateMapPathFt2
->handle
= this;
6899 stateMapPathFt2
->abstract_path
= carla_lv2_state_map_to_abstract_path_real
;
6900 stateMapPathFt2
->absolute_path
= carla_lv2_state_map_to_absolute_path_real
;
6902 for (uint32_t j
=0; j
< kStateFeatureCountAll
; ++j
)
6903 fStateFeatures
[j
] = new LV2_Feature
;
6905 fStateFeatures
[kStateFeatureIdFreePath
]->URI
= LV2_STATE__freePath
;
6906 fStateFeatures
[kStateFeatureIdFreePath
]->data
= stateFreePathFt
;
6908 fStateFeatures
[kStateFeatureIdMakePath
]->URI
= LV2_STATE__makePath
;
6909 fStateFeatures
[kStateFeatureIdMakePath
]->data
= stateMakePathFt2
;
6911 fStateFeatures
[kStateFeatureIdMapPath
]->URI
= LV2_STATE__mapPath
;
6912 fStateFeatures
[kStateFeatureIdMapPath
]->data
= stateMapPathFt2
;
6914 fStateFeatures
[kStateFeatureIdWorker
]->URI
= LV2_WORKER__schedule
;
6915 fStateFeatures
[kStateFeatureIdWorker
]->data
= workerFt
;
6917 // ---------------------------------------------------------------
6918 // initialize plugin
6921 fHandle
= fDescriptor
->instantiate(fDescriptor
, pData
->engine
->getSampleRate(), fRdfDescriptor
->Bundle
, fFeatures
);
6924 if (fHandle
== nullptr)
6926 pData
->engine
->setLastError("Plugin failed to initialize");
6930 recheckExtensions();
6932 // ---------------------------------------------------------------
6935 pData
->options
= 0x0;
6937 if (fLatencyIndex
>= 0 || getMidiOutCount() != 0 || fNeedsFixedBuffers
)
6938 pData
->options
|= PLUGIN_OPTION_FIXED_BUFFERS
;
6939 else if (options
& PLUGIN_OPTION_FIXED_BUFFERS
)
6940 pData
->options
|= PLUGIN_OPTION_FIXED_BUFFERS
;
6942 if (opts
.forceStereo
)
6943 pData
->options
|= PLUGIN_OPTION_FORCE_STEREO
;
6944 else if (options
& PLUGIN_OPTION_FORCE_STEREO
)
6945 pData
->options
|= PLUGIN_OPTION_FORCE_STEREO
;
6947 if (getMidiInCount() != 0)
6949 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_CONTROL_CHANGES
))
6950 pData
->options
|= PLUGIN_OPTION_SEND_CONTROL_CHANGES
;
6951 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE
))
6952 pData
->options
|= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE
;
6953 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH
))
6954 pData
->options
|= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH
;
6955 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_PITCHBEND
))
6956 pData
->options
|= PLUGIN_OPTION_SEND_PITCHBEND
;
6957 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_ALL_SOUND_OFF
))
6958 pData
->options
|= PLUGIN_OPTION_SEND_ALL_SOUND_OFF
;
6959 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_SEND_PROGRAM_CHANGES
))
6960 pData
->options
|= PLUGIN_OPTION_SEND_PROGRAM_CHANGES
;
6961 if (isPluginOptionInverseEnabled(options
, PLUGIN_OPTION_SKIP_SENDING_NOTES
))
6962 pData
->options
|= PLUGIN_OPTION_SKIP_SENDING_NOTES
;
6965 if (fExt
.programs
!= nullptr && (pData
->options
& PLUGIN_OPTION_SEND_PROGRAM_CHANGES
) == 0)
6967 if (isPluginOptionEnabled(options
, PLUGIN_OPTION_MAP_PROGRAM_CHANGES
))
6968 pData
->options
|= PLUGIN_OPTION_MAP_PROGRAM_CHANGES
;
6971 // ---------------------------------------------------------------
6974 if (fRdfDescriptor
->UICount
!= 0)
6980 (void)needsArchBridge
;
6983 // -------------------------------------------------------------------
6987 // ---------------------------------------------------------------
6988 // find the most appropriate ui
6990 int eQt4
, eQt5
, eGtk2
, eGtk3
, eCocoa
, eWindows
, eX11
, eMod
, iCocoa
, iWindows
, iX11
, iExt
, iFinal
;
6991 eQt4
= eQt5
= eGtk2
= eGtk3
= eCocoa
= eWindows
= eX11
= eMod
= iCocoa
= iWindows
= iX11
= iExt
= iFinal
= -1;
6993 #if defined(LV2_UIS_ONLY_BRIDGES)
6994 const bool preferUiBridges
= true;
6995 #elif defined(BUILD_BRIDGE)
6996 const bool preferUiBridges
= false;
6998 const bool preferUiBridges
= pData
->engine
->getOptions().preferUiBridges
;
7000 bool hasShowInterface
= false;
7002 for (uint32_t i
=0; i
< fRdfDescriptor
->UICount
; ++i
)
7004 CARLA_SAFE_ASSERT_CONTINUE(fRdfDescriptor
->UIs
[i
].URI
!= nullptr);
7006 const int ii(static_cast<int>(i
));
7008 switch (fRdfDescriptor
->UIs
[i
].Type
)
7011 if (isUiBridgeable(i
))
7015 if (isUiBridgeable(i
))
7019 if (isUiBridgeable(i
))
7023 if (isUiBridgeable(i
))
7028 if (isUiBridgeable(i
) && preferUiBridges
)
7034 case LV2_UI_WINDOWS
:
7035 if (isUiBridgeable(i
) && preferUiBridges
)
7041 if (isUiBridgeable(i
) && preferUiBridges
)
7045 case LV2_UI_EXTERNAL
:
7046 case LV2_UI_OLD_EXTERNAL
:
7061 else if (eGtk2
>= 0)
7063 else if (eGtk3
>= 0)
7066 else if (eCocoa
>= 0)
7070 else if (eWindows
>= 0)
7077 #ifndef LV2_UIS_ONLY_BRIDGES
7078 # ifdef CARLA_OS_MAC
7079 else if (iCocoa
>= 0)
7082 # ifdef CARLA_OS_WIN
7083 else if (iWindows
>= 0)
7094 #ifndef BUILD_BRIDGE
7098 // no suitable UI found, see if there's one which supports ui:showInterface
7099 for (uint32_t i
=0; i
< fRdfDescriptor
->UICount
&& ! hasShowInterface
; ++i
)
7101 LV2_RDF_UI
* const ui(&fRdfDescriptor
->UIs
[i
]);
7103 for (uint32_t j
=0; j
< ui
->ExtensionCount
; ++j
)
7105 CARLA_SAFE_ASSERT_CONTINUE(ui
->Extensions
[j
] != nullptr);
7107 if (std::strcmp(ui
->Extensions
[j
], LV2_UI__showInterface
) != 0)
7110 iFinal
= static_cast<int>(i
);
7111 hasShowInterface
= true;
7120 carla_stderr("Failed to find an appropriate LV2 UI for this plugin");
7124 // use MODGUI as last resort
7129 fUI
.rdfDescriptor
= &fRdfDescriptor
->UIs
[iFinal
];
7131 // ---------------------------------------------------------------
7132 // check supported ui features
7134 bool canContinue
= true;
7135 bool canDelete
= true;
7137 for (uint32_t i
=0; i
< fUI
.rdfDescriptor
->FeatureCount
; ++i
)
7139 const char* const uri(fUI
.rdfDescriptor
->Features
[i
].URI
);
7140 CARLA_SAFE_ASSERT_CONTINUE(uri
!= nullptr && uri
[0] != '\0');
7142 if (! is_lv2_ui_feature_supported(uri
))
7144 if (fUI
.rdfDescriptor
->Features
[i
].Required
)
7146 carla_stderr("Plugin UI requires a feature that is not supported:\n%s", uri
);
7147 canContinue
= false;
7151 carla_stderr("Plugin UI wants a feature that is not supported (ignored):\n%s", uri
);
7154 if (std::strcmp(uri
, LV2_UI__makeResident
) == 0 || std::strcmp(uri
, LV2_UI__makeSONameResident
) == 0)
7156 else if (std::strcmp(uri
, LV2_UI__requestValue
) == 0)
7157 pData
->hints
|= PLUGIN_NEEDS_UI_MAIN_THREAD
;
7162 fUI
.rdfDescriptor
= nullptr;
7166 // ---------------------------------------------------------------
7167 // initialize ui according to type
7169 const LV2_Property uiType
= fUI
.rdfDescriptor
->Type
;
7171 #ifndef LV2_UIS_ONLY_INPROCESS
7178 iFinal
== eWindows
||
7182 && ! hasShowInterface
7186 // -----------------------------------------------------------
7187 // initialize ui-bridge
7189 if (const char* const bridgeBinary
= getUiBridgeBinary(uiType
))
7191 carla_stdout("Will use UI-Bridge for '%s', binary: \"%s\"", pData
->name
, bridgeBinary
);
7193 CarlaString uiTitle
;
7195 if (pData
->uiTitle
.isNotEmpty())
7197 uiTitle
= pData
->uiTitle
;
7201 uiTitle
= pData
->name
;
7202 uiTitle
+= " (GUI)";
7205 fLv2Options
.windowTitle
= uiTitle
.releaseBufferPointer();
7207 fUI
.type
= UI::TYPE_BRIDGE
;
7208 fPipeServer
.setData(bridgeBinary
, fRdfDescriptor
->URI
, fUI
.rdfDescriptor
->URI
);
7210 delete[] bridgeBinary
;
7214 if (iFinal
== eQt4
|| iFinal
== eQt5
|| iFinal
== eGtk2
|| iFinal
== eGtk3
|| iFinal
== eMod
)
7216 carla_stderr2("Failed to find UI bridge binary for '%s', cannot use UI", pData
->name
);
7217 fUI
.rdfDescriptor
= nullptr;
7223 #ifdef LV2_UIS_ONLY_BRIDGES
7224 carla_stderr2("Failed to get an UI working, canBridge:%s", bool2str(isUiBridgeable(static_cast<uint32_t>(iFinal
))));
7225 fUI
.rdfDescriptor
= nullptr;
7229 // ---------------------------------------------------------------
7233 // Binary might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
7234 removeFileFromQuarantine(fUI
.rdfDescriptor
->Binary
);
7237 if (! pData
->uiLibOpen(fUI
.rdfDescriptor
->Binary
, canDelete
))
7239 carla_stderr2("Could not load UI library, error was:\n%s", pData
->libError(fUI
.rdfDescriptor
->Binary
));
7240 fUI
.rdfDescriptor
= nullptr;
7244 // ---------------------------------------------------------------
7245 // get UI DLL main entry
7247 LV2UI_DescriptorFunction uiDescFn
= pData
->uiLibSymbol
<LV2UI_DescriptorFunction
>("lv2ui_descriptor");
7249 if (uiDescFn
== nullptr)
7251 carla_stderr2("Could not find the LV2UI Descriptor in the UI library");
7252 pData
->uiLibClose();
7253 fUI
.rdfDescriptor
= nullptr;
7257 // ---------------------------------------------------------------
7258 // get UI descriptor that matches UI URI
7261 while ((fUI
.descriptor
= uiDescFn(i
++)))
7263 if (std::strcmp(fUI
.descriptor
->URI
, fUI
.rdfDescriptor
->URI
) == 0)
7267 if (fUI
.descriptor
== nullptr)
7269 carla_stderr2("Could not find the requested GUI in the plugin UI library");
7270 pData
->uiLibClose();
7271 fUI
.rdfDescriptor
= nullptr;
7275 // ---------------------------------------------------------------
7276 // check if ui is usable
7281 carla_stdout("Will use LV2 Show Interface for '%s'", pData
->name
);
7282 fUI
.type
= UI::TYPE_EMBED
;
7285 carla_stdout("Will use LV2 Qt4 UI for '%s', NOT!", pData
->name
);
7286 fUI
.type
= UI::TYPE_EMBED
;
7289 carla_stdout("Will use LV2 Qt5 UI for '%s', NOT!", pData
->name
);
7290 fUI
.type
= UI::TYPE_EMBED
;
7293 carla_stdout("Will use LV2 Gtk2 UI for '%s', NOT!", pData
->name
);
7294 fUI
.type
= UI::TYPE_EMBED
;
7297 carla_stdout("Will use LV2 Gtk3 UI for '%s', NOT!", pData
->name
);
7298 fUI
.type
= UI::TYPE_EMBED
;
7302 carla_stdout("Will use LV2 Cocoa UI for '%s'", pData
->name
);
7303 fUI
.type
= UI::TYPE_EMBED
;
7307 case LV2_UI_WINDOWS
:
7308 carla_stdout("Will use LV2 Windows UI for '%s'", pData
->name
);
7309 fUI
.type
= UI::TYPE_EMBED
;
7314 carla_stdout("Will use LV2 X11 UI for '%s'", pData
->name
);
7316 carla_stdout("Will use LV2 X11 UI for '%s', NOT!", pData
->name
);
7318 fUI
.type
= UI::TYPE_EMBED
;
7320 case LV2_UI_EXTERNAL
:
7321 case LV2_UI_OLD_EXTERNAL
:
7322 carla_stdout("Will use LV2 External UI for '%s'", pData
->name
);
7323 fUI
.type
= UI::TYPE_EXTERNAL
;
7327 if (fUI
.type
== UI::TYPE_NULL
)
7329 pData
->uiLibClose();
7330 fUI
.descriptor
= nullptr;
7331 fUI
.rdfDescriptor
= nullptr;
7335 // ---------------------------------------------------------------
7336 // initialize ui data
7339 CarlaString uiTitle
;
7341 if (pData
->uiTitle
.isNotEmpty())
7343 uiTitle
= pData
->uiTitle
;
7347 uiTitle
= pData
->name
;
7348 uiTitle
+= " (GUI)";
7351 fLv2Options
.windowTitle
= uiTitle
.releaseBufferPointer();
7354 fLv2Options
.opts
[CarlaPluginLV2Options::WindowTitle
].size
= (uint32_t)std::strlen(fLv2Options
.windowTitle
);
7355 fLv2Options
.opts
[CarlaPluginLV2Options::WindowTitle
].value
= fLv2Options
.windowTitle
;
7357 // ---------------------------------------------------------------
7358 // initialize ui features (part 1)
7360 LV2_Extension_Data_Feature
* const uiDataFt
= new LV2_Extension_Data_Feature
;
7361 uiDataFt
->data_access
= fDescriptor
->extension_data
;
7363 LV2UI_Port_Map
* const uiPortMapFt
= new LV2UI_Port_Map
;
7364 uiPortMapFt
->handle
= this;
7365 uiPortMapFt
->port_index
= carla_lv2_ui_port_map
;
7367 LV2UI_Request_Value
* const uiRequestValueFt
= new LV2UI_Request_Value
;
7368 uiRequestValueFt
->handle
= this;
7369 uiRequestValueFt
->request
= carla_lv2_ui_request_value
;
7371 LV2UI_Resize
* const uiResizeFt
= new LV2UI_Resize
;
7372 uiResizeFt
->handle
= this;
7373 uiResizeFt
->ui_resize
= carla_lv2_ui_resize
;
7375 LV2UI_Touch
* const uiTouchFt
= new LV2UI_Touch
;
7376 uiTouchFt
->handle
= this;
7377 uiTouchFt
->touch
= carla_lv2_ui_touch
;
7379 LV2_External_UI_Host
* const uiExternalHostFt
= new LV2_External_UI_Host
;
7380 uiExternalHostFt
->ui_closed
= carla_lv2_external_ui_closed
;
7381 uiExternalHostFt
->plugin_human_id
= fLv2Options
.windowTitle
;
7383 // ---------------------------------------------------------------
7384 // initialize ui features (part 2)
7386 for (uint32_t j
=kFeatureCountPlugin
; j
< kFeatureCountAll
; ++j
)
7387 fFeatures
[j
] = new LV2_Feature
;
7389 fFeatures
[kFeatureIdUiDataAccess
]->URI
= LV2_DATA_ACCESS_URI
;
7390 fFeatures
[kFeatureIdUiDataAccess
]->data
= uiDataFt
;
7392 fFeatures
[kFeatureIdUiInstanceAccess
]->URI
= LV2_INSTANCE_ACCESS_URI
;
7393 fFeatures
[kFeatureIdUiInstanceAccess
]->data
= fHandle
;
7395 fFeatures
[kFeatureIdUiIdleInterface
]->URI
= LV2_UI__idleInterface
;
7396 fFeatures
[kFeatureIdUiIdleInterface
]->data
= nullptr;
7398 fFeatures
[kFeatureIdUiFixedSize
]->URI
= LV2_UI__fixedSize
;
7399 fFeatures
[kFeatureIdUiFixedSize
]->data
= nullptr;
7401 fFeatures
[kFeatureIdUiMakeResident
]->URI
= LV2_UI__makeResident
;
7402 fFeatures
[kFeatureIdUiMakeResident
]->data
= nullptr;
7404 fFeatures
[kFeatureIdUiMakeResident2
]->URI
= LV2_UI__makeSONameResident
;
7405 fFeatures
[kFeatureIdUiMakeResident2
]->data
= nullptr;
7407 fFeatures
[kFeatureIdUiNoUserResize
]->URI
= LV2_UI__noUserResize
;
7408 fFeatures
[kFeatureIdUiNoUserResize
]->data
= nullptr;
7410 fFeatures
[kFeatureIdUiParent
]->URI
= LV2_UI__parent
;
7411 fFeatures
[kFeatureIdUiParent
]->data
= nullptr;
7413 fFeatures
[kFeatureIdUiPortMap
]->URI
= LV2_UI__portMap
;
7414 fFeatures
[kFeatureIdUiPortMap
]->data
= uiPortMapFt
;
7416 fFeatures
[kFeatureIdUiPortSubscribe
]->URI
= LV2_UI__portSubscribe
;
7417 fFeatures
[kFeatureIdUiPortSubscribe
]->data
= nullptr;
7419 fFeatures
[kFeatureIdUiRequestValue
]->URI
= LV2_UI__requestValue
;
7420 fFeatures
[kFeatureIdUiRequestValue
]->data
= uiRequestValueFt
;
7422 fFeatures
[kFeatureIdUiResize
]->URI
= LV2_UI__resize
;
7423 fFeatures
[kFeatureIdUiResize
]->data
= uiResizeFt
;
7425 fFeatures
[kFeatureIdUiTouch
]->URI
= LV2_UI__touch
;
7426 fFeatures
[kFeatureIdUiTouch
]->data
= uiTouchFt
;
7428 fFeatures
[kFeatureIdExternalUi
]->URI
= LV2_EXTERNAL_UI__Host
;
7429 fFeatures
[kFeatureIdExternalUi
]->data
= uiExternalHostFt
;
7431 fFeatures
[kFeatureIdExternalUiOld
]->URI
= LV2_EXTERNAL_UI_DEPRECATED_URI
;
7432 fFeatures
[kFeatureIdExternalUiOld
]->data
= uiExternalHostFt
;
7434 // ---------------------------------------------------------------
7435 // initialize ui extensions
7437 if (fUI
.descriptor
->extension_data
== nullptr)
7440 fExt
.uiidle
= (const LV2UI_Idle_Interface
*)fUI
.descriptor
->extension_data(LV2_UI__idleInterface
);
7441 fExt
.uishow
= (const LV2UI_Show_Interface
*)fUI
.descriptor
->extension_data(LV2_UI__showInterface
);
7442 fExt
.uiresize
= (const LV2UI_Resize
*)fUI
.descriptor
->extension_data(LV2_UI__resize
);
7443 fExt
.uiprograms
= (const LV2_Programs_UI_Interface
*)fUI
.descriptor
->extension_data(LV2_PROGRAMS__UIInterface
);
7446 if (fExt
.uiidle
!= nullptr && fExt
.uiidle
->idle
== nullptr)
7447 fExt
.uiidle
= nullptr;
7449 if (fExt
.uishow
!= nullptr && (fExt
.uishow
->show
== nullptr || fExt
.uishow
->hide
== nullptr))
7450 fExt
.uishow
= nullptr;
7452 if (fExt
.uiresize
!= nullptr && fExt
.uiresize
->ui_resize
== nullptr)
7453 fExt
.uiresize
= nullptr;
7455 if (fExt
.uiprograms
!= nullptr && fExt
.uiprograms
->select_program
== nullptr)
7456 fExt
.uiprograms
= nullptr;
7458 // don't use uiidle if external
7459 if (fUI
.type
== UI::TYPE_EXTERNAL
)
7460 fExt
.uiidle
= nullptr;
7463 // -------------------------------------------------------------------
7465 void handleTransferAtom(const uint32_t portIndex
, const LV2_Atom
* const atom
)
7467 CARLA_SAFE_ASSERT_RETURN(atom
!= nullptr,);
7468 carla_debug("CarlaPluginLV2::handleTransferAtom(%i, %p)", portIndex
, atom
);
7470 fAtomBufferEvIn
.put(atom
, portIndex
);
7473 void handleUridMap(const LV2_URID urid
, const char* const uri
)
7475 CARLA_SAFE_ASSERT_RETURN(urid
!= kUridNull
,);
7476 CARLA_SAFE_ASSERT_RETURN(uri
!= nullptr && uri
[0] != '\0',);
7477 carla_debug("CarlaPluginLV2::handleUridMap(%i v " P_SIZE
", \"%s\")", urid
, fCustomURIDs
.size()-1, uri
);
7479 const std::size_t uriCount(fCustomURIDs
.size());
7481 if (urid
< uriCount
)
7483 const char* const ourURI(carla_lv2_urid_unmap(this, urid
));
7484 CARLA_SAFE_ASSERT_RETURN(ourURI
!= nullptr && ourURI
!= kUnmapFallback
,);
7486 if (std::strcmp(ourURI
, uri
) != 0)
7488 carla_stderr2("PLUGIN :: wrong URI '%s' vs '%s'", ourURI
, uri
);
7493 CARLA_SAFE_ASSERT_RETURN(urid
== uriCount
,);
7494 fCustomURIDs
.push_back(uri
);
7498 // -------------------------------------------------------------------
7500 void writeAtomPath(const char* const path
, const LV2_URID urid
)
7502 uint8_t atomBuf
[4096];
7503 LV2_Atom_Forge atomForge
;
7504 initAtomForge(atomForge
);
7505 lv2_atom_forge_set_buffer(&atomForge
, atomBuf
, sizeof(atomBuf
));
7507 LV2_Atom_Forge_Frame forgeFrame
;
7508 lv2_atom_forge_object(&atomForge
, &forgeFrame
, kUridNull
, kUridPatchSet
);
7510 lv2_atom_forge_key(&atomForge
, kUridCarlaParameterChange
);
7511 lv2_atom_forge_bool(&atomForge
, true);
7513 lv2_atom_forge_key(&atomForge
, kUridPatchProperty
);
7514 lv2_atom_forge_urid(&atomForge
, urid
);
7516 lv2_atom_forge_key(&atomForge
, kUridPatchValue
);
7517 lv2_atom_forge_path(&atomForge
, path
, static_cast<uint32_t>(std::strlen(path
))+1);
7519 lv2_atom_forge_pop(&atomForge
, &forgeFrame
);
7521 LV2_Atom
* const atom((LV2_Atom
*)atomBuf
);
7522 CARLA_SAFE_ASSERT(atom
->size
< sizeof(atomBuf
));
7524 fAtomBufferEvIn
.put(atom
, fEventsIn
.ctrlIndex
);
7527 // -------------------------------------------------------------------
7531 LV2_Handle fHandle2
;
7532 LV2_Feature
* fFeatures
[kFeatureCountAll
+1];
7533 LV2_Feature
* fStateFeatures
[kStateFeatureCountAll
+1];
7534 const LV2_Descriptor
* fDescriptor
;
7535 const LV2_RDF_Descriptor
* fRdfDescriptor
;
7537 float** fAudioInBuffers
;
7538 float** fAudioOutBuffers
;
7539 float** fCvInBuffers
;
7540 float** fCvOutBuffers
;
7541 float* fParamBuffers
;
7543 bool fHasLoadDefaultState
: 1;
7544 bool fHasThreadSafeRestore
: 1;
7545 bool fNeedsFixedBuffers
: 1;
7546 bool fNeedsUiClose
: 1;
7547 bool fInlineDisplayNeedsRedraw
: 1;
7548 int64_t fInlineDisplayLastRedrawTime
;
7549 int32_t fLatencyIndex
; // -1 if invalid
7550 int fStrictBounds
; // -1 unsupported, 0 optional, 1 required
7552 Lv2AtomRingBuffer fAtomBufferEvIn
;
7553 Lv2AtomRingBuffer fAtomBufferUiOut
;
7554 Lv2AtomRingBuffer fAtomBufferWorkerIn
;
7555 Lv2AtomRingBuffer fAtomBufferWorkerResp
;
7556 uint8_t* fAtomBufferUiOutTmpData
;
7557 uint8_t* fAtomBufferWorkerInTmpData
;
7558 LV2_Atom
* fAtomBufferRealtime
;
7559 uint32_t fAtomBufferRealtimeSize
;
7561 CarlaPluginLV2EventData fEventsIn
;
7562 CarlaPluginLV2EventData fEventsOut
;
7563 CarlaPluginLV2Options fLv2Options
;
7564 #ifndef LV2_UIS_ONLY_INPROCESS
7565 CarlaPipeServerLV2 fPipeServer
;
7568 std::vector
<std::string
> fCustomURIDs
;
7570 bool fFirstActive
; // first process() call after activate()
7571 void* fLastStateChunk
;
7572 EngineTimeInfo fLastTimeInfo
;
7574 // if plugin provides path parameter, use it as fake "gui"
7575 CarlaString fFilePathURI
;
7578 const LV2_Options_Interface
* options
;
7579 const LV2_State_Interface
* state
;
7580 const LV2_Worker_Interface
* worker
;
7581 const LV2_Inline_Display_Interface
* inlineDisplay
;
7582 const LV2_Midnam_Interface
* midnam
;
7583 const LV2_Programs_Interface
* programs
;
7584 const LV2UI_Idle_Interface
* uiidle
;
7585 const LV2UI_Show_Interface
* uishow
;
7586 const LV2UI_Resize
* uiresize
;
7587 const LV2_Programs_UI_Interface
* uiprograms
;
7593 inlineDisplay(nullptr),
7599 uiprograms(nullptr) {}
7601 CARLA_DECLARE_NON_COPYABLE(Extensions
);
7607 #ifndef LV2_UIS_ONLY_INPROCESS
7615 LV2UI_Handle handle
;
7616 LV2UI_Widget widget
;
7617 const LV2UI_Descriptor
* descriptor
;
7618 const LV2_RDF_UI
* rdfDescriptor
;
7621 bool fileBrowserOpen
;
7622 const char* fileNeededForURI
;
7623 CarlaPluginUI
* window
;
7629 descriptor(nullptr),
7630 rdfDescriptor(nullptr),
7632 fileBrowserOpen(false),
7633 fileNeededForURI(nullptr),
7638 CARLA_SAFE_ASSERT(handle
== nullptr);
7639 CARLA_SAFE_ASSERT(widget
== nullptr);
7640 CARLA_SAFE_ASSERT(descriptor
== nullptr);
7641 CARLA_SAFE_ASSERT(rdfDescriptor
== nullptr);
7642 CARLA_SAFE_ASSERT(! fileBrowserOpen
);
7643 CARLA_SAFE_ASSERT(fileNeededForURI
== nullptr);
7644 CARLA_SAFE_ASSERT(window
== nullptr);
7647 CARLA_DECLARE_NON_COPYABLE(UI
);
7650 // -------------------------------------------------------------------
7653 static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data
, LV2_Event
* event
)
7655 CARLA_SAFE_ASSERT_RETURN(callback_data
!= nullptr, 0);
7656 CARLA_SAFE_ASSERT_RETURN(event
!= nullptr, 0);
7657 carla_debug("carla_lv2_event_ref(%p, %p)", callback_data
, event
);
7662 static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data
, LV2_Event
* event
)
7664 CARLA_SAFE_ASSERT_RETURN(callback_data
!= nullptr, 0);
7665 CARLA_SAFE_ASSERT_RETURN(event
!= nullptr, 0);
7666 carla_debug("carla_lv2_event_unref(%p, %p)", callback_data
, event
);
7671 // -------------------------------------------------------------------
7674 static int carla_lv2_log_printf(LV2_Log_Handle handle
, LV2_URID type
, const char* fmt
, ...)
7676 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, 0);
7677 CARLA_SAFE_ASSERT_RETURN(type
!= kUridNull
, 0);
7678 CARLA_SAFE_ASSERT_RETURN(fmt
!= nullptr, 0);
7681 if (type
== kUridLogTrace
)
7686 va_start(args
, fmt
);
7687 const int ret(carla_lv2_log_vprintf(handle
, type
, fmt
, args
));
7693 static int carla_lv2_log_vprintf(LV2_Log_Handle handle
, LV2_URID type
, const char* fmt
, va_list ap
)
7695 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, 0);
7696 CARLA_SAFE_ASSERT_RETURN(type
!= kUridNull
, 0);
7697 CARLA_SAFE_ASSERT_RETURN(fmt
!= nullptr, 0);
7704 std::fprintf(stderr
, "\x1b[31m");
7705 ret
= std::vfprintf(stderr
, fmt
, ap
);
7706 std::fprintf(stderr
, "\x1b[0m");
7710 ret
= std::vfprintf(stdout
, fmt
, ap
);
7715 std::fprintf(stdout
, "\x1b[30;1m");
7716 ret
= std::vfprintf(stdout
, fmt
, ap
);
7717 std::fprintf(stdout
, "\x1b[0m");
7721 case kUridLogWarning
:
7722 ret
= std::vfprintf(stderr
, fmt
, ap
);
7732 // -------------------------------------------------------------------
7735 static void carla_lv2_program_changed(LV2_Programs_Handle handle
, int32_t index
)
7737 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr,);
7738 carla_debug("carla_lv2_program_changed(%p, %i)", handle
, index
);
7740 ((CarlaPluginLV2
*)handle
)->handleProgramChanged(index
);
7743 // -------------------------------------------------------------------
7744 // Resize Port Feature
7746 static LV2_Resize_Port_Status
carla_lv2_resize_port(LV2_Resize_Port_Feature_Data data
, uint32_t index
, size_t size
)
7748 CARLA_SAFE_ASSERT_RETURN(data
!= nullptr, LV2_RESIZE_PORT_ERR_UNKNOWN
);
7749 carla_debug("carla_lv2_program_changed(%p, %i, " P_SIZE
")", data
, index
, size
);
7751 return ((CarlaPluginLV2
*)data
)->handleResizePort(index
, size
);
7754 // -------------------------------------------------------------------
7757 static void carla_lv2_state_free_path(LV2_State_Free_Path_Handle handle
, char* const path
)
7759 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr,);
7760 carla_debug("carla_lv2_state_free_path(%p, \"%s\")", handle
, path
);
7765 static char* carla_lv2_state_make_path_real(LV2_State_Make_Path_Handle handle
, const char* path
)
7767 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7768 CARLA_SAFE_ASSERT_RETURN(path
!= nullptr, nullptr);
7769 carla_debug("carla_lv2_state_make_path_real(%p, \"%s\")", handle
, path
);
7771 // allow empty paths to mean "current dir"
7772 if (path
[0] == '\0')
7775 const File
file(((CarlaPluginLV2
*)handle
)->handleStateMapToAbsolutePath(true, false, false, path
));
7776 return file
.isNotNull() ? strdup(file
.getFullPathName().toRawUTF8()) : nullptr;
7779 static char* carla_lv2_state_make_path_tmp(LV2_State_Make_Path_Handle handle
, const char* path
)
7781 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7782 CARLA_SAFE_ASSERT_RETURN(path
!= nullptr, nullptr);
7783 carla_debug("carla_lv2_state_make_path_tmp(%p, \"%s\")", handle
, path
);
7785 // allow empty paths to mean "current dir"
7786 if (path
[0] == '\0')
7789 const File
file(((CarlaPluginLV2
*)handle
)->handleStateMapToAbsolutePath(true, false, true, path
));
7790 return file
.isNotNull() ? strdup(file
.getFullPathName().toRawUTF8()) : nullptr;
7793 static char* carla_lv2_state_map_to_abstract_path_real(LV2_State_Map_Path_Handle handle
, const char* const absolute_path
)
7795 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7796 CARLA_SAFE_ASSERT_RETURN(absolute_path
!= nullptr, nullptr);
7797 carla_debug("carla_lv2_state_map_to_abstract_path_real(%p, \"%s\")", handle
, absolute_path
);
7799 // handle invalid empty paths the same way as lilv
7800 if (absolute_path
[0] == '\0')
7803 return ((CarlaPluginLV2
*)handle
)->handleStateMapToAbstractPath(false, absolute_path
);
7806 static char* carla_lv2_state_map_to_abstract_path_tmp(LV2_State_Map_Path_Handle handle
, const char* const absolute_path
)
7808 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7809 CARLA_SAFE_ASSERT_RETURN(absolute_path
!= nullptr, nullptr);
7810 carla_debug("carla_lv2_state_map_to_abstract_path_tmp(%p, \"%s\")", handle
, absolute_path
);
7812 // handle invalid empty paths the same way as lilv
7813 if (absolute_path
[0] == '\0')
7816 return ((CarlaPluginLV2
*)handle
)->handleStateMapToAbstractPath(true, absolute_path
);
7819 static char* carla_lv2_state_map_to_absolute_path_real(LV2_State_Map_Path_Handle handle
, const char* abstract_path
)
7821 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7822 CARLA_SAFE_ASSERT_RETURN(abstract_path
!= nullptr, nullptr);
7823 carla_debug("carla_lv2_state_map_to_absolute_path_real(%p, \"%s\")", handle
, abstract_path
);
7825 // allow empty paths to mean "current dir"
7826 if (abstract_path
[0] == '\0')
7827 abstract_path
= ".";
7829 const File
file(((CarlaPluginLV2
*)handle
)->handleStateMapToAbsolutePath(true, true, false, abstract_path
));
7830 return file
.isNotNull() ? strdup(file
.getFullPathName().toRawUTF8()) : nullptr;
7833 static char* carla_lv2_state_map_to_absolute_path_tmp(LV2_State_Map_Path_Handle handle
, const char* abstract_path
)
7835 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7836 CARLA_SAFE_ASSERT_RETURN(abstract_path
!= nullptr, nullptr);
7837 carla_debug("carla_lv2_state_map_to_absolute_path_tmp(%p, \"%s\")", handle
, abstract_path
);
7839 // allow empty paths to mean "current dir"
7840 if (abstract_path
[0] == '\0')
7841 abstract_path
= ".";
7843 const File
file(((CarlaPluginLV2
*)handle
)->handleStateMapToAbsolutePath(true, true, true, abstract_path
));
7844 return file
.isNotNull() ? strdup(file
.getFullPathName().toRawUTF8()) : nullptr;
7847 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
)
7849 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2_STATE_ERR_UNKNOWN
);
7850 carla_debug("carla_lv2_state_store(%p, %i, %p, " P_SIZE
", %i, %i)", handle
, key
, value
, size
, type
, flags
);
7852 return ((CarlaPluginLV2
*)handle
)->handleStateStore(key
, value
, size
, type
, flags
);
7855 static const void* carla_lv2_state_retrieve(LV2_State_Handle handle
, uint32_t key
, size_t* size
, uint32_t* type
, uint32_t* flags
)
7857 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
7858 carla_debug("carla_lv2_state_retrieve(%p, %i, %p, %p, %p)", handle
, key
, size
, type
, flags
);
7860 return ((CarlaPluginLV2
*)handle
)->handleStateRetrieve(key
, size
, type
, flags
);
7863 // -------------------------------------------------------------------
7866 static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data
, const char* map
, const char* uri
)
7868 carla_debug("carla_lv2_uri_to_id(%p, \"%s\", \"%s\")", data
, map
, uri
);
7869 return carla_lv2_urid_map((LV2_URID_Map_Handle
*)data
, uri
);
7875 // -------------------------------------------------------------------
7878 static LV2_URID
carla_lv2_urid_map(LV2_URID_Map_Handle handle
, const char* uri
)
7880 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, kUridNull
);
7881 CARLA_SAFE_ASSERT_RETURN(uri
!= nullptr && uri
[0] != '\0', kUridNull
);
7882 carla_debug("carla_lv2_urid_map(%p, \"%s\")", handle
, uri
);
7885 if (std::strcmp(uri
, LV2_ATOM__Blank
) == 0)
7886 return kUridAtomBlank
;
7887 if (std::strcmp(uri
, LV2_ATOM__Bool
) == 0)
7888 return kUridAtomBool
;
7889 if (std::strcmp(uri
, LV2_ATOM__Chunk
) == 0)
7890 return kUridAtomChunk
;
7891 if (std::strcmp(uri
, LV2_ATOM__Double
) == 0)
7892 return kUridAtomDouble
;
7893 if (std::strcmp(uri
, LV2_ATOM__Event
) == 0)
7894 return kUridAtomEvent
;
7895 if (std::strcmp(uri
, LV2_ATOM__Float
) == 0)
7896 return kUridAtomFloat
;
7897 if (std::strcmp(uri
, LV2_ATOM__Int
) == 0)
7898 return kUridAtomInt
;
7899 if (std::strcmp(uri
, LV2_ATOM__Literal
) == 0)
7900 return kUridAtomLiteral
;
7901 if (std::strcmp(uri
, LV2_ATOM__Long
) == 0)
7902 return kUridAtomLong
;
7903 if (std::strcmp(uri
, LV2_ATOM__Number
) == 0)
7904 return kUridAtomNumber
;
7905 if (std::strcmp(uri
, LV2_ATOM__Object
) == 0)
7906 return kUridAtomObject
;
7907 if (std::strcmp(uri
, LV2_ATOM__Path
) == 0)
7908 return kUridAtomPath
;
7909 if (std::strcmp(uri
, LV2_ATOM__Property
) == 0)
7910 return kUridAtomProperty
;
7911 if (std::strcmp(uri
, LV2_ATOM__Resource
) == 0)
7912 return kUridAtomResource
;
7913 if (std::strcmp(uri
, LV2_ATOM__Sequence
) == 0)
7914 return kUridAtomSequence
;
7915 if (std::strcmp(uri
, LV2_ATOM__Sound
) == 0)
7916 return kUridAtomSound
;
7917 if (std::strcmp(uri
, LV2_ATOM__String
) == 0)
7918 return kUridAtomString
;
7919 if (std::strcmp(uri
, LV2_ATOM__Tuple
) == 0)
7920 return kUridAtomTuple
;
7921 if (std::strcmp(uri
, LV2_ATOM__URI
) == 0)
7922 return kUridAtomURI
;
7923 if (std::strcmp(uri
, LV2_ATOM__URID
) == 0)
7924 return kUridAtomURID
;
7925 if (std::strcmp(uri
, LV2_ATOM__Vector
) == 0)
7926 return kUridAtomVector
;
7927 if (std::strcmp(uri
, LV2_ATOM__atomTransfer
) == 0)
7928 return kUridAtomTransferAtom
;
7929 if (std::strcmp(uri
, LV2_ATOM__eventTransfer
) == 0)
7930 return kUridAtomTransferEvent
;
7933 if (std::strcmp(uri
, LV2_BUF_SIZE__maxBlockLength
) == 0)
7934 return kUridBufMaxLength
;
7935 if (std::strcmp(uri
, LV2_BUF_SIZE__minBlockLength
) == 0)
7936 return kUridBufMinLength
;
7937 if (std::strcmp(uri
, LV2_BUF_SIZE__nominalBlockLength
) == 0)
7938 return kUridBufNominalLength
;
7939 if (std::strcmp(uri
, LV2_BUF_SIZE__sequenceSize
) == 0)
7940 return kUridBufSequenceSize
;
7943 if (std::strcmp(uri
, LV2_LOG__Error
) == 0)
7944 return kUridLogError
;
7945 if (std::strcmp(uri
, LV2_LOG__Note
) == 0)
7946 return kUridLogNote
;
7947 if (std::strcmp(uri
, LV2_LOG__Trace
) == 0)
7948 return kUridLogTrace
;
7949 if (std::strcmp(uri
, LV2_LOG__Warning
) == 0)
7950 return kUridLogWarning
;
7953 if (std::strcmp(uri
, LV2_PATCH__Set
) == 0)
7954 return kUridPatchSet
;
7955 if (std::strcmp(uri
, LV2_PATCH__property
) == 0)
7956 return kUridPatchProperty
;
7957 if (std::strcmp(uri
, LV2_PATCH__subject
) == 0)
7958 return kUridPatchSubject
;
7959 if (std::strcmp(uri
, LV2_PATCH__value
) == 0)
7960 return kUridPatchValue
;
7963 if (std::strcmp(uri
, LV2_TIME__Position
) == 0)
7964 return kUridTimePosition
;
7965 if (std::strcmp(uri
, LV2_TIME__bar
) == 0)
7966 return kUridTimeBar
;
7967 if (std::strcmp(uri
, LV2_TIME__barBeat
) == 0)
7968 return kUridTimeBarBeat
;
7969 if (std::strcmp(uri
, LV2_TIME__beat
) == 0)
7970 return kUridTimeBeat
;
7971 if (std::strcmp(uri
, LV2_TIME__beatUnit
) == 0)
7972 return kUridTimeBeatUnit
;
7973 if (std::strcmp(uri
, LV2_TIME__beatsPerBar
) == 0)
7974 return kUridTimeBeatsPerBar
;
7975 if (std::strcmp(uri
, LV2_TIME__beatsPerMinute
) == 0)
7976 return kUridTimeBeatsPerMinute
;
7977 if (std::strcmp(uri
, LV2_TIME__frame
) == 0)
7978 return kUridTimeFrame
;
7979 if (std::strcmp(uri
, LV2_TIME__framesPerSecond
) == 0)
7980 return kUridTimeFramesPerSecond
;
7981 if (std::strcmp(uri
, LV2_TIME__speed
) == 0)
7982 return kUridTimeSpeed
;
7983 if (std::strcmp(uri
, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat
) == 0)
7984 return kUridTimeTicksPerBeat
;
7987 if (std::strcmp(uri
, LV2_MIDI__MidiEvent
) == 0)
7988 return kUridMidiEvent
;
7989 if (std::strcmp(uri
, LV2_PARAMETERS__sampleRate
) == 0)
7990 return kUridParamSampleRate
;
7991 if (std::strcmp(uri
, LV2_UI__backgroundColor
) == 0)
7992 return kUridBackgroundColor
;
7993 if (std::strcmp(uri
, LV2_UI__foregroundColor
) == 0)
7994 return kUridForegroundColor
;
7995 #ifndef CARLA_OS_MAC
7996 if (std::strcmp(uri
, LV2_UI__scaleFactor
) == 0)
7997 return kUridScaleFactor
;
7999 if (std::strcmp(uri
, LV2_UI__windowTitle
) == 0)
8000 return kUridWindowTitle
;
8002 // Custom Carla types
8003 if (std::strcmp(uri
, URI_CARLA_ATOM_WORKER_IN
) == 0)
8004 return kUridCarlaAtomWorkerIn
;
8005 if (std::strcmp(uri
, URI_CARLA_ATOM_WORKER_RESP
) == 0)
8006 return kUridCarlaAtomWorkerResp
;
8007 if (std::strcmp(uri
, URI_CARLA_PARAMETER_CHANGE
) == 0)
8008 return kUridCarlaParameterChange
;
8009 if (std::strcmp(uri
, LV2_KXSTUDIO_PROPERTIES__TransientWindowId
) == 0)
8010 return kUridCarlaTransientWindowId
;
8012 // Custom plugin types
8013 return ((CarlaPluginLV2
*)handle
)->getCustomURID(uri
);
8016 static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle
, LV2_URID urid
)
8018 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, nullptr);
8019 CARLA_SAFE_ASSERT_RETURN(urid
!= kUridNull
, nullptr);
8020 carla_debug("carla_lv2_urid_unmap(%p, %i)", handle
, urid
);
8025 case kUridAtomBlank
:
8026 return LV2_ATOM__Blank
;
8028 return LV2_ATOM__Bool
;
8029 case kUridAtomChunk
:
8030 return LV2_ATOM__Chunk
;
8031 case kUridAtomDouble
:
8032 return LV2_ATOM__Double
;
8033 case kUridAtomEvent
:
8034 return LV2_ATOM__Event
;
8035 case kUridAtomFloat
:
8036 return LV2_ATOM__Float
;
8038 return LV2_ATOM__Int
;
8039 case kUridAtomLiteral
:
8040 return LV2_ATOM__Literal
;
8042 return LV2_ATOM__Long
;
8043 case kUridAtomNumber
:
8044 return LV2_ATOM__Number
;
8045 case kUridAtomObject
:
8046 return LV2_ATOM__Object
;
8048 return LV2_ATOM__Path
;
8049 case kUridAtomProperty
:
8050 return LV2_ATOM__Property
;
8051 case kUridAtomResource
:
8052 return LV2_ATOM__Resource
;
8053 case kUridAtomSequence
:
8054 return LV2_ATOM__Sequence
;
8055 case kUridAtomSound
:
8056 return LV2_ATOM__Sound
;
8057 case kUridAtomString
:
8058 return LV2_ATOM__String
;
8059 case kUridAtomTuple
:
8060 return LV2_ATOM__Tuple
;
8062 return LV2_ATOM__URI
;
8064 return LV2_ATOM__URID
;
8065 case kUridAtomVector
:
8066 return LV2_ATOM__Vector
;
8067 case kUridAtomTransferAtom
:
8068 return LV2_ATOM__atomTransfer
;
8069 case kUridAtomTransferEvent
:
8070 return LV2_ATOM__eventTransfer
;
8073 case kUridBufMaxLength
:
8074 return LV2_BUF_SIZE__maxBlockLength
;
8075 case kUridBufMinLength
:
8076 return LV2_BUF_SIZE__minBlockLength
;
8077 case kUridBufNominalLength
:
8078 return LV2_BUF_SIZE__nominalBlockLength
;
8079 case kUridBufSequenceSize
:
8080 return LV2_BUF_SIZE__sequenceSize
;
8084 return LV2_LOG__Error
;
8086 return LV2_LOG__Note
;
8088 return LV2_LOG__Trace
;
8089 case kUridLogWarning
:
8090 return LV2_LOG__Warning
;
8094 return LV2_PATCH__Set
;
8095 case kUridPatchProperty
:
8096 return LV2_PATCH__property
;
8097 case kUridPatchSubject
:
8098 return LV2_PATCH__subject
;
8099 case kUridPatchValue
:
8100 return LV2_PATCH__value
;
8103 case kUridTimePosition
:
8104 return LV2_TIME__Position
;
8106 return LV2_TIME__bar
;
8107 case kUridTimeBarBeat
:
8108 return LV2_TIME__barBeat
;
8110 return LV2_TIME__beat
;
8111 case kUridTimeBeatUnit
:
8112 return LV2_TIME__beatUnit
;
8113 case kUridTimeBeatsPerBar
:
8114 return LV2_TIME__beatsPerBar
;
8115 case kUridTimeBeatsPerMinute
:
8116 return LV2_TIME__beatsPerMinute
;
8117 case kUridTimeFrame
:
8118 return LV2_TIME__frame
;
8119 case kUridTimeFramesPerSecond
:
8120 return LV2_TIME__framesPerSecond
;
8121 case kUridTimeSpeed
:
8122 return LV2_TIME__speed
;
8123 case kUridTimeTicksPerBeat
:
8124 return LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat
;
8127 case kUridMidiEvent
:
8128 return LV2_MIDI__MidiEvent
;
8129 case kUridParamSampleRate
:
8130 return LV2_PARAMETERS__sampleRate
;
8131 case kUridBackgroundColor
:
8132 return LV2_UI__backgroundColor
;
8133 case kUridForegroundColor
:
8134 return LV2_UI__foregroundColor
;
8135 #ifndef CARLA_OS_MAC
8136 case kUridScaleFactor
:
8137 return LV2_UI__scaleFactor
;
8139 case kUridWindowTitle
:
8140 return LV2_UI__windowTitle
;
8142 // Custom Carla types
8143 case kUridCarlaAtomWorkerIn
:
8144 return URI_CARLA_ATOM_WORKER_IN
;
8145 case kUridCarlaAtomWorkerResp
:
8146 return URI_CARLA_ATOM_WORKER_RESP
;
8147 case kUridCarlaParameterChange
:
8148 return URI_CARLA_PARAMETER_CHANGE
;
8149 case kUridCarlaTransientWindowId
:
8150 return LV2_KXSTUDIO_PROPERTIES__TransientWindowId
;
8153 // Custom plugin types
8154 return ((CarlaPluginLV2
*)handle
)->getCustomURIDString(urid
);
8157 // -------------------------------------------------------------------
8160 static LV2_Worker_Status
carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle
, uint32_t size
, const void* data
)
8162 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2_WORKER_ERR_UNKNOWN
);
8163 carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle
, size
, data
);
8165 return ((CarlaPluginLV2
*)handle
)->handleWorkerSchedule(size
, data
);
8168 static LV2_Worker_Status
carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle
, uint32_t size
, const void* data
)
8170 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2_WORKER_ERR_UNKNOWN
);
8171 carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle
, size
, data
);
8173 return ((CarlaPluginLV2
*)handle
)->handleWorkerRespond(size
, data
);
8176 // -------------------------------------------------------------------
8177 // Inline Display Feature
8179 static void carla_lv2_inline_display_queue_draw(LV2_Inline_Display_Handle handle
)
8181 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr,);
8182 // carla_debug("carla_lv2_inline_display_queue_draw(%p)", handle);
8184 ((CarlaPluginLV2
*)handle
)->handleInlineDisplayQueueRedraw();
8187 // -------------------------------------------------------------------
8190 static void carla_lv2_midnam_update(LV2_Midnam_Handle handle
)
8192 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr,);
8193 carla_stdout("carla_lv2_midnam_update(%p)", handle
);
8195 ((CarlaPluginLV2
*)handle
)->handleMidnamUpdate();
8198 // -------------------------------------------------------------------
8199 // ControlInputPort change request Feature
8201 static LV2_ControlInputPort_Change_Status
carla_lv2_ctrl_in_port_change_req(
8202 LV2_ControlInputPort_Change_Request_Handle handle
, uint32_t index
, float value
)
8204 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2_CONTROL_INPUT_PORT_CHANGE_ERR_UNKNOWN
);
8205 carla_stdout("carla_lv2_ctrl_in_port_change_req(%p, %u, %f)", handle
, index
, value
);
8207 return ((CarlaPluginLV2
*)handle
)->handleCtrlInPortChangeReq(index
, value
);
8210 // -------------------------------------------------------------------
8211 // External UI Feature
8213 static void carla_lv2_external_ui_closed(LV2UI_Controller controller
)
8215 CARLA_SAFE_ASSERT_RETURN(controller
!= nullptr,);
8216 carla_debug("carla_lv2_external_ui_closed(%p)", controller
);
8218 ((CarlaPluginLV2
*)controller
)->handleExternalUIClosed();
8221 // -------------------------------------------------------------------
8222 // UI Port-Map Feature
8224 static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle
, const char* symbol
)
8226 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2UI_INVALID_PORT_INDEX
);
8227 carla_debug("carla_lv2_ui_port_map(%p, \"%s\")", handle
, symbol
);
8229 return ((CarlaPluginLV2
*)handle
)->handleUIPortMap(symbol
);
8232 // ----------------------------------------------------------------------------------------------------------------
8233 // UI Request Parameter Feature
8235 static LV2UI_Request_Value_Status
carla_lv2_ui_request_value(LV2UI_Feature_Handle handle
,
8238 const LV2_Feature
* const* features
)
8240 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN
);
8241 carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle
, key
, type
, features
);
8243 return ((CarlaPluginLV2
*)handle
)->handleUIRequestValue(key
, type
, features
);
8246 // -------------------------------------------------------------------
8247 // UI Resize Feature
8249 static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle
, int width
, int height
)
8251 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr, 1);
8252 carla_debug("carla_lv2_ui_resize(%p, %i, %i)", handle
, width
, height
);
8254 return ((CarlaPluginLV2
*)handle
)->handleUIResize(width
, height
);
8257 // -------------------------------------------------------------------
8260 static void carla_lv2_ui_touch(LV2UI_Feature_Handle handle
, uint32_t port_index
, bool touch
)
8262 CARLA_SAFE_ASSERT_RETURN(handle
!= nullptr,);
8263 carla_debug("carla_lv2_ui_touch(%p, %u, %s)", handle
, port_index
, bool2str(touch
));
8265 ((CarlaPluginLV2
*)handle
)->handleUITouch(port_index
, touch
);
8268 // -------------------------------------------------------------------
8271 static void carla_lv2_ui_write_function(LV2UI_Controller controller
, uint32_t port_index
, uint32_t buffer_size
, uint32_t format
, const void* buffer
)
8273 CARLA_SAFE_ASSERT_RETURN(controller
!= nullptr,);
8274 carla_debug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller
, port_index
, buffer_size
, format
, buffer
);
8276 ((CarlaPluginLV2
*)controller
)->handleUIWrite(port_index
, buffer_size
, format
, buffer
);
8279 // -------------------------------------------------------------------
8282 static void carla_lilv_set_port_value(const char* port_symbol
, void* user_data
, const void* value
, uint32_t size
, uint32_t type
)
8284 CARLA_SAFE_ASSERT_RETURN(user_data
!= nullptr,);
8285 carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i", port_symbol
, user_data
, value
, size
, type
);
8287 ((CarlaPluginLV2
*)user_data
)->handleLilvSetPortValue(port_symbol
, value
, size
, type
);
8290 // -------------------------------------------------------------------
8292 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginLV2
)
8295 // -------------------------------------------------------------------------------------------------------------------
8297 #ifndef LV2_UIS_ONLY_INPROCESS
8298 bool CarlaPipeServerLV2::msgReceived(const char* const msg
) noexcept
8300 if (std::strcmp(msg
, "exiting") == 0)
8307 if (std::strcmp(msg
, "control") == 0)
8312 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index
), true);
8313 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value
), true);
8316 kPlugin
->handleUIWrite(index
, sizeof(float), kUridNull
, &value
);
8317 } CARLA_SAFE_EXCEPTION("magReceived control");
8322 if (std::strcmp(msg
, "pcontrol") == 0)
8327 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri
, true), true);
8328 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value
), true);
8331 kPlugin
->handleUIBridgeParameter(uri
, value
);
8332 } CARLA_SAFE_EXCEPTION("magReceived pcontrol");
8337 if (std::strcmp(msg
, "atom") == 0)
8339 uint32_t index
, atomTotalSize
, base64Size
;
8340 const char* base64atom
;
8342 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index
), true);
8343 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(atomTotalSize
), true);
8344 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(base64Size
), true);
8345 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(base64atom
, false, base64Size
), true);
8347 std::vector
<uint8_t> chunk(carla_getChunkFromBase64String(base64atom
));
8348 CARLA_SAFE_ASSERT_UINT2_RETURN(chunk
.size() >= sizeof(LV2_Atom
), chunk
.size(), sizeof(LV2_Atom
), true);
8350 #ifdef CARLA_PROPER_CPP11_SUPPORT
8351 const LV2_Atom
* const atom((const LV2_Atom
*)chunk
.data());
8353 const LV2_Atom
* const atom((const LV2_Atom
*)&chunk
.front());
8355 CARLA_SAFE_ASSERT_RETURN(lv2_atom_total_size(atom
) == chunk
.size(), true);
8358 kPlugin
->handleUIWrite(index
, lv2_atom_total_size(atom
), kUridAtomTransferEvent
, atom
);
8359 } CARLA_SAFE_EXCEPTION("magReceived atom");
8364 if (std::strcmp(msg
, "program") == 0)
8368 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index
), true);
8371 kPlugin
->setMidiProgram(static_cast<int32_t>(index
), false, true, true, false);
8372 } CARLA_SAFE_EXCEPTION("msgReceived program");
8377 if (std::strcmp(msg
, "urid") == 0)
8379 uint32_t urid
, size
;
8382 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(urid
), true);
8383 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(size
), true);
8384 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(uri
, false, size
), true);
8389 kPlugin
->handleUridMap(urid
, uri
);
8390 } CARLA_SAFE_EXCEPTION("msgReceived urid");
8396 if (std::strcmp(msg
, "reloadprograms") == 0)
8400 CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index
), true);
8403 kPlugin
->handleProgramChanged(index
);
8404 } CARLA_SAFE_EXCEPTION("handleProgramChanged");
8409 if (std::strcmp(msg
, "requestvalue") == 0)
8413 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(key
), true);
8414 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(type
), true);
8419 kPlugin
->handleUIRequestValue(key
, type
, nullptr);
8420 } CARLA_SAFE_EXCEPTION("msgReceived requestvalue");
8430 // -------------------------------------------------------------------------------------------------------------------
8432 CarlaPluginPtr
CarlaPlugin::newLV2(const Initializer
& init
)
8434 carla_debug("CarlaPlugin::newLV2({%p, \"%s\", \"%s\"})", init
.engine
, init
.name
, init
.label
);
8436 std::shared_ptr
<CarlaPluginLV2
> plugin(new CarlaPluginLV2(init
.engine
, init
.id
));
8438 const char* needsArchBridge
= nullptr;
8439 if (plugin
->init(plugin
, init
.name
, init
.label
, init
.options
, needsArchBridge
))
8442 #ifndef CARLA_OS_WASM
8443 if (needsArchBridge
!= nullptr)
8445 CarlaString
bridgeBinary(init
.engine
->getOptions().binaryDir
);
8446 bridgeBinary
+= CARLA_OS_SEP_STR
"carla-bridge-native";
8448 return CarlaPlugin::newBridge(init
, BINARY_NATIVE
, PLUGIN_LV2
, needsArchBridge
, bridgeBinary
);
8455 // used in CarlaStandalone.cpp
8456 const void* carla_render_inline_display_lv2(const CarlaPluginPtr
& plugin
, uint32_t width
, uint32_t height
);
8458 const void* carla_render_inline_display_lv2(const CarlaPluginPtr
& plugin
, uint32_t width
, uint32_t height
)
8460 const std::shared_ptr
<CarlaPluginLV2
>& lv2Plugin((const std::shared_ptr
<CarlaPluginLV2
>&)plugin
);
8462 return lv2Plugin
->renderInlineDisplay(width
, height
);
8465 // -------------------------------------------------------------------------------------------------------------------
8467 CARLA_BACKEND_END_NAMESPACE