3 * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_PLUGIN_INTERNAL_HPP_INCLUDED
19 #define CARLA_PLUGIN_INTERNAL_HPP_INCLUDED
21 #include "CarlaPlugin.hpp"
23 #include "CarlaJuceUtils.hpp"
24 #include "CarlaLibUtils.hpp"
25 #include "CarlaStateUtils.hpp"
27 #include "CarlaMIDI.h"
28 #include "CarlaMutex.hpp"
29 #include "CarlaString.hpp"
30 #include "RtLinkedList.hpp"
32 CARLA_BACKEND_START_NAMESPACE
34 // -----------------------------------------------------------------------
35 // Engine helper macro, sets lastError and returns false/NULL
37 #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return false; }
38 #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return nullptr; }
40 #define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return false; }
41 #define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return nullptr; }
43 // -----------------------------------------------------------------------
44 // Maximum pre-allocated events for some plugin types
46 constexpr const uint16_t kPluginMaxMidiEvents
= 512;
48 // -----------------------------------------------------------------------
49 // Extra parameter hints, hidden from backend
51 constexpr const uint PARAMETER_MAPPED_RANGES_SET
= 0x10000;
52 constexpr const uint PARAMETER_IS_STRICT_BOUNDS
= 0x20000;
53 constexpr const uint PARAMETER_IS_TRIGGER
= 0x40000;
55 // -----------------------------------------------------------------------
56 // Extra plugin hints, hidden from backend
58 constexpr const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN
= 0x01;
59 constexpr const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT
= 0x02;
61 // -----------------------------------------------------------------------
64 enum SpecialParameterType
{
65 PARAMETER_SPECIAL_NULL
= 0,
66 PARAMETER_SPECIAL_FREEWHEEL
= 1,
67 PARAMETER_SPECIAL_LATENCY
= 2,
68 PARAMETER_SPECIAL_SAMPLE_RATE
= 3,
69 PARAMETER_SPECIAL_TIME
= 4
72 // -----------------------------------------------------------------------
76 * These are events postponned from within the process function,
78 * During process, we cannot lock, allocate memory or do UI stuff.
79 * Events have to be postponned to be executed later, on a separate thread.
80 * @see PluginPostRtEvent
82 enum PluginPostRtEventType
{
83 kPluginPostRtEventNull
= 0,
84 kPluginPostRtEventParameterChange
,
85 kPluginPostRtEventProgramChange
,
86 kPluginPostRtEventMidiProgramChange
,
87 kPluginPostRtEventNoteOn
,
88 kPluginPostRtEventNoteOff
,
89 kPluginPostRtEventMidiLearn
94 * @see PluginPostRtEventType
96 struct PluginPostRtEvent
{
97 PluginPostRtEventType type
;
120 // -----------------------------------------------------------------------
122 struct ExternalMidiNote
{
123 int8_t channel
; // invalid if -1
124 uint8_t note
; // 0 to 127
125 uint8_t velo
; // 1 to 127, 0 for note-off
128 // -----------------------------------------------------------------------
130 struct PluginAudioPort
{
132 CarlaEngineAudioPort
* port
;
135 struct PluginAudioData
{
137 PluginAudioPort
* ports
;
139 PluginAudioData() noexcept
;
140 ~PluginAudioData() noexcept
;
141 void createNew(uint32_t newCount
);
142 void clear() noexcept
;
143 void initBuffers() const noexcept
;
145 CARLA_DECLARE_NON_COPYABLE(PluginAudioData
)
148 // -----------------------------------------------------------------------
150 struct PluginCVPort
{
152 //uint32_t param; // FIXME is this needed?
153 CarlaEngineCVPort
* port
;
156 struct PluginCVData
{
160 PluginCVData() noexcept
;
161 ~PluginCVData() noexcept
;
162 void createNew(uint32_t newCount
);
163 void clear() noexcept
;
164 void initBuffers() const noexcept
;
166 CARLA_DECLARE_NON_COPYABLE(PluginCVData
)
169 // -----------------------------------------------------------------------
171 struct PluginEventData
{
172 CarlaEngineEventPort
* portIn
;
173 CarlaEngineEventPort
* portOut
;
174 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
175 CarlaEngineCVSourcePorts
* cvSourcePorts
;
178 PluginEventData() noexcept
;
179 ~PluginEventData() noexcept
;
180 void clear() noexcept
;
181 void initBuffers() const noexcept
;
183 CARLA_DECLARE_NON_COPYABLE(PluginEventData
)
186 // -----------------------------------------------------------------------
188 struct PluginParameterData
{
191 ParameterRanges
* ranges
;
192 SpecialParameterType
* special
;
194 PluginParameterData() noexcept
;
195 ~PluginParameterData() noexcept
;
196 void createNew(uint32_t newCount
, bool withSpecial
);
197 void clear() noexcept
;
198 float getFixedValue(uint32_t parameterId
, float value
) const noexcept
;
199 float getFinalUnnormalizedValue(uint32_t parameterId
, float normalizedValue
) const noexcept
;
200 float getFinalValueWithMidiDelta(uint32_t parameterId
, float value
, int8_t delta
) const noexcept
;
202 CARLA_DECLARE_NON_COPYABLE(PluginParameterData
)
205 // -----------------------------------------------------------------------
207 typedef const char* ProgramName
;
209 struct PluginProgramData
{
214 PluginProgramData() noexcept
;
215 ~PluginProgramData() noexcept
;
216 void createNew(uint32_t newCount
);
217 void clear() noexcept
;
219 CARLA_DECLARE_NON_COPYABLE(PluginProgramData
)
222 // -----------------------------------------------------------------------
224 struct PluginMidiProgramData
{
227 MidiProgramData
* data
;
229 PluginMidiProgramData() noexcept
;
230 ~PluginMidiProgramData() noexcept
;
231 void createNew(uint32_t newCount
);
232 void clear() noexcept
;
233 const MidiProgramData
& getCurrent() const noexcept
;
235 CARLA_DECLARE_NON_COPYABLE(PluginMidiProgramData
)
238 // -----------------------------------------------------------------------
240 struct CarlaPlugin::ProtectedData
{
241 CarlaEngine
* const engine
;
242 CarlaEngineClient
* client
;
262 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
263 int32_t midiLearnParameterIndex
;
264 uint transientTryCounter
;
265 bool transientFirstTry
;
270 const char* filename
;
271 const char* iconName
;
274 PluginAudioData audioIn
;
275 PluginAudioData audioOut
;
278 PluginEventData event
;
279 PluginParameterData param
;
280 PluginProgramData prog
;
281 PluginMidiProgramData midiprog
;
282 LinkedList
<CustomData
> custom
;
284 CarlaMutex masterMutex
; // global master lock
285 CarlaMutex singleMutex
; // small lock used only in processSingle()
287 CarlaStateSave stateSave
;
291 struct ExternalNotes
{
293 RtLinkedList
<ExternalMidiNote
>::Pool dataPool
;
294 RtLinkedList
<ExternalMidiNote
> data
;
296 ExternalNotes() noexcept
;
297 ~ExternalNotes() noexcept
;
298 void appendNonRT(const ExternalMidiNote
& note
) noexcept
;
299 void clear() noexcept
;
301 CARLA_DECLARE_NON_COPYABLE(ExternalNotes
)
315 void clearBuffers() noexcept
;
316 void recreateBuffers(uint32_t newChannels
, uint32_t newFrames
);
319 CARLA_DECLARE_NON_COPYABLE(Latency
)
325 PostRtEvents() noexcept
;
326 ~PostRtEvents() noexcept
;
327 void appendRT(const PluginPostRtEvent
& event
) noexcept
;
328 void trySplice() noexcept
;
331 Access(PostRtEvents
& e
)
333 poolMutex(e
.poolMutex
)
335 const CarlaMutexLocker
cml1(e
.dataMutex
);
336 const CarlaMutexLocker
cml2(e
.poolMutex
);
338 if (e
.data
.isNotEmpty())
339 e
.data
.moveTo(data2
, true);
344 const CarlaMutexLocker
cml(poolMutex
);
349 inline RtLinkedList
<PluginPostRtEvent
>::Itenerator
getDataIterator() const noexcept
351 return data2
.begin2();
354 inline std::size_t isEmpty() const noexcept
356 return data2
.isEmpty();
360 RtLinkedList
<PluginPostRtEvent
> data2
;
361 CarlaMutex
& poolMutex
;
365 RtLinkedList
<PluginPostRtEvent
>::Pool dataPool
;
366 RtLinkedList
<PluginPostRtEvent
> data
, dataPendingRT
;
367 CarlaMutex dataMutex
;
368 CarlaMutex dataPendingMutex
;
369 CarlaMutex poolMutex
;
371 CARLA_DECLARE_NON_COPYABLE(PostRtEvents
)
375 struct PostUiEvents
{
377 LinkedList
<PluginPostRtEvent
> data
;
379 PostUiEvents() noexcept
;
380 ~PostUiEvents() noexcept
;
381 void append(const PluginPostRtEvent
& event
) noexcept
;
382 void clear() noexcept
;
384 CARLA_DECLARE_NON_COPYABLE(PostUiEvents
)
388 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
399 CARLA_DECLARE_NON_COPYABLE(PostProc
)
404 ProtectedData(CarlaEngine
* engine
, uint idx
) noexcept
;
405 ~ProtectedData() noexcept
;
407 // -------------------------------------------------------------------
410 void clearBuffers() noexcept
;
412 // -------------------------------------------------------------------
415 void postponeRtEvent(const PluginPostRtEvent
& rtEvent
) noexcept
;
416 void postponeParameterChangeRtEvent(bool sendCallbackLater
, int32_t index
, float value
) noexcept
;
417 void postponeProgramChangeRtEvent(bool sendCallbackLater
, uint32_t index
) noexcept
;
418 void postponeMidiProgramChangeRtEvent(bool sendCallbackLater
, uint32_t index
) noexcept
;
419 void postponeNoteOnRtEvent(bool sendCallbackLater
, uint8_t channel
, uint8_t note
, uint8_t velocity
) noexcept
;
420 void postponeNoteOffRtEvent(bool sendCallbackLater
, uint8_t channel
, uint8_t note
) noexcept
;
421 void postponeMidiLearnRtEvent(bool sendCallbackLater
, uint32_t parameter
, uint8_t cc
, uint8_t channel
) noexcept
;
423 // -------------------------------------------------------------------
426 static const char* libError(const char* filename
) noexcept
;
428 bool libOpen(const char* filename
) noexcept
;
429 bool libClose() noexcept
;
430 void setCanDeleteLib(bool canDelete
) noexcept
;
432 bool uiLibOpen(const char* filename
, bool canDelete
) noexcept
;
433 bool uiLibClose() noexcept
;
435 template<typename Func
>
436 Func
libSymbol(const char* symbol
) const noexcept
438 return lib_symbol
<Func
>(lib
, symbol
);
441 template<typename Func
>
442 Func
uiLibSymbol(const char* symbol
) const noexcept
444 return lib_symbol
<Func
>(uiLib
, symbol
);
447 // -------------------------------------------------------------------
450 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
451 void tryTransient() noexcept
;
453 void updateParameterValues(CarlaPlugin
* plugin
,
454 bool sendCallback
, bool sendOsc
, bool useDefault
) noexcept
;
455 void updateDefaultParameterValues(CarlaPlugin
* plugin
) noexcept
;
457 // -------------------------------------------------------------------
459 #ifdef CARLA_PROPER_CPP11_SUPPORT
460 ProtectedData() = delete;
461 CARLA_DECLARE_NON_COPYABLE(ProtectedData
);
463 CARLA_LEAK_DETECTOR(ProtectedData
);
466 CARLA_BACKEND_END_NAMESPACE
468 #endif // CARLA_PLUGIN_INTERNAL_HPP_INCLUDED