DISTRHO Plugin Framework (or DPF for short) is a plugin framework designed to make development of new plugins an easy and enjoyable task.
It allows developers to create plugins with custom UIs using a simple C++ API.
The framework facilitates exporting various different plugin formats from the same code-base.
DPF can build for LADSPA, DSSI, LV2, VST2, VST3 and CLAP formats.
A JACK/Standalone mode is also available, allowing you to quickly test plugins.
Macros
You start by creating a "DistrhoPluginInfo.h" file describing the plugin via macros, see PluginMacros.
This file is included during compilation of the main DPF code to select which features to activate for each plugin format.
For example, a plugin (with UI) that use states will require LV2 hosts to support Atom and Worker extensions for message passing from the UI to the (DSP) plugin.
If your plugin does not make use of states, the Worker extension is not set as a required feature.
Plugin
The next step is to create your plugin code by subclassing DPF's Plugin class.
You need to pass the number of parameters in the constructor and also the number of programs and states, if any.
Do note all of DPF code is within its own C++ namespace (DISTRHO for DSP/plugin stuff, DGL for UI stuff).
You can use START_NAMESPACE_DISTRHO / END_NAMESPACE_DISTRHO combo around your code, or globally set USE_NAMESPACE_DISTRHO.
These are defined as compiler macros so that you can override the namespace name during build. When in doubt, just follow the examples.
Examples
Let's begin with some examples.
Here is one of a stereo audio plugin that simply mutes the host output:
#include "DistrhoPlugin.hpp"
class MutePlugin :
public Plugin
{
public:
MutePlugin()
{
}
protected:
{
return "Mute";
}
{
return "DPF";
}
{
return "MIT";
}
{
}
{
}
void run(
const float**,
float** outputs, uint32_t frames)
override
{
float* const outL = outputs[0];
float* const outR = outputs[1];
std::memset(outL, 0, sizeof(float)*frames);
std::memset(outR, 0, sizeof(float)*frames);
}
};
{
return new MutePlugin();
}
Definition: DistrhoPlugin.hpp:61
virtual const char * getLabel() const =0
virtual void run(const float **inputs, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount)=0
virtual const char * getLicense() const =0
virtual const char * getMaker() const =0
virtual uint32_t getVersion() const =0
virtual int64_t getUniqueId() const =0
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
static constexpr uint32_t d_version(const uint8_t major, const uint8_t minor, const uint8_t micro) noexcept
Definition: DistrhoUtils.hpp:90
#define USE_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:955
See the Plugin class for more information.
Parameters
A plugin is nothing without parameters.
In DPF parameters can be inputs or outputs.
They have hints to describe how they behave plus a name and a symbol identifying them.
Parameters also have 'ranges' - a minimum, maximum and default value.
Input parameters are by default "read-only": the plugin can read them but not change them. (there are exceptions and possibly a request to the host to change values, more on that below)
It's the host responsibility to save, restore and set input parameters.
Output parameters can be changed at anytime by the plugin.
The host will simply read their values and never change them.
Here's an example of an audio plugin that has 1 input parameter:
class GainPlugin :
public Plugin
{
public:
GainPlugin()
fGain(1.0f)
{
}
protected:
{
return "Gain";
}
{
return "DPF";
}
{
return "MIT";
}
{
}
{
}
{
}
{
return fGain;
}
{
fGain = value;
}
void run(
const float**,
float** outputs, uint32_t frames)
override
{
const float* const in = inputs[0];
float* const out = outputs[0];
for (uint32_t i=0; i < frames; ++i)
out[i] = in[i] * fGain;
}
private:
float fGain;
};
virtual void setParameterValue(uint32_t index, float value)
virtual void initParameter(uint32_t index, Parameter ¶meter)
virtual float getParameterValue(uint32_t index) const
static constexpr const uint32_t kParameterIsAutomatable
Definition: DistrhoDetails.hpp:96
float max
Definition: DistrhoDetails.hpp:338
float min
Definition: DistrhoDetails.hpp:333
float def
Definition: DistrhoDetails.hpp:328
Definition: DistrhoDetails.hpp:588
ParameterRanges ranges
Definition: DistrhoDetails.hpp:634
uint32_t hints
Definition: DistrhoDetails.hpp:593
String symbol
Definition: DistrhoDetails.hpp:615
String name
Definition: DistrhoDetails.hpp:600
See the Parameter struct for more information about parameters.
Programs
Programs in DPF refer to plugin-side presets (usually called "factory presets").
This is meant as an initial set of presets provided by plugin authors included in the actual plugin.
To use programs you must first enable them by setting DISTRHO_PLUGIN_WANT_PROGRAMS to 1 in your DistrhoPluginInfo.h file.
When enabled you'll need to override 2 new function in your plugin code, Plugin::initProgramName(uint32_t, String&) and Plugin::loadProgram(uint32_t).
Here's an example of a plugin with a "default" program:
class PluginWithPresets :
public Plugin
{
public:
PluginWithPresets()
fGainL(1.0f),
fGainR(1.0f),
{
}
protected:
{
return "Prog";
}
{
return "DPF";
}
{
return "MIT";
}
{
}
{
}
{
switch (index)
{
case 0:
parameter.
name =
"Gain Right";
break;
case 1:
parameter.
name =
"Gain Left";
break;
}
}
{
programName = "Default";
}
{
switch (index)
{
case 0:
return fGainL;
case 1:
return fGainR;
default:
return 0.f;
}
}
{
switch (index)
{
case 0:
fGainL = value;
break;
case 1:
fGainR = value;
break;
}
}
{
fGainL = 1.0f;
fGainR = 1.0f;
}
void run(
const float**,
float** outputs, uint32_t frames)
override
{
const float* const inL = inputs[0];
const float* const inR = inputs[0];
float* const outL = outputs[0];
float* const outR = outputs[0];
for (uint32_t i=0; i < frames; ++i)
{
outL[i] = inL[i] * fGainL;
outR[i] = inR[i] * fGainR;
}
}
private:
float fGainL, fGainR;
};
virtual void loadProgram(uint32_t index)
virtual void initProgramName(uint32_t index, String &programName)=0
Definition: String.hpp:35
This is a work-in-progress documentation page. States, MIDI, Latency, Time-Position and UI are still TODO.