2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED
18 #define DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED
20 #include "../DistrhoPlugin.hpp"
22 #ifdef DISTRHO_PLUGIN_TARGET_VST3
23 # include "DistrhoPluginVST.hpp"
28 START_NAMESPACE_DISTRHO
30 // -----------------------------------------------------------------------
33 static const uint32_t kMaxMidiEvents
= 512;
35 // -----------------------------------------------------------------------
36 // Static data, see DistrhoPlugin.cpp
38 extern uint32_t d_nextBufferSize
;
39 extern double d_nextSampleRate
;
40 extern const char* d_nextBundlePath
;
41 extern bool d_nextPluginIsDummy
;
42 extern bool d_nextCanRequestParameterValueChanges
;
44 // -----------------------------------------------------------------------
47 typedef bool (*writeMidiFunc
) (void* ptr
, const MidiEvent
& midiEvent
);
48 typedef bool (*requestParameterValueChangeFunc
) (void* ptr
, uint32_t index
, float value
);
49 typedef bool (*updateStateValueFunc
) (void* ptr
, const char* key
, const char* value
);
51 // -----------------------------------------------------------------------
54 struct AudioPortWithBusId
: AudioPort
{
62 struct PortGroupWithId
: PortGroup
{
67 groupId(kPortGroupNone
) {}
70 static void fillInPredefinedPortGroupData(const uint32_t groupId
, PortGroup
& portGroup
)
75 portGroup
.name
.clear();
76 portGroup
.symbol
.clear();
79 portGroup
.name
= "Mono";
80 portGroup
.symbol
= "dpf_mono";
82 case kPortGroupStereo
:
83 portGroup
.name
= "Stereo";
84 portGroup
.symbol
= "dpf_stereo";
89 // -----------------------------------------------------------------------
90 // Plugin private data
92 struct Plugin::PrivateData
{
93 const bool canRequestParameterValueChanges
;
97 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
98 AudioPortWithBusId
* audioPorts
;
101 uint32_t parameterCount
;
102 uint32_t parameterOffset
;
103 Parameter
* parameters
;
105 uint32_t portGroupCount
;
106 PortGroupWithId
* portGroups
;
108 #if DISTRHO_PLUGIN_WANT_PROGRAMS
109 uint32_t programCount
;
110 String
* programNames
;
113 #if DISTRHO_PLUGIN_WANT_STATE
118 #if DISTRHO_PLUGIN_WANT_LATENCY
122 #if DISTRHO_PLUGIN_WANT_TIMEPOS
123 TimePosition timePosition
;
128 writeMidiFunc writeMidiCallbackFunc
;
129 requestParameterValueChangeFunc requestParameterValueChangeCallbackFunc
;
130 updateStateValueFunc updateStateValueCallbackFunc
;
136 PrivateData() noexcept
137 : canRequestParameterValueChanges(d_nextCanRequestParameterValueChanges
),
138 isDummy(d_nextPluginIsDummy
),
140 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
148 #if DISTRHO_PLUGIN_WANT_PROGRAMS
150 programNames(nullptr),
152 #if DISTRHO_PLUGIN_WANT_STATE
156 #if DISTRHO_PLUGIN_WANT_LATENCY
159 callbacksPtr(nullptr),
160 writeMidiCallbackFunc(nullptr),
161 requestParameterValueChangeCallbackFunc(nullptr),
162 updateStateValueCallbackFunc(nullptr),
163 bufferSize(d_nextBufferSize
),
164 sampleRate(d_nextSampleRate
),
165 bundlePath(d_nextBundlePath
!= nullptr ? strdup(d_nextBundlePath
) : nullptr)
167 DISTRHO_SAFE_ASSERT(bufferSize
!= 0);
168 DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate
));
170 #if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)
171 parameterOffset
+= DISTRHO_PLUGIN_NUM_INPUTS
+ DISTRHO_PLUGIN_NUM_OUTPUTS
;
172 # if DISTRHO_PLUGIN_WANT_LATENCY
173 parameterOffset
+= 1;
177 #ifdef DISTRHO_PLUGIN_TARGET_LV2
178 # if (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_STATE || DISTRHO_PLUGIN_WANT_TIMEPOS)
179 parameterOffset
+= 1;
181 # if (DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || DISTRHO_PLUGIN_WANT_STATE)
182 parameterOffset
+= 1;
186 #ifdef DISTRHO_PLUGIN_TARGET_VST3
187 parameterOffset
+= kVst3InternalParameterCount
;
191 ~PrivateData() noexcept
193 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
194 if (audioPorts
!= nullptr)
197 audioPorts
= nullptr;
201 if (parameters
!= nullptr)
204 parameters
= nullptr;
207 if (portGroups
!= nullptr)
210 portGroups
= nullptr;
213 #if DISTRHO_PLUGIN_WANT_PROGRAMS
214 if (programNames
!= nullptr)
216 delete[] programNames
;
217 programNames
= nullptr;
221 #if DISTRHO_PLUGIN_WANT_STATE
222 if (states
!= nullptr)
229 if (bundlePath
!= nullptr)
231 std::free(bundlePath
);
232 bundlePath
= nullptr;
236 #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
237 bool writeMidiCallback(const MidiEvent
& midiEvent
)
239 if (writeMidiCallbackFunc
!= nullptr)
240 return writeMidiCallbackFunc(callbacksPtr
, midiEvent
);
246 #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
247 bool requestParameterValueChangeCallback(const uint32_t index
, const float value
)
249 if (requestParameterValueChangeCallbackFunc
!= nullptr)
250 return requestParameterValueChangeCallbackFunc(callbacksPtr
, index
, value
);
256 #if DISTRHO_PLUGIN_WANT_STATE
257 bool updateStateValueCallback(const char* const key
, const char* const value
)
259 d_stdout("updateStateValueCallback %p", updateStateValueCallbackFunc
);
260 if (updateStateValueCallbackFunc
!= nullptr)
261 return updateStateValueCallbackFunc(callbacksPtr
, key
, value
);
268 // -----------------------------------------------------------------------
269 // Plugin exporter class
274 PluginExporter(void* const callbacksPtr
,
275 const writeMidiFunc writeMidiCall
,
276 const requestParameterValueChangeFunc requestParameterValueChangeCall
,
277 const updateStateValueFunc updateStateValueCall
)
278 : fPlugin(createPlugin()),
279 fData((fPlugin
!= nullptr) ? fPlugin
->pData
: nullptr),
282 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
283 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
285 #if defined(DPF_RUNTIME_TESTING) && defined(__GNUC__) && !defined(__clang__)
286 /* Run-time testing build.
287 * Verify that virtual functions are overriden if parameters, programs or states are in use.
288 * This does not work on all compilers, but we use it purely as informational check anyway. */
289 if (fData
->parameterCount
!= 0)
291 if ((void*)(fPlugin
->*(&Plugin::initParameter
)) == (void*)&Plugin::initParameter
)
293 d_stderr2("DPF warning: Plugins with parameters must implement `initParameter`");
296 if ((void*)(fPlugin
->*(&Plugin::getParameterValue
)) == (void*)&Plugin::getParameterValue
)
298 d_stderr2("DPF warning: Plugins with parameters must implement `getParameterValue`");
301 if ((void*)(fPlugin
->*(&Plugin::setParameterValue
)) == (void*)&Plugin::setParameterValue
)
303 d_stderr2("DPF warning: Plugins with parameters must implement `setParameterValue`");
308 # if DISTRHO_PLUGIN_WANT_PROGRAMS
309 if (fData
->programCount
!= 0)
311 if ((void*)(fPlugin
->*(&Plugin::initProgramName
)) == (void*)&Plugin::initProgramName
)
313 d_stderr2("DPF warning: Plugins with programs must implement `initProgramName`");
316 if ((void*)(fPlugin
->*(&Plugin::loadProgram
)) == (void*)&Plugin::loadProgram
)
318 d_stderr2("DPF warning: Plugins with programs must implement `loadProgram`");
324 # if DISTRHO_PLUGIN_WANT_STATE
325 if (fData
->stateCount
!= 0)
327 if ((void*)(fPlugin
->*(&Plugin::initState
)) == (void*)&Plugin::initState
)
329 d_stderr2("DPF warning: Plugins with state must implement `initState`");
333 if ((void*)(fPlugin
->*(&Plugin::setState
)) == (void*)&Plugin::setState
)
335 d_stderr2("DPF warning: Plugins with state must implement `setState`");
341 # if DISTRHO_PLUGIN_WANT_FULL_STATE
342 if (fData
->stateCount
!= 0)
344 if ((void*)(fPlugin
->*(&Plugin::getState
)) == (void*)&Plugin::getState
)
346 d_stderr2("DPF warning: Plugins with full state must implement `getState`");
352 d_stderr2("DPF warning: Plugins with full state must have at least 1 state");
358 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
361 # if DISTRHO_PLUGIN_NUM_INPUTS > 0
362 for (uint32_t i
=0; i
< DISTRHO_PLUGIN_NUM_INPUTS
; ++i
, ++j
)
363 fPlugin
->initAudioPort(true, i
, fData
->audioPorts
[j
]);
365 # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
366 for (uint32_t i
=0; i
< DISTRHO_PLUGIN_NUM_OUTPUTS
; ++i
, ++j
)
367 fPlugin
->initAudioPort(false, i
, fData
->audioPorts
[j
]);
370 #endif // DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
372 for (uint32_t i
=0, count
=fData
->parameterCount
; i
< count
; ++i
)
373 fPlugin
->initParameter(i
, fData
->parameters
[i
]);
376 std::set
<uint32_t> portGroupIndices
;
378 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
379 for (uint32_t i
=0; i
< DISTRHO_PLUGIN_NUM_INPUTS
+DISTRHO_PLUGIN_NUM_OUTPUTS
; ++i
)
380 portGroupIndices
.insert(fData
->audioPorts
[i
].groupId
);
382 for (uint32_t i
=0, count
=fData
->parameterCount
; i
< count
; ++i
)
383 portGroupIndices
.insert(fData
->parameters
[i
].groupId
);
385 portGroupIndices
.erase(kPortGroupNone
);
387 if (const uint32_t portGroupSize
= static_cast<uint32_t>(portGroupIndices
.size()))
389 fData
->portGroups
= new PortGroupWithId
[portGroupSize
];
390 fData
->portGroupCount
= portGroupSize
;
393 for (std::set
<uint32_t>::iterator it
= portGroupIndices
.begin(); it
!= portGroupIndices
.end(); ++it
, ++index
)
395 PortGroupWithId
& portGroup(fData
->portGroups
[index
]);
396 portGroup
.groupId
= *it
;
398 if (portGroup
.groupId
< portGroupSize
)
399 fPlugin
->initPortGroup(portGroup
.groupId
, portGroup
);
401 fillInPredefinedPortGroupData(portGroup
.groupId
, portGroup
);
406 #if DISTRHO_PLUGIN_WANT_PROGRAMS
407 for (uint32_t i
=0, count
=fData
->programCount
; i
< count
; ++i
)
408 fPlugin
->initProgramName(i
, fData
->programNames
[i
]);
411 #if DISTRHO_PLUGIN_WANT_STATE
412 for (uint32_t i
=0, count
=fData
->stateCount
; i
< count
; ++i
)
413 fPlugin
->initState(i
, fData
->states
[i
]);
416 fData
->callbacksPtr
= callbacksPtr
;
417 fData
->writeMidiCallbackFunc
= writeMidiCall
;
418 fData
->requestParameterValueChangeCallbackFunc
= requestParameterValueChangeCall
;
419 fData
->updateStateValueCallbackFunc
= updateStateValueCall
;
427 // -------------------------------------------------------------------
429 const char* getName() const noexcept
431 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
433 return fPlugin
->getName();
436 const char* getLabel() const noexcept
438 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
440 return fPlugin
->getLabel();
443 const char* getDescription() const noexcept
445 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
447 return fPlugin
->getDescription();
450 const char* getMaker() const noexcept
452 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
454 return fPlugin
->getMaker();
457 const char* getHomePage() const noexcept
459 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
461 return fPlugin
->getHomePage();
464 const char* getLicense() const noexcept
466 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, "");
468 return fPlugin
->getLicense();
471 uint32_t getVersion() const noexcept
473 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, 0);
475 return fPlugin
->getVersion();
478 long getUniqueId() const noexcept
480 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, 0);
482 return fPlugin
->getUniqueId();
485 void* getInstancePointer() const noexcept
490 // -------------------------------------------------------------------
492 #if DISTRHO_PLUGIN_WANT_LATENCY
493 uint32_t getLatency() const noexcept
495 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
497 return fData
->latency
;
501 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
502 AudioPortWithBusId
& getAudioPort(const bool input
, const uint32_t index
) const noexcept
504 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, sFallbackAudioPort
);
508 # if DISTRHO_PLUGIN_NUM_INPUTS > 0
509 DISTRHO_SAFE_ASSERT_RETURN(index
< DISTRHO_PLUGIN_NUM_INPUTS
, sFallbackAudioPort
);
514 # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
515 DISTRHO_SAFE_ASSERT_RETURN(index
< DISTRHO_PLUGIN_NUM_OUTPUTS
, sFallbackAudioPort
);
519 return fData
->audioPorts
[index
+ (input
? 0 : DISTRHO_PLUGIN_NUM_INPUTS
)];
522 uint32_t getAudioPortHints(const bool input
, const uint32_t index
) const noexcept
524 return getAudioPort(input
, index
).hints
;
527 uint32_t getAudioPortCountWithGroupId(const bool input
, const uint32_t groupId
) const noexcept
529 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
531 uint32_t numPorts
= 0;
535 #if DISTRHO_PLUGIN_NUM_INPUTS > 0
536 for (uint32_t i
=0; i
<DISTRHO_PLUGIN_NUM_INPUTS
; ++i
)
538 if (fData
->audioPorts
[i
].groupId
== groupId
)
545 #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
546 for (uint32_t i
=0; i
<DISTRHO_PLUGIN_NUM_OUTPUTS
; ++i
)
548 if (fData
->audioPorts
[i
+ DISTRHO_PLUGIN_NUM_INPUTS
].groupId
== groupId
)
558 uint32_t getParameterCount() const noexcept
560 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
562 return fData
->parameterCount
;
565 uint32_t getParameterOffset() const noexcept
567 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
569 return fData
->parameterOffset
;
572 uint32_t getParameterHints(const uint32_t index
) const noexcept
574 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, 0x0);
576 return fData
->parameters
[index
].hints
;
579 ParameterDesignation
getParameterDesignation(const uint32_t index
) const noexcept
581 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, kParameterDesignationNull
);
583 return fData
->parameters
[index
].designation
;
586 bool isParameterInput(const uint32_t index
) const noexcept
588 return (getParameterHints(index
) & kParameterIsOutput
) == 0x0;
591 bool isParameterOutput(const uint32_t index
) const noexcept
593 return (getParameterHints(index
) & kParameterIsOutput
) != 0x0;
596 bool isParameterTrigger(const uint32_t index
) const noexcept
598 return (getParameterHints(index
) & kParameterIsTrigger
) == kParameterIsTrigger
;
601 bool isParameterOutputOrTrigger(const uint32_t index
) const noexcept
603 const uint32_t hints
= getParameterHints(index
);
605 if (hints
& kParameterIsOutput
)
607 if ((hints
& kParameterIsTrigger
) == kParameterIsTrigger
)
613 const String
& getParameterName(const uint32_t index
) const noexcept
615 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackString
);
617 return fData
->parameters
[index
].name
;
620 const String
& getParameterShortName(const uint32_t index
) const noexcept
622 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackString
);
624 return fData
->parameters
[index
].shortName
;
627 const String
& getParameterSymbol(const uint32_t index
) const noexcept
629 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackString
);
631 return fData
->parameters
[index
].symbol
;
634 const String
& getParameterUnit(const uint32_t index
) const noexcept
636 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackString
);
638 return fData
->parameters
[index
].unit
;
641 const String
& getParameterDescription(const uint32_t index
) const noexcept
643 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackString
);
645 return fData
->parameters
[index
].description
;
648 const ParameterEnumerationValues
& getParameterEnumValues(const uint32_t index
) const noexcept
650 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackEnumValues
);
652 return fData
->parameters
[index
].enumValues
;
655 const ParameterRanges
& getParameterRanges(const uint32_t index
) const noexcept
657 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, sFallbackRanges
);
659 return fData
->parameters
[index
].ranges
;
662 uint8_t getParameterMidiCC(const uint32_t index
) const noexcept
664 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, 0);
666 return fData
->parameters
[index
].midiCC
;
669 uint32_t getParameterGroupId(const uint32_t index
) const noexcept
671 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, kPortGroupNone
);
673 return fData
->parameters
[index
].groupId
;
676 float getParameterDefault(const uint32_t index
) const
678 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, 0.0f
);
679 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, 0.0f
);
681 return fData
->parameters
[index
].ranges
.def
;
684 float getParameterValue(const uint32_t index
) const
686 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr, 0.0f
);
687 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
, 0.0f
);
689 return fPlugin
->getParameterValue(index
);
692 void setParameterValue(const uint32_t index
, const float value
)
694 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
695 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->parameterCount
,);
697 fPlugin
->setParameterValue(index
, value
);
700 uint32_t getPortGroupCount() const noexcept
702 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
704 return fData
->portGroupCount
;
707 const PortGroupWithId
& getPortGroupById(const uint32_t groupId
) const noexcept
709 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && fData
->portGroupCount
!= 0, sFallbackPortGroup
);
711 for (uint32_t i
=0; i
< fData
->portGroupCount
; ++i
)
713 const PortGroupWithId
& portGroup(fData
->portGroups
[i
]);
715 if (portGroup
.groupId
== groupId
)
719 return sFallbackPortGroup
;
722 const PortGroupWithId
& getPortGroupByIndex(const uint32_t index
) const noexcept
724 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->portGroupCount
, sFallbackPortGroup
);
726 return fData
->portGroups
[index
];
729 const String
& getPortGroupSymbolForId(const uint32_t groupId
) const noexcept
731 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, sFallbackString
);
733 return getPortGroupById(groupId
).symbol
;
736 #if DISTRHO_PLUGIN_WANT_PROGRAMS
737 uint32_t getProgramCount() const noexcept
739 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
741 return fData
->programCount
;
744 const String
& getProgramName(const uint32_t index
) const noexcept
746 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->programCount
, sFallbackString
);
748 return fData
->programNames
[index
];
751 void loadProgram(const uint32_t index
)
753 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
754 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->programCount
,);
756 fPlugin
->loadProgram(index
);
760 #if DISTRHO_PLUGIN_WANT_STATE
761 uint32_t getStateCount() const noexcept
763 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
765 return fData
->stateCount
;
768 uint32_t getStateHints(const uint32_t index
) const noexcept
770 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->stateCount
, 0x0);
772 return fData
->states
[index
].hints
;
775 const String
& getStateKey(const uint32_t index
) const noexcept
777 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->stateCount
, sFallbackString
);
779 return fData
->states
[index
].key
;
782 const String
& getStateDefaultValue(const uint32_t index
) const noexcept
784 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->stateCount
, sFallbackString
);
786 return fData
->states
[index
].defaultValue
;
789 const String
& getStateLabel(const uint32_t index
) const noexcept
791 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->stateCount
, sFallbackString
);
793 return fData
->states
[index
].label
;
796 const String
& getStateDescription(const uint32_t index
) const noexcept
798 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr && index
< fData
->stateCount
, sFallbackString
);
800 return fData
->states
[index
].description
;
803 # if DISTRHO_PLUGIN_WANT_FULL_STATE
804 String
getStateValue(const char* const key
) const
806 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, sFallbackString
);
807 DISTRHO_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0', sFallbackString
);
809 return fPlugin
->getState(key
);
813 void setState(const char* const key
, const char* const value
)
815 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
816 DISTRHO_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0',);
817 DISTRHO_SAFE_ASSERT_RETURN(value
!= nullptr,);
819 fPlugin
->setState(key
, value
);
822 bool wantStateKey(const char* const key
) const noexcept
824 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, false);
825 DISTRHO_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0', false);
827 for (uint32_t i
=0; i
< fData
->stateCount
; ++i
)
829 if (fData
->states
[i
].key
== key
)
837 #if DISTRHO_PLUGIN_WANT_TIMEPOS
838 void setTimePosition(const TimePosition
& timePosition
) noexcept
840 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
842 std::memcpy(&fData
->timePosition
, &timePosition
, sizeof(TimePosition
));
846 // -------------------------------------------------------------------
848 bool isActive() const noexcept
855 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
856 DISTRHO_SAFE_ASSERT_RETURN(! fIsActive
,);
864 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
865 DISTRHO_SAFE_ASSERT_RETURN(fIsActive
,);
868 fPlugin
->deactivate();
871 void deactivateIfNeeded()
873 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
878 fPlugin
->deactivate();
882 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
883 void run(const float** const inputs
, float** const outputs
, const uint32_t frames
,
884 const MidiEvent
* const midiEvents
, const uint32_t midiEventCount
)
886 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
887 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
895 fData
->isProcessing
= true;
896 fPlugin
->run(inputs
, outputs
, frames
, midiEvents
, midiEventCount
);
897 fData
->isProcessing
= false;
900 void run(const float** const inputs
, float** const outputs
, const uint32_t frames
)
902 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
903 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
911 fData
->isProcessing
= true;
912 fPlugin
->run(inputs
, outputs
, frames
);
913 fData
->isProcessing
= false;
917 // -------------------------------------------------------------------
919 uint32_t getBufferSize() const noexcept
921 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0);
922 return fData
->bufferSize
;
925 double getSampleRate() const noexcept
927 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr, 0.0);
928 return fData
->sampleRate
;
931 void setBufferSize(const uint32_t bufferSize
, const bool doCallback
= false)
933 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
934 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
935 DISTRHO_SAFE_ASSERT(bufferSize
>= 2);
937 if (fData
->bufferSize
== bufferSize
)
940 fData
->bufferSize
= bufferSize
;
944 if (fIsActive
) fPlugin
->deactivate();
945 fPlugin
->bufferSizeChanged(bufferSize
);
946 if (fIsActive
) fPlugin
->activate();
950 void setSampleRate(const double sampleRate
, const bool doCallback
= false)
952 DISTRHO_SAFE_ASSERT_RETURN(fData
!= nullptr,);
953 DISTRHO_SAFE_ASSERT_RETURN(fPlugin
!= nullptr,);
954 DISTRHO_SAFE_ASSERT(sampleRate
> 0.0);
956 if (d_isEqual(fData
->sampleRate
, sampleRate
))
959 fData
->sampleRate
= sampleRate
;
963 if (fIsActive
) fPlugin
->deactivate();
964 fPlugin
->sampleRateChanged(sampleRate
);
965 if (fIsActive
) fPlugin
->activate();
970 // -------------------------------------------------------------------
971 // Plugin and DistrhoPlugin data
973 Plugin
* const fPlugin
;
974 Plugin::PrivateData
* const fData
;
977 // -------------------------------------------------------------------
978 // Static fallback data, see DistrhoPlugin.cpp
980 static const String sFallbackString
;
981 static /* */ AudioPortWithBusId sFallbackAudioPort
;
982 static const ParameterRanges sFallbackRanges
;
983 static const ParameterEnumerationValues sFallbackEnumValues
;
984 static const PortGroupWithId sFallbackPortGroup
;
986 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter
)
989 // -----------------------------------------------------------------------
991 END_NAMESPACE_DISTRHO
993 #endif // DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED