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