DPF

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

ExamplePluginCVPort.cpp (8494B)


      1 /*
      2  * DISTRHO Plugin Framework (DPF)
      3  * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
      4  * Copyright (C) 2020 Takamitsu Endo
      5  *
      6  * Permission to use, copy, modify, and/or distribute this software for any purpose with
      7  * or without fee is hereby granted, provided that the above copyright notice and this
      8  * permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
     11  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
     12  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     14  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     15  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  */
     17 
     18 #include "DistrhoPlugin.hpp"
     19 
     20 START_NAMESPACE_DISTRHO
     21 
     22 // -----------------------------------------------------------------------------------------------------------
     23 
     24 static constexpr const float kMaxHoldTime = 1.0f;
     25 
     26 /**
     27   Simple plugin to demonstrate how to modify input/output port type in DPF.
     28   The plugin outputs sample & hold (S&H) value of input signal.
     29   User can specify hold time via parameter and/or Hold Time CV port.
     30  */
     31 class ExamplePluginCVPort : public Plugin
     32 {
     33 public:
     34     ExamplePluginCVPort()
     35         : Plugin(1, 0, 0), // 1 parameters, 0 programs, 0 states
     36           counter(0),
     37           holdTime(0.0f),
     38           holdValue(0.0f),
     39           sampleRate(getSampleRate()) {}
     40 
     41 protected:
     42    /* --------------------------------------------------------------------------------------------------------
     43     * Information */
     44 
     45    /**
     46       Get the plugin label.
     47       A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
     48     */
     49     const char* getLabel() const override
     50     {
     51         return "CVPort";
     52     }
     53 
     54    /**
     55       Get an extensive comment/description about the plugin.
     56     */
     57     const char* getDescription() const override
     58     {
     59         return "Simple plugin with CVPort.\nThe plugin does sample & hold processing.";
     60     }
     61 
     62    /**
     63       Get the plugin author/maker.
     64     */
     65     const char* getMaker() const override
     66     {
     67         return "DISTRHO";
     68     }
     69 
     70    /**
     71       Get the plugin homepage.
     72     */
     73     const char* getHomePage() const override
     74     {
     75         return "https://github.com/DISTRHO/DPF";
     76     }
     77 
     78    /**
     79       Get the plugin license name (a single line of text).
     80       For commercial plugins this should return some short copyright information.
     81     */
     82     const char* getLicense() const override
     83     {
     84         return "ISC";
     85     }
     86 
     87    /**
     88       Get the plugin version, in hexadecimal.
     89     */
     90     uint32_t getVersion() const override
     91     {
     92         return d_version(1, 0, 0);
     93     }
     94 
     95    /**
     96       Get the plugin unique Id.
     97       This value is used by LADSPA, DSSI and VST plugin formats.
     98     */
     99     int64_t getUniqueId() const override
    100     {
    101         return d_cconst('d', 'C', 'V', 'P');
    102     }
    103 
    104    /* --------------------------------------------------------------------------------------------------------
    105     * Init */
    106 
    107    /**
    108       Initialize the audio port @a index.@n
    109       This function will be called once, shortly after the plugin is created.
    110     */
    111     void initAudioPort(bool input, uint32_t index, AudioPort& port) override
    112     {
    113        /**
    114           Note that index is independent for input and output.
    115           In other words, input port index starts from 0 and output port index also starts from 0.
    116         */
    117         if (input)
    118         {
    119             switch (index)
    120             {
    121             case 0:
    122                 // Audio port doesn't need to specify port.hints.
    123                 port.name    = "Audio Input";
    124                 port.symbol  = "audio_in";
    125                 return;
    126             case 1:
    127                 port.hints   = kAudioPortIsCV;
    128                 port.name    = "Hold Time";
    129                 port.symbol  = "hold_time";
    130                 return;
    131             }
    132             // Add more conditions here when increasing DISTRHO_PLUGIN_NUM_INPUTS.
    133         }
    134         else
    135         {
    136             switch (index)
    137             {
    138             case 0:
    139                 port.hints   = kAudioPortIsCV;
    140                 port.name    = "CV Output";
    141                 port.symbol  = "cv_out";
    142                 return;
    143             }
    144             // Add more conditions here when increasing DISTRHO_PLUGIN_NUM_OUTPUTS.
    145         }
    146 
    147         // It shouldn't reach here, but just in case if index is greater than 0.
    148         Plugin::initAudioPort(input, index, port);
    149     }
    150 
    151    /**
    152       Initialize the parameter @a index.
    153       This function will be called once, shortly after the plugin is created.
    154     */
    155     void initParameter(uint32_t index, Parameter& parameter) override
    156     {
    157         if (index != 0)
    158             return;
    159 
    160         parameter.name       = "Hold Time";
    161         parameter.symbol     = "hold_time";
    162         parameter.hints      = kParameterIsAutomatable|kParameterIsLogarithmic;
    163         parameter.ranges.min = 0.0f;
    164         parameter.ranges.max = kMaxHoldTime;
    165         parameter.ranges.def = 0.1f;
    166     }
    167 
    168    /* --------------------------------------------------------------------------------------------------------
    169     * Internal data */
    170 
    171    /**
    172       Get the current value of a parameter.
    173     */
    174     float getParameterValue(uint32_t index) const override
    175     {
    176         if (index != 0)
    177             return 0.0f;
    178 
    179         return holdTime;
    180     }
    181 
    182    /**
    183       Change a parameter value.
    184     */
    185     void setParameterValue(uint32_t index, float value) override
    186     {
    187         if (index != 0)
    188             return;
    189 
    190         holdTime = value;
    191         counter = uint32_t(holdTime * sampleRate);
    192     }
    193 
    194    /* --------------------------------------------------------------------------------------------------------
    195     * Process */
    196 
    197    /**
    198       Run/process function for plugins without MIDI input.
    199     */
    200     void run(const float** inputs, float** outputs, uint32_t frames) override
    201     {
    202         float cv, time;
    203 
    204        /**
    205         - inputs[0] is input audio port.
    206         - inputs[1] is hold time CV port.
    207         - outputs[0] is output CV port.
    208         */
    209        const float* const audioIn = inputs[0];
    210        const float* const holdCV = inputs[1];
    211        float* const cvOut = outputs[0];
    212 
    213         for (uint32_t i = 0; i < frames; ++i)
    214         {
    215             if (counter == 0)
    216             {
    217                 cv = holdCV[i] > 0.0f ? holdCV[i] : 0.0f;
    218 
    219                 time = holdTime + cv;
    220                 if (time > kMaxHoldTime)
    221                     time = kMaxHoldTime;
    222 
    223                 counter = static_cast<uint32_t>(time * sampleRate + 0.5f);
    224 
    225                 holdValue = audioIn[i]; // Refresh hold value.
    226             }
    227             else
    228             {
    229                 --counter;
    230             }
    231 
    232             cvOut[i] = holdValue;
    233         }
    234     }
    235 
    236    /* --------------------------------------------------------------------------------------------------------
    237     * Callbacks (optional) */
    238 
    239    /**
    240       Optional callback to inform the plugin about a sample rate change.@n
    241       This function will only be called when the plugin is deactivated.
    242     */
    243     void sampleRateChanged(double newSampleRate) override
    244     {
    245         sampleRate = newSampleRate;
    246         counter = static_cast<uint32_t>(holdTime * sampleRate + 0.5f);
    247     }
    248 
    249     // -------------------------------------------------------------------------------------------------------
    250 
    251 private:
    252     uint32_t counter; // Hold time in samples. Used to count hold time.
    253     float holdTime;  // Hold time in seconds.
    254     float holdValue;
    255     float sampleRate;
    256 
    257    /**
    258       Set our plugin class as non-copyable and add a leak detector just in case.
    259     */
    260     DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginCVPort)
    261 };
    262 
    263 /* ------------------------------------------------------------------------------------------------------------
    264  * Plugin entry point, called by DPF to create a new plugin instance. */
    265 
    266 Plugin* createPlugin()
    267 {
    268     return new ExamplePluginCVPort();
    269 }
    270 
    271 // -----------------------------------------------------------------------------------------------------------
    272 
    273 END_NAMESPACE_DISTRHO