Browse Source

Add S&H functionality to CVPort example plugin

pull/218/head
cu 5 years ago
parent
commit
4324dea325
3 changed files with 90 additions and 24 deletions
  1. +3
    -3
      examples/CVPort/DistrhoPluginInfo.h
  2. +78
    -19
      examples/CVPort/ExamplePluginCVPort.cpp
  3. +9
    -2
      examples/CVPort/README.md

+ 3
- 3
examples/CVPort/DistrhoPluginInfo.h View File

@@ -21,8 +21,8 @@
#define DISTRHO_PLUGIN_NAME "CVPort"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/CVPort"

#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 1
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 78
- 19
examples/CVPort/ExamplePluginCVPort.cpp View File

@@ -21,14 +21,15 @@ START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
/**
Simple plugin to demonstrate parameter usage (including UI).
The plugin will be treated as an effect, but it will not change the host audio.
Simple plugin to demonstrate how to modify input/output port type in DPF.
The plugin outputs sample & hold (S&H) value of input signal.
User can specify hold time via parameter and/or Hold Time CV port.
*/
class ExamplePluginParameters : public Plugin
class ExamplePluginCVPort : public Plugin
{
public:
ExamplePluginParameters()
: Plugin(0, 0, 0) {} // 0 parameters, 0 programs, 0 states
ExamplePluginCVPort()
: Plugin(1, 0, 0) {} // 1 parameters, 0 programs, 0 states
protected:
/* --------------------------------------------------------------------------------------------------------
@@ -49,7 +50,7 @@ protected:
const char* getDescription() const override
{
return "Simple plugin with CVPort.\n\
The plugin will be treated as an effect, signal will bypassed.";
The plugin does sample & hold processing.";
}
/**
@@ -110,9 +111,15 @@ The plugin will be treated as an effect, signal will bypassed.";
if (input)
{
if (index == 0) {
// Audio port doesn't need to specify port.hints.
port.name = "Audio Input";
port.symbol = "audio_in";
return;
}
else if (index == 1) {
port.hints = kAudioPortIsCV;
port.name = "CV Input";
port.symbol = "cv_in";
port.name = "Hold Time";
port.symbol = "hold_time";
return;
}
// Add more condition here when increasing DISTRHO_PLUGIN_NUM_INPUTS.
@@ -133,13 +140,44 @@ The plugin will be treated as an effect, signal will bypassed.";
*/
Plugin::initAudioPort(input, index, port);
}
/**
Initialize the parameter @a index.
This function will be called once, shortly after the plugin is created.
*/
void initParameter(uint32_t index, Parameter& parameter) override
{
if (index != 0) return;
parameter.name = "Hold Time";
parameter.symbol = "hold_time";
parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic;
parameter.ranges.min = 0.0f;
parameter.ranges.max = maxHoldTime;
parameter.ranges.def = 0.1f;
}
/* --------------------------------------------------------------------------------------------------------
* Init and Internal data, unused in this plugin */
* Internal data */
/**
Get the current value of a parameter.
*/
inline float getParameterValue(uint32_t index) const override
{
return index == 0 ? holdTime : 0.0f;
}
void initParameter(uint32_t, Parameter&) override {}
float getParameterValue(uint32_t) const override { return 0.0f;}
void setParameterValue(uint32_t, float) override {}
/**
Change a parameter value.
*/
void setParameterValue(uint32_t index, float value) override
{
if (index != 0) return;
holdTime = value;
counter = uint32_t(holdTime * sampleRate);
}
/* --------------------------------------------------------------------------------------------------------
* Process */
@@ -150,21 +188,42 @@ The plugin will be treated as an effect, signal will bypassed.";
void run(const float** inputs, float** outputs, uint32_t frames) override
{
/**
This plugin does nothing, it just demonstrates CVPort usage.
So here we directly copy inputs over outputs, leaving the audio untouched.
We need to be careful in case the host re-uses the same buffer for both ins and outs.
- inputs[0] is input audio port.
- inputs[1] is hold time CV port.
- outputs[0] is output CV port.
*/
if (outputs[0] != inputs[0])
std::memcpy(outputs[0], inputs[0], sizeof(float)*frames);
for (uint32_t i = 0; i < frames; ++i) {
if (counter == 0) {
float cv = inputs[1][i] > 0.0f ? inputs[1][i] : 0.0f;
float time = holdTime + cv;
if (time > maxHoldTime)
time = maxHoldTime;
counter = uint32_t(time * sampleRate);
holdValue = inputs[0][i]; // Refresh hold value.
} else {
--counter;
}
outputs[0][i] = holdValue;
}
}
// -------------------------------------------------------------------------------------------------------
private:
const float maxHoldTime = 1.0f;
float sampleRate = 44100.0f;
uint32_t counter = 0; // Hold time in samples. Used to count hold time.
float holdTime = 0.0f; // Hold time in seconds.
float holdValue = 0.0f;
/**
Set our plugin class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginParameters)
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginCVPort)
};
/* ------------------------------------------------------------------------------------------------------------
@@ -172,7 +231,7 @@ private:
Plugin* createPlugin()
{
return new ExamplePluginParameters();
return new ExamplePluginCVPort();
}
// -----------------------------------------------------------------------------------------------------------


+ 9
- 2
examples/CVPort/README.md View File

@@ -1,6 +1,13 @@
# CVPort example

This example will show how to modify input/output port type in DPF.<br/>
The plugin will not do any audio processing.<br/>

Take a look at `initAudioPort()` method.<br/>

The plugin does sample & hold (S&H) processing.<br/>
3 I/O ports are specified.<br/>

- Input audio port.
- Input CV port to modify Hold Time.
- Output CV port.

The plugin also has a Hold Time parameter. It mixes CV value and parameter value.<br/>

Loading…
Cancel
Save