DISTRHO Plugin Framework
DistrhoPlugin.hpp
1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
4  *
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.
8  *
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.
15  */
16 
17 #ifndef DISTRHO_PLUGIN_HPP_INCLUDED
18 #define DISTRHO_PLUGIN_HPP_INCLUDED
19 
20 #include "DistrhoDetails.hpp"
21 #include "extra/LeakDetector.hpp"
22 #include "src/DistrhoPluginChecks.h"
23 
25 
26 /* ------------------------------------------------------------------------------------------------------------
27  * DPF Plugin */
28 
29 /**
30  @defgroup MainClasses Main Classes
31  @{
32  */
33 
34 /**
35  DPF Plugin class from where plugin instances are created.
36 
37  The public methods (Host state) are called from the plugin to get or set host information.@n
38  They can be called from a plugin instance at anytime unless stated otherwise.@n
39  All other methods are to be implemented by the plugin and will be called by the host.
40 
41  Shortly after a plugin instance is created, the various init* functions will be called by the host.@n
42  Host will call activate() before run(), and deactivate() before the plugin instance is destroyed.@n
43  The host may call deactivate right after activate and vice-versa, but never activate/deactivate consecutively.@n
44  There is no limit on how many times run() is called, only that activate/deactivate will be called in between.
45 
46  The buffer size and sample rate values will remain constant between activate and deactivate.@n
47  Buffer size is only a hint though, the host might call run() with a higher or lower number of frames.
48 
49  Some of this class functions are only available according to some macros.
50 
51  DISTRHO_PLUGIN_WANT_PROGRAMS activates program related features.@n
52  When enabled you need to implement initProgramName() and loadProgram().
53 
54  DISTRHO_PLUGIN_WANT_STATE activates internal state features.@n
55  When enabled you need to implement initState() and setState().
56 
57  The process function run() changes wherever DISTRHO_PLUGIN_WANT_MIDI_INPUT is enabled or not.@n
58  When enabled it provides midi input events.
59  */
60 class Plugin
61 {
62 public:
63  /**
64  Plugin class constructor.@n
65  You must set all parameter values to their defaults, matching ParameterRanges::def.
66  */
67  Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount);
68 
69  /**
70  Destructor.
71  */
72  virtual ~Plugin();
73 
74  /* --------------------------------------------------------------------------------------------------------
75  * Host state */
76 
77  /**
78  Get the current buffer size that will probably be used during processing, in frames.@n
79  This value will remain constant between activate and deactivate.
80  @note This value is only a hint!@n
81  Hosts might call run() with a higher or lower number of frames.
82  @see bufferSizeChanged(uint32_t)
83  */
84  uint32_t getBufferSize() const noexcept;
85 
86  /**
87  Get the current sample rate that will be used during processing.@n
88  This value will remain constant between activate and deactivate.
89  @see sampleRateChanged(double)
90  */
91  double getSampleRate() const noexcept;
92 
93  /**
94  Get the bundle path where the plugin resides.
95  Can return null if the plugin is not available in a bundle (if it is a single binary).
96  @see getBinaryFilename
97  @see getResourcePath
98  */
99  const char* getBundlePath() const noexcept;
100 
101  /**
102  Check if this plugin instance is a "dummy" one used for plugin meta-data/information export.@n
103  When true no processing will be done, the plugin is created only to extract information.@n
104  In DPF, LADSPA/DSSI, VST2 and VST3 formats create one global instance per plugin binary
105  while LV2 creates one when generating turtle meta-data.
106  */
107  bool isDummyInstance() const noexcept;
108 
109  /**
110  Check if this plugin instance is a "selftest" one used for automated plugin tests.@n
111  To enable this mode build with `DPF_RUNTIME_TESTING` macro defined (i.e. set as compiler build flag),
112  and run the JACK/Standalone executable with "selftest" as its only and single argument.
113 
114  A few basic DSP and UI tests will run in self-test mode, with once instance having this function returning true.@n
115  You can use this chance to do a few tests of your own as well.
116  */
117  bool isSelfTestInstance() const noexcept;
118 
119 #if DISTRHO_PLUGIN_WANT_TIMEPOS
120  /**
121  Get the current host transport time position.@n
122  This function should only be called during run().@n
123  You can call this during other times, but the returned position is not guaranteed to be in sync.
124  @note TimePosition is not supported in LADSPA and DSSI plugin formats.
125  */
126  const TimePosition& getTimePosition() const noexcept;
127 #endif
128 
129 #if DISTRHO_PLUGIN_WANT_LATENCY
130  /**
131  Change the plugin audio output latency to @a frames.@n
132  This function should only be called in the constructor, activate() and run().
133  @note This function is only available if DISTRHO_PLUGIN_WANT_LATENCY is enabled.
134  */
135  void setLatency(uint32_t frames) noexcept;
136 #endif
137 
138 #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
139  /**
140  Write a MIDI output event.@n
141  This function must only be called during run().@n
142  Returns false when the host buffer is full, in which case do not call this again until the next run().
143  */
144  bool writeMidiEvent(const MidiEvent& midiEvent) noexcept;
145 #endif
146 
147 #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
148  /**
149  Check if parameter value change requests will work with the current plugin host.
150  @note This function is only available if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST is enabled.
151  @see requestParameterValueChange(uint32_t, float)
152  */
153  bool canRequestParameterValueChanges() const noexcept;
154 
155  /**
156  Request a parameter value change from the host.
157  If successful, this function will automatically trigger a parameter update on the UI side as well.
158  This function can fail, for example if the host is busy with the parameter for read-only automation.
159  Some hosts simply do not have this functionality, which can be verified with canRequestParameterValueChanges().
160  @note This function is only available if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST is enabled.
161  */
162  bool requestParameterValueChange(uint32_t index, float value) noexcept;
163 #endif
164 
165 #if DISTRHO_PLUGIN_WANT_STATE
166  /**
167  Set state value and notify the host about the change.@n
168  This function will call `setState()` and also trigger an update on the UI side as necessary.@n
169  It must not be called during run.@n
170  The state must be host readable.
171  @note this function does nothing on DSSI plugin format, as DSSI only supports UI->DSP messages.
172 
173  TODO API under construction
174  */
175  bool updateStateValue(const char* key, const char* value) noexcept;
176 #endif
177 
178 protected:
179  /* --------------------------------------------------------------------------------------------------------
180  * Information */
181 
182  /**
183  Get the plugin name.@n
184  Returns DISTRHO_PLUGIN_NAME by default.
185  */
186  virtual const char* getName() const { return DISTRHO_PLUGIN_NAME; }
187 
188  /**
189  Get the plugin label.@n
190  This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
191  */
192  virtual const char* getLabel() const = 0;
193 
194  /**
195  Get an extensive comment/description about the plugin.@n
196  Optional, returns nothing by default.
197  */
198  virtual const char* getDescription() const { return ""; }
199 
200  /**
201  Get the plugin author/maker.
202  */
203  virtual const char* getMaker() const = 0;
204 
205  /**
206  Get the plugin homepage.@n
207  Optional, returns nothing by default.
208  */
209  virtual const char* getHomePage() const { return ""; }
210 
211  /**
212  Get the plugin license (a single line of text or a URL).@n
213  For commercial plugins this should return some short copyright information.
214  */
215  virtual const char* getLicense() const = 0;
216 
217  /**
218  Get the plugin version, in hexadecimal.
219  @see d_version()
220  */
221  virtual uint32_t getVersion() const = 0;
222 
223  /**
224  Get the plugin unique Id.@n
225  This value is used by LADSPA, DSSI, VST2, VST3 and AUv2 plugin formats.@n
226  @note It is preferred that you set DISTRHO_PLUGIN_UNIQUE_ID macro instead of overriding this call,
227  as that is required for AUv2 plugins anyhow.
228  @see d_cconst()
229  */
230  #ifdef DISTRHO_PLUGIN_UNIQUE_ID
231  virtual int64_t getUniqueId() const
232  {
233  return d_cconst(STRINGIFY(DISTRHO_PLUGIN_UNIQUE_ID));
234  }
235  #else
236  virtual int64_t getUniqueId() const = 0;
237  #endif
238 
239  /* --------------------------------------------------------------------------------------------------------
240  * Init */
241 
242  /**
243  Initialize the audio port @a index.@n
244  This function will be called once, shortly after the plugin is created.
245  */
246  virtual void initAudioPort(bool input, uint32_t index, AudioPort& port);
247 
248  /**
249  Initialize the parameter @a index.@n
250  This function will be called once, shortly after the plugin is created.
251  */
252  virtual void initParameter(uint32_t index, Parameter& parameter);
253 
254  /**
255  Initialize the port group @a groupId.@n
256  This function will be called once,
257  shortly after the plugin is created and all audio ports and parameters have been enumerated.
258  */
259  virtual void initPortGroup(uint32_t groupId, PortGroup& portGroup);
260 
261 #if DISTRHO_PLUGIN_WANT_PROGRAMS
262  /**
263  Set the name of the program @a index.@n
264  This function will be called once, shortly after the plugin is created.@n
265  Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_PROGRAMS is enabled.
266  */
267  virtual void initProgramName(uint32_t index, String& programName) = 0;
268 #endif
269 
270 #if DISTRHO_PLUGIN_WANT_STATE
271  /**
272  Initialize the state @a index.@n
273  This function will be called once, shortly after the plugin is created.@n
274  Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled.
275  */
276  virtual void initState(uint32_t index, State& state);
277 
278  DISTRHO_DEPRECATED_BY("initState(uint32_t,State&)")
279  virtual void initState(uint32_t, String&, String&) {}
280 
281  DISTRHO_DEPRECATED_BY("initState(uint32_t,State&)")
282  virtual bool isStateFile(uint32_t) { return false; }
283 #endif
284 
285  /* --------------------------------------------------------------------------------------------------------
286  * Internal data */
287 
288  /**
289  Get the current value of a parameter.@n
290  The host may call this function from any context, including realtime processing.
291  */
292  virtual float getParameterValue(uint32_t index) const;
293 
294  /**
295  Change a parameter value.@n
296  The host may call this function from any context, including realtime processing.@n
297  When a parameter is marked as automatable, you must ensure no non-realtime operations are performed.
298  @note This function will only be called for parameter inputs.
299  */
300  virtual void setParameterValue(uint32_t index, float value);
301 
302 #if DISTRHO_PLUGIN_WANT_PROGRAMS
303  /**
304  Load a program.@n
305  The host may call this function from any context, including realtime processing.@n
306  Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_PROGRAMS is enabled.
307  */
308  virtual void loadProgram(uint32_t index);
309 #endif
310 
311 #if DISTRHO_PLUGIN_WANT_FULL_STATE
312  /**
313  Get the value of an internal state.@n
314  The host may call this function from any non-realtime context.@n
315  Must be implemented by your plugin class if DISTRHO_PLUGIN_WANT_FULL_STATE is enabled.
316  @note The use of this function breaks compatibility with the DSSI format.
317  */
318  virtual String getState(const char* key) const;
319 #endif
320 
321 #if DISTRHO_PLUGIN_WANT_STATE
322  /**
323  Change an internal state @a key to @a value.@n
324  Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled.
325  */
326  virtual void setState(const char* key, const char* value);
327 #endif
328 
329  /* --------------------------------------------------------------------------------------------------------
330  * Audio/MIDI Processing */
331 
332  /**
333  Activate this plugin.
334  */
335  virtual void activate() {}
336 
337  /**
338  Deactivate this plugin.
339  */
340  virtual void deactivate() {}
341 
342 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
343  /**
344  Run/process function for plugins with MIDI input.
345  @note Some parameters might be null if there are no audio inputs/outputs or MIDI events.
346  */
347  virtual void run(const float** inputs, float** outputs, uint32_t frames,
348  const MidiEvent* midiEvents, uint32_t midiEventCount) = 0;
349 #else
350  /**
351  Run/process function for plugins without MIDI input.
352  @note Some parameters might be null if there are no audio inputs or outputs.
353  */
354  virtual void run(const float** inputs, float** outputs, uint32_t frames) = 0;
355 #endif
356 
357  /* --------------------------------------------------------------------------------------------------------
358  * Callbacks (optional) */
359 
360  /**
361  Optional callback to inform the plugin about a buffer size change.@n
362  This function will only be called when the plugin is deactivated.
363  @note This value is only a hint!@n
364  Hosts might call run() with a higher or lower number of frames.
365  @see getBufferSize()
366  */
367  virtual void bufferSizeChanged(uint32_t newBufferSize);
368 
369  /**
370  Optional callback to inform the plugin about a sample rate change.@n
371  This function will only be called when the plugin is deactivated.
372  @see getSampleRate()
373  */
374  virtual void sampleRateChanged(double newSampleRate);
375 
376  /**
377  Optional callback to inform the plugin about audio port IO changes.@n
378  This function will only be called when the plugin is deactivated.@n
379  Only used in AU (AudioUnit) format when DISTRHO_PLUGIN_EXTRA_IO is defined.
380  @see DISTRHO_PLUGIN_EXTRA_IO
381  */
382  virtual void ioChanged(uint16_t numInputs, uint16_t numOutputs);
383 
384  // -------------------------------------------------------------------------------------------------------
385 
386 private:
387  struct PrivateData;
388  PrivateData* const pData;
389  friend class PluginExporter;
390 
391  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Plugin)
392 };
393 
394 /** @} */
395 
396 /* ------------------------------------------------------------------------------------------------------------
397  * Create plugin, entry point */
398 
399 /**
400  @defgroup EntryPoints Entry Points
401  @{
402  */
403 
404 /**
405  Create an instance of the Plugin class.@n
406  This is the entry point for DPF plugins.@n
407  DPF will call this to either create an instance of your plugin for the host
408  or to fetch some initial information for internal caching.
409  */
411 
412 /** @} */
413 
414 // -----------------------------------------------------------------------------------------------------------
415 
417 
418 #endif // DISTRHO_PLUGIN_HPP_INCLUDED
Definition: DistrhoPlugin.hpp:61
virtual const char * getLabel() const =0
bool writeMidiEvent(const MidiEvent &midiEvent) noexcept
virtual void run(const float **inputs, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount)=0
uint32_t getBufferSize() const noexcept
void setLatency(uint32_t frames) noexcept
virtual void sampleRateChanged(double newSampleRate)
virtual const char * getDescription() const
Definition: DistrhoPlugin.hpp:198
double getSampleRate() const noexcept
virtual void loadProgram(uint32_t index)
virtual void initProgramName(uint32_t index, String &programName)=0
bool canRequestParameterValueChanges() const noexcept
const char * getBundlePath() const noexcept
virtual const char * getLicense() const =0
virtual void initPortGroup(uint32_t groupId, PortGroup &portGroup)
virtual void initAudioPort(bool input, uint32_t index, AudioPort &port)
virtual void setParameterValue(uint32_t index, float value)
virtual ~Plugin()
bool isSelfTestInstance() const noexcept
virtual const char * getMaker() const =0
virtual String getState(const char *key) const
virtual void bufferSizeChanged(uint32_t newBufferSize)
virtual void deactivate()
Definition: DistrhoPlugin.hpp:340
virtual void activate()
Definition: DistrhoPlugin.hpp:335
bool updateStateValue(const char *key, const char *value) noexcept
virtual void initParameter(uint32_t index, Parameter &parameter)
bool isDummyInstance() const noexcept
virtual uint32_t getVersion() const =0
virtual void ioChanged(uint16_t numInputs, uint16_t numOutputs)
Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount)
virtual const char * getHomePage() const
Definition: DistrhoPlugin.hpp:209
virtual void initState(uint32_t index, State &state)
virtual int64_t getUniqueId() const =0
bool requestParameterValueChange(uint32_t index, float value) noexcept
const TimePosition & getTimePosition() const noexcept
virtual const char * getName() const
Definition: DistrhoPlugin.hpp:186
virtual float getParameterValue(uint32_t index) const
virtual void setState(const char *key, const char *value)
Definition: String.hpp:35
Plugin * createPlugin()
static constexpr int64_t d_cconst(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) noexcept
Definition: DistrhoUtils.hpp:72
#define END_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:949
#define START_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:943
#define DISTRHO_PLUGIN_UNIQUE_ID
Definition: DistrhoInfo.hpp:691
#define DISTRHO_PLUGIN_NAME
Definition: DistrhoInfo.hpp:488
Definition: DistrhoDetails.hpp:275
Definition: DistrhoDetails.hpp:891
Definition: DistrhoDetails.hpp:588
Definition: DistrhoDetails.hpp:797
Definition: DistrhoDetails.hpp:823
Definition: DistrhoDetails.hpp:925