DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

DistrhoPlugin.hpp (15654B)


      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 
     24 START_NAMESPACE_DISTRHO
     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  */
    410 extern Plugin* createPlugin();
    411 
    412 /** @} */
    413 
    414 // -----------------------------------------------------------------------------------------------------------
    415 
    416 END_NAMESPACE_DISTRHO
    417 
    418 #endif // DISTRHO_PLUGIN_HPP_INCLUDED