Browse Source

Import plugin examples into this repo

pull/72/head
falkTX 4 years ago
parent
commit
af99b460ea
29 changed files with 3276 additions and 0 deletions
  1. +47
    -0
      examples/Info/DistrhoPluginInfo.h
  2. +288
    -0
      examples/Info/InfoExamplePlugin.cpp
  3. +222
    -0
      examples/Info/InfoExampleUI.cpp
  4. +45
    -0
      examples/Info/Makefile
  5. +10
    -0
      examples/Info/README.md
  6. +30
    -0
      examples/Latency/DistrhoPluginInfo.h
  7. +251
    -0
      examples/Latency/LatencyExamplePlugin.cpp
  8. +36
    -0
      examples/Latency/Makefile
  9. +8
    -0
      examples/Latency/README.md
  10. +172
    -0
      examples/Makefile.mk
  11. +34
    -0
      examples/Meters/DistrhoPluginInfo.h
  12. +284
    -0
      examples/Meters/ExamplePluginMeters.cpp
  13. +254
    -0
      examples/Meters/ExampleUIMeters.cpp
  14. +53
    -0
      examples/Meters/Makefile
  15. +8
    -0
      examples/Meters/README.md
  16. +31
    -0
      examples/MidiThrough/DistrhoPluginInfo.h
  17. +35
    -0
      examples/MidiThrough/Makefile
  18. +137
    -0
      examples/MidiThrough/MidiThroughExamplePlugin.cpp
  19. +6
    -0
      examples/MidiThrough/README.md
  20. +30
    -0
      examples/Parameters/DistrhoPluginInfo.h
  21. +292
    -0
      examples/Parameters/ExamplePluginParameters.cpp
  22. +244
    -0
      examples/Parameters/ExampleUIParameters.cpp
  23. +54
    -0
      examples/Parameters/Makefile
  24. +9
    -0
      examples/Parameters/README.md
  25. +31
    -0
      examples/States/DistrhoPluginInfo.h
  26. +316
    -0
      examples/States/ExamplePluginStates.cpp
  27. +287
    -0
      examples/States/ExampleUIStates.cpp
  28. +53
    -0
      examples/States/Makefile
  29. +9
    -0
      examples/States/README.md

+ 47
- 0
examples/Info/DistrhoPluginInfo.h View File

@@ -0,0 +1,47 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED

#define DISTRHO_PLUGIN_BRAND "DISTRHO"
#define DISTRHO_PLUGIN_NAME "Info"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Info"

#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
#define DISTRHO_UI_USE_NANOVG 1

enum Parameters {
kParameterBufferSize = 0,
kParameterTimePlaying,
kParameterTimeFrame,
kParameterTimeValidBBT,
kParameterTimeBar,
kParameterTimeBeat,
kParameterTimeTick,
kParameterTimeBarStartTick,
kParameterTimeBeatsPerBar,
kParameterTimeBeatType,
kParameterTimeTicksPerBeat,
kParameterTimeBeatsPerMinute,
kParameterCount
};

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 288
- 0
examples/Info/InfoExamplePlugin.cpp View File

@@ -0,0 +1,288 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DistrhoPlugin.hpp"
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
/**
Plugin to show how to get some basic information sent to the UI.
*/
class InfoExamplePlugin : public Plugin
{
public:
InfoExamplePlugin()
: Plugin(kParameterCount, 0, 0)
{
// clear all parameters
std::memset(fParameters, 0, sizeof(float)*kParameterCount);
// we can know buffer-size right at the start
fParameters[kParameterBufferSize] = getBufferSize();
}
protected:
/* --------------------------------------------------------------------------------------------------------
* Information */
/**
Get the plugin label.
This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
*/
const char* getLabel() const override
{
return "Info";
}
/**
Get an extensive comment/description about the plugin.
*/
const char* getDescription() const override
{
return "Plugin to show how to get some basic information sent to the UI.";
}
/**
Get the plugin author/maker.
*/
const char* getMaker() const override
{
return "DISTRHO";
}
/**
Get the plugin homepage.
*/
const char* getHomePage() const override
{
return "https://github.com/DISTRHO/plugin-examples";
}
/**
Get the plugin license name (a single line of text).
For commercial plugins this should return some short copyright information.
*/
const char* getLicense() const override
{
return "ISC";
}
/**
Get the plugin version, in hexadecimal.
*/
uint32_t getVersion() const override
{
return d_version(1, 0, 0);
}
/**
Get the plugin unique Id.
This value is used by LADSPA, DSSI and VST plugin formats.
*/
int64_t getUniqueId() const override
{
return d_cconst('d', 'N', 'f', 'o');
}
/* --------------------------------------------------------------------------------------------------------
* Init */
/**
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
{
parameter.hints = kParameterIsAutomable|kParameterIsOutput;
parameter.ranges.def = 0.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 16777216.0f;
switch (index)
{
case kParameterBufferSize:
parameter.name = "BufferSize";
parameter.symbol = "buffer_size";
break;
case kParameterTimePlaying:
parameter.hints |= kParameterIsBoolean;
parameter.name = "TimePlaying";
parameter.symbol = "time_playing";
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
break;
case kParameterTimeFrame:
parameter.name = "TimeFrame";
parameter.symbol = "time_frame";
break;
case kParameterTimeValidBBT:
parameter.hints |= kParameterIsBoolean;
parameter.name = "TimeValidBBT";
parameter.symbol = "time_validbbt";
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
break;
case kParameterTimeBar:
parameter.name = "TimeBar";
parameter.symbol = "time_bar";
break;
case kParameterTimeBeat:
parameter.name = "TimeBeat";
parameter.symbol = "time_beat";
break;
case kParameterTimeTick:
parameter.name = "TimeTick";
parameter.symbol = "time_tick";
break;
case kParameterTimeBarStartTick:
parameter.name = "TimeBarStartTick";
parameter.symbol = "time_barstarttick";
break;
case kParameterTimeBeatsPerBar:
parameter.name = "TimeBeatsPerBar";
parameter.symbol = "time_beatsperbar";
break;
case kParameterTimeBeatType:
parameter.name = "TimeBeatType";
parameter.symbol = "time_beattype";
break;
case kParameterTimeTicksPerBeat:
parameter.name = "TimeTicksPerBeat";
parameter.symbol = "time_ticksperbeat";
break;
case kParameterTimeBeatsPerMinute:
parameter.name = "TimeBeatsPerMinute";
parameter.symbol = "time_beatsperminute";
break;
}
}
/* --------------------------------------------------------------------------------------------------------
* Internal data */
/**
Get the current value of a parameter.
The host may call this function from any context, including realtime processing.
*/
float getParameterValue(uint32_t index) const override
{
return fParameters[index];
}
/**
Change a parameter value.
The host may call this function from any context, including realtime processing.
When a parameter is marked as automable, you must ensure no non-realtime operations are performed.
@note This function will only be called for parameter inputs.
*/
void setParameterValue(uint32_t, float) override
{
// this is only called for input paramters, which we have none of.
}
/* --------------------------------------------------------------------------------------------------------
* Audio/MIDI Processing */
/**
Run/process function for plugins without MIDI input.
@note Some parameters might be null if there are no audio inputs or outputs.
*/
void run(const float** inputs, float** outputs, uint32_t frames) override
{
/**
This plugin does nothing, it just demonstrates information 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.
*/
if (outputs[0] != inputs[0])
std::memcpy(outputs[0], inputs[0], sizeof(float)*frames);
if (outputs[1] != inputs[1])
std::memcpy(outputs[1], inputs[1], sizeof(float)*frames);
// get time position
const TimePosition& timePos(getTimePosition());
// set basic values
fParameters[kParameterTimePlaying] = timePos.playing ? 1.0f : 0.0f;
fParameters[kParameterTimeFrame] = timePos.frame;
fParameters[kParameterTimeValidBBT] = timePos.bbt.valid ? 1.0f : 0.0f;
// set bbt
if (timePos.bbt.valid)
{
fParameters[kParameterTimeBar] = timePos.bbt.bar;
fParameters[kParameterTimeBeat] = timePos.bbt.beat;
fParameters[kParameterTimeTick] = timePos.bbt.tick;
fParameters[kParameterTimeBarStartTick] = timePos.bbt.barStartTick;
fParameters[kParameterTimeBeatsPerBar] = timePos.bbt.beatsPerBar;
fParameters[kParameterTimeBeatType] = timePos.bbt.beatType;
fParameters[kParameterTimeTicksPerBeat] = timePos.bbt.ticksPerBeat;
fParameters[kParameterTimeBeatsPerMinute] = timePos.bbt.beatsPerMinute;
}
else
{
fParameters[kParameterTimeBar] = 0.0f;
fParameters[kParameterTimeBeat] = 0.0f;
fParameters[kParameterTimeTick] = 0.0f;
fParameters[kParameterTimeBarStartTick] = 0.0f;
fParameters[kParameterTimeBeatsPerBar] = 0.0f;
fParameters[kParameterTimeBeatType] = 0.0f;
fParameters[kParameterTimeTicksPerBeat] = 0.0f;
fParameters[kParameterTimeBeatsPerMinute] = 0.0f;
}
}
/* --------------------------------------------------------------------------------------------------------
* Callbacks (optional) */
/**
Optional callback to inform the plugin about a buffer size change.@
This function will only be called when the plugin is deactivated.
@note This value is only a hint!
Hosts might call run() with a higher or lower number of frames.
*/
void bufferSizeChanged(uint32_t newBufferSize) override
{
fParameters[kParameterBufferSize] = newBufferSize;
}
// -------------------------------------------------------------------------------------------------------
private:
// Parameters
float fParameters[kParameterCount];
/**
Set our plugin class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExamplePlugin)
};
/* ------------------------------------------------------------------------------------------------------------
* Plugin entry point, called by DPF to create a new plugin instance. */
Plugin* createPlugin()
{
return new InfoExamplePlugin();
}
// -----------------------------------------------------------------------------------------------------------
END_NAMESPACE_DISTRHO

+ 222
- 0
examples/Info/InfoExampleUI.cpp View File

@@ -0,0 +1,222 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "DistrhoPluginInfo.h"

#include "DistrhoUI.hpp"

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------------------------------------------

class InfoExampleUI : public UI
{
public:
InfoExampleUI()
: UI(405, 256)
{
std::memset(fParameters, 0, sizeof(float)*kParameterCount);
std::memset(fStrBuf, 0, sizeof(char)*(0xff+1));

fSampleRate = getSampleRate();
fFont = createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
}

protected:
/* --------------------------------------------------------------------------------------------------------
* DSP/Plugin Callbacks */

/**
A parameter has changed on the plugin side.
This is called by the host to inform the UI about parameter changes.
*/
void parameterChanged(uint32_t index, float value) override
{
fParameters[index] = value;
repaint();
}

/* --------------------------------------------------------------------------------------------------------
* DSP/Plugin Callbacks (optional) */

/**
Optional callback to inform the UI about a sample rate change on the plugin side.
*/
void sampleRateChanged(double newSampleRate) override
{
fSampleRate = newSampleRate;
repaint();
}

/* --------------------------------------------------------------------------------------------------------
* Widget Callbacks */

/**
The NanoVG drawing function.
*/
void onNanoDisplay() override
{
static const float lineHeight = 20;

fontSize(15.0f);
textLineHeight(lineHeight);

float x = 0;
float y = 15;

// buffer size
drawLeft(x, y, "Buffer Size:");
drawRight(x, y, getTextBufInt(fParameters[kParameterBufferSize]));
y+=lineHeight;

// sample rate
drawLeft(x, y, "Sample Rate:");
drawRight(x, y, getTextBufFloat(fSampleRate));
y+=lineHeight;

// nothing
y+=lineHeight;

// time stuff
drawLeft(x, y, "Playing:");
drawRight(x, y, (fParameters[kParameterTimePlaying] > 0.5f) ? "Yes" : "No");
y+=lineHeight;

drawLeft(x, y, "Frame:");
drawRight(x, y, getTextBufInt(fParameters[kParameterTimeFrame]));
y+=lineHeight;

drawLeft(x, y, "Time:");
drawRight(x, y, getTextBufTime(fParameters[kParameterTimeFrame]));
y+=lineHeight;

// BBT
x = 200;
y = 15;

const bool validBBT(fParameters[kParameterTimeValidBBT] > 0.5f);
drawLeft(x, y, "BBT Valid:");
drawRight(x, y, validBBT ? "Yes" : "No");
y+=lineHeight;

if (! validBBT)
return;

drawLeft(x, y, "Bar:");
drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBar]));
y+=lineHeight;

drawLeft(x, y, "Beat:");
drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBeat]));
y+=lineHeight;

drawLeft(x, y, "Tick:");
drawRight(x, y, getTextBufInt(fParameters[kParameterTimeTick]));
y+=lineHeight;

drawLeft(x, y, "Bar Start Tick:");
drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBarStartTick]));
y+=lineHeight;

drawLeft(x, y, "Beats Per Bar:");
drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerBar]));
y+=lineHeight;

drawLeft(x, y, "Beat Type:");
drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatType]));
y+=lineHeight;

drawLeft(x, y, "Ticks Per Beat:");
drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeTicksPerBeat]));
y+=lineHeight;

drawLeft(x, y, "BPM:");
drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerMinute]));
y+=lineHeight;
}

// -------------------------------------------------------------------------------------------------------

private:
// Parameters
float fParameters[kParameterCount];
double fSampleRate;

// font
FontId fFont;

// temp buf for text
char fStrBuf[0xff+1];

// helpers for putting text into fStrBuf and returning it
const char* getTextBufInt(const int value)
{
std::snprintf(fStrBuf, 0xff, "%i", value);
return fStrBuf;
}

const char* getTextBufFloat(const float value)
{
std::snprintf(fStrBuf, 0xff, "%.1f", value);
return fStrBuf;
}

const char* getTextBufTime(const uint64_t frame)
{
const uint32_t time = frame / uint64_t(fSampleRate);
const uint32_t secs = time % 60;
const uint32_t mins = (time / 60) % 60;
const uint32_t hrs = (time / 3600) % 60;
std::snprintf(fStrBuf, 0xff, "%02i:%02i:%02i", hrs, mins, secs);
return fStrBuf;
}

// helpers for drawing text
void drawLeft(const float x, const float y, const char* const text)
{
beginPath();
fillColor(200, 200, 200);
textAlign(ALIGN_RIGHT|ALIGN_TOP);
textBox(x, y, 100, text);
closePath();
}

void drawRight(const float x, const float y, const char* const text)
{
beginPath();
fillColor(255, 255, 255);
textAlign(ALIGN_LEFT|ALIGN_TOP);
textBox(x+105, y, 100, text);
closePath();
}

/**
Set our UI class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExampleUI)
};

/* ------------------------------------------------------------------------------------------------------------
* UI entry point, called by DPF to create a new UI instance. */

UI* createUI()
{
return new InfoExampleUI();
}

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO

+ 45
- 0
examples/Info/Makefile View File

@@ -0,0 +1,45 @@
#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#

# --------------------------------------------------------------
# Project name, used for binaries

NAME = d_info

# --------------------------------------------------------------
# Files to build

FILES_DSP = \
InfoExamplePlugin.cpp

FILES_UI = \
InfoExampleUI.cpp

# --------------------------------------------------------------
# Do some magic

include ../Makefile.mk

# --------------------------------------------------------------
# Enable all possible plugin types

ifeq ($(HAVE_DGL),true)
ifeq ($(HAVE_JACK),true)
TARGETS += jack
endif
endif

ifeq ($(HAVE_DGL),true)
TARGETS += lv2_sep
else
TARGETS += lv2_dsp
endif

TARGETS += vst

all: $(TARGETS)

# --------------------------------------------------------------

+ 10
- 0
examples/Info/README.md View File

@@ -0,0 +1,10 @@
# Information example

This example will show how to get some basic information sent to the UI.<br/>

The Plugin has a lot of parameter outputs which the UI uses to get info from.<br/>
This includes buffer-size and time position.<br/>
Sample-rate can be requested directly from the UI.<br/>
The UI will show this information as text.<br/>

The plugin will not do any audio processing.<br/>

+ 30
- 0
examples/Latency/DistrhoPluginInfo.h View File

@@ -0,0 +1,30 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED

#define DISTRHO_PLUGIN_BRAND "DISTRHO"
#define DISTRHO_PLUGIN_NAME "Latency"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Latency"

#define DISTRHO_PLUGIN_HAS_UI 0
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 1
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1
#define DISTRHO_PLUGIN_WANT_LATENCY 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 251
- 0
examples/Latency/LatencyExamplePlugin.cpp View File

@@ -0,0 +1,251 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DistrhoPlugin.hpp"
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
/**
Plugin that demonstrates the latency API in DPF.
*/
class LatencyExamplePlugin : public Plugin
{
public:
LatencyExamplePlugin()
: Plugin(1, 0, 0), // 1 parameter
fLatency(1.0f),
fLatencyInFrames(0),
fBuffer(nullptr),
fBufferPos(0)
{
// allocates buffer
sampleRateChanged(getSampleRate());
}
~LatencyExamplePlugin() override
{
delete[] fBuffer;
}
protected:
/* --------------------------------------------------------------------------------------------------------
* Information */
/**
Get the plugin label.
This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
*/
const char* getLabel() const override
{
return "Latency";
}
/**
Get an extensive comment/description about the plugin.
*/
const char* getDescription() const override
{
return "Plugin that demonstrates the latency API in DPF.";
}
/**
Get the plugin author/maker.
*/
const char* getMaker() const override
{
return "DISTRHO";
}
/**
Get the plugin homepage.
*/
const char* getHomePage() const override
{
return "https://github.com/DISTRHO/plugin-examples";
}
/**
Get the plugin license name (a single line of text).
For commercial plugins this should return some short copyright information.
*/
const char* getLicense() const override
{
return "ISC";
}
/**
Get the plugin version, in hexadecimal.
*/
uint32_t getVersion() const override
{
return d_version(1, 0, 0);
}
/**
Get the plugin unique Id.
This value is used by LADSPA, DSSI and VST plugin formats.
*/
int64_t getUniqueId() const override
{
return d_cconst('d', 'L', 'a', 't');
}
/* --------------------------------------------------------------------------------------------------------
* Init */
/**
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.hints = kParameterIsAutomable;
parameter.name = "Latency";
parameter.symbol = "latency";
parameter.unit = "s";
parameter.ranges.def = 1.0f;
parameter.ranges.min = 0.0f;
parameter.ranges.max = 5.0f;
}
/* --------------------------------------------------------------------------------------------------------
* Internal data */
/**
Get the current value of a parameter.
The host may call this function from any context, including realtime processing.
*/
float getParameterValue(uint32_t index) const override
{
if (index != 0)
return 0.0f;
return fLatency;
}
/**
Change a parameter value.
The host may call this function from any context, including realtime processing.
When a parameter is marked as automable, you must ensure no non-realtime operations are performed.
@note This function will only be called for parameter inputs.
*/
void setParameterValue(uint32_t index, float value) override
{
if (index != 0)
return;
fLatency = value;
fLatencyInFrames = value*getSampleRate();
setLatency(fLatencyInFrames);
}
/* --------------------------------------------------------------------------------------------------------
* Audio/MIDI Processing */
/**
Run/process function for plugins without MIDI input.
@note Some parameters might be null if there are no audio inputs or outputs.
*/
void run(const float** inputs, float** outputs, uint32_t frames) override
{
const float* const in = inputs[0];
/* */ float* const out = outputs[0];
if (fLatencyInFrames == 0)
{
if (out != in)
std::memcpy(out, in, sizeof(float)*frames);
return;
}
// Put the new audio in the buffer.
std::memcpy(fBuffer+fBufferPos, in, sizeof(float)*frames);
fBufferPos += frames;
// buffer is not filled enough yet
if (fBufferPos < fLatencyInFrames+frames)
{
// silence output
std::memset(out, 0, sizeof(float)*frames);
}
// buffer is ready to copy
else
{
// copy latency buffer to output
const uint32_t readPos = fBufferPos-fLatencyInFrames-frames;
std::memcpy(out, fBuffer+readPos, sizeof(float)*frames);
// move latency buffer back by some frames
std::memmove(fBuffer, fBuffer+frames, sizeof(float)*fBufferPos);
fBufferPos -= frames;
}
}
/* --------------------------------------------------------------------------------------------------------
* Callbacks (optional) */
/**
Optional callback to inform the plugin about a sample rate change.
This function will only be called when the plugin is deactivated.
*/
void sampleRateChanged(double newSampleRate) override
{
if (fBuffer != nullptr)
delete[] fBuffer;
const uint32_t maxFrames = newSampleRate*6; // 6 seconds
fBuffer = new float[maxFrames];
std::memset(fBuffer, 0, sizeof(float)*maxFrames);
fLatencyInFrames = fLatency*newSampleRate;
fBufferPos = 0;
}
// -------------------------------------------------------------------------------------------------------
private:
// Parameters
float fLatency;
uint32_t fLatencyInFrames;
// Buffer for previous audio, size depends on sample rate
float* fBuffer;
uint32_t fBufferPos;
/**
Set our plugin class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LatencyExamplePlugin)
};
/* ------------------------------------------------------------------------------------------------------------
* Plugin entry point, called by DPF to create a new plugin instance. */
Plugin* createPlugin()
{
return new LatencyExamplePlugin();
}
// -----------------------------------------------------------------------------------------------------------
END_NAMESPACE_DISTRHO

+ 36
- 0
examples/Latency/Makefile View File

@@ -0,0 +1,36 @@
#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#

# --------------------------------------------------------------
# Project name, used for binaries

NAME = d_latency

# --------------------------------------------------------------
# Files to build

FILES_DSP = \
LatencyExamplePlugin.cpp

# --------------------------------------------------------------
# Do some magic

include ../Makefile.mk

# --------------------------------------------------------------
# Enable all possible plugin types

ifeq ($(LINUX),true)
TARGETS += ladspa
TARGETS += dssi
endif

TARGETS += lv2_dsp
TARGETS += vst

all: $(TARGETS)

# --------------------------------------------------------------

+ 8
- 0
examples/Latency/README.md View File

@@ -0,0 +1,8 @@
# Latency example

This example will show how to use latency in DPF based plugins.<br/>

The plugin will delay its audio signal by a variable amount of time, specified by a parameter.<br/>
Good hosts will receive this hint and compensate accordingly.<br/>

The plugin has no UI because there's no need for one in this case.<br/>

+ 172
- 0
examples/Makefile.mk View File

@@ -0,0 +1,172 @@
#!/usr/bin/make -f
# Makefile for DPF Example Plugins #
# -------------------------------- #
# Created by falkTX
#

# NAME, FILES_DSP and FILES_UI have been defined before

include ../../Makefile.mk

ifeq ($(OBJS_UI),)
HAVE_DGL = false
endif

# ---------------------------------------------------------------------------------------------------------------------
# Basic setup

TARGET_DIR = ../../bin
BUILD_DIR = ../../build/$(NAME)

BUILD_C_FLAGS += -I.
BUILD_CXX_FLAGS += -I. -I../../distrho -I../../dgl

ifeq ($(HAVE_DGL),true)
BASE_FLAGS += -DHAVE_DGL
endif

ifeq ($(HAVE_JACK),true)
BASE_FLAGS += -DHAVE_JACK
endif

ifeq ($(HAVE_LIBLO),true)
BASE_FLAGS += -DHAVE_LIBLO
endif

# ---------------------------------------------------------------------------------------------------------------------
# Set files to build

OBJS_DSP = $(FILES_DSP:%=$(BUILD_DIR)/%.o)
OBJS_UI = $(FILES_UI:%=$(BUILD_DIR)/%.o)

# ---------------------------------------------------------------------------------------------------------------------
# Set plugin binary file targets

jack = $(TARGET_DIR)/$(NAME)$(APP_EXT)
ladspa_dsp = $(TARGET_DIR)/$(NAME)-ladspa$(LIB_EXT)
dssi_dsp = $(TARGET_DIR)/$(NAME)-dssi$(LIB_EXT)
dssi_ui = $(TARGET_DIR)/$(NAME)-dssi/$(NAME)_ui$(APP_EXT)
lv2 = $(TARGET_DIR)/$(NAME).lv2/$(NAME)$(LIB_EXT)
lv2_dsp = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_dsp$(LIB_EXT)
lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui$(LIB_EXT)
vst = $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT)

# ---------------------------------------------------------------------------------------------------------------------
# Set distrho code files

DISTRHO_PLUGIN_FILES = ../../distrho/DistrhoPluginMain.cpp

ifeq ($(HAVE_DGL),true)
DISTRHO_UI_FILES = ../../distrho/DistrhoUIMain.cpp ../../build/libdgl.a
endif

# ---------------------------------------------------------------------------------------------------------------------
# Handle plugins without UI

ifneq ($(HAVE_DGL),true)
dssi_ui =
lv2_ui =
DISTRHO_UI_FILES =
DGL_LIBS =
OBJS_UI =
endif

# ---------------------------------------------------------------------------------------------------------------------
# all needs to be first

all:

# ---------------------------------------------------------------------------------------------------------------------
# Common

$(BUILD_DIR)/%.c.o: %.c
-@mkdir -p $(BUILD_DIR)
@echo "Compiling $<"
@$(CC) $< $(BUILD_C_FLAGS) -c -o $@

$(BUILD_DIR)/%.cpp.o: %.cpp
-@mkdir -p $(BUILD_DIR)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

clean:
rm -rf $(BUILD_DIR)
rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2

# ---------------------------------------------------------------------------------------------------------------------
# JACK

jack: $(jack)

$(jack): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating JACK standalone for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs jack) -DDISTRHO_PLUGIN_TARGET_JACK -o $@

# ---------------------------------------------------------------------------------------------------------------------
# LADSPA

ladspa: $(ladspa_dsp)

$(ladspa_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating LADSPA plugin for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LADSPA -o $@

# ---------------------------------------------------------------------------------------------------------------------
# DSSI

dssi: $(dssi_dsp) $(dssi_ui)
dssi_dsp: $(dssi_dsp)
dssi_ui: $(dssi_ui)

$(dssi_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating DSSI plugin library for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@

$(dssi_ui): $(OBJS_UI) $(DISTRHO_UI_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating DSSI UI for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs liblo) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@

# ---------------------------------------------------------------------------------------------------------------------
# LV2

lv2_one: $(lv2)
lv2_dsp: $(lv2_dsp)
lv2_sep: $(lv2_dsp) $(lv2_ui)

$(lv2): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@

$(lv2_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin library for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@

$(lv2_ui): $(OBJS_UI) $(DISTRHO_UI_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating LV2 plugin UI for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@

# ---------------------------------------------------------------------------------------------------------------------
# VST

vst: $(vst)

$(vst): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES)
-@mkdir -p $(shell dirname $@)
@echo "Creating VST plugin for $(NAME)"
@$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_VST -o $@

# ---------------------------------------------------------------------------------------------------------------------

-include $(OBJS_DSP:%.o=%.d)
ifeq ($(HAVE_DGL),true)
-include $(OBJS_UI:%.o=%.d)
endif

# ---------------------------------------------------------------------------------------------------------------------

+ 34
- 0
examples/Meters/DistrhoPluginInfo.h View File

@@ -0,0 +1,34 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED

#define DISTRHO_PLUGIN_BRAND "DISTRHO"
#define DISTRHO_PLUGIN_NAME "Meters"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Meters"

#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_STATE 1
#define DISTRHO_UI_USE_NANOVG 1

#define METER_COLOR_GREEN 0
#define METER_COLOR_BLUE 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 284
- 0
examples/Meters/ExamplePluginMeters.cpp View File

@@ -0,0 +1,284 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DistrhoPlugin.hpp"
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
/**
Plugin to demonstrate parameter outputs using meters.
*/
class ExamplePluginMeters : public Plugin
{
public:
ExamplePluginMeters()
: Plugin(3, 0, 0), // 3 parameters, 0 programs, 0 states
fColor(0.0f),
fOutLeft(0.0f),
fOutRight(0.0f),
fNeedsReset(true)
{
}
protected:
/* --------------------------------------------------------------------------------------------------------
* Information */
/**
Get the plugin label.
A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
*/
const char* getLabel() const override
{
return "meters";
}
/**
Get an extensive comment/description about the plugin.
*/
const char* getDescription() const override
{
return "Plugin to demonstrate parameter outputs using meters.";
}
/**
Get the plugin author/maker.
*/
const char* getMaker() const override
{
return "DISTRHO";
}
/**
Get the plugin homepage.
*/
const char* getHomePage() const override
{
return "https://github.com/DISTRHO/plugin-examples";
}
/**
Get the plugin license name (a single line of text).
For commercial plugins this should return some short copyright information.
*/
const char* getLicense() const override
{
return "ISC";
}
/**
Get the plugin version, in hexadecimal.
*/
uint32_t getVersion() const override
{
return d_version(1, 0, 0);
}
/**
Get the plugin unique Id.
This value is used by LADSPA, DSSI and VST plugin formats.
*/
int64_t getUniqueId() const override
{
return d_cconst('d', 'M', 't', 'r');
}
/* --------------------------------------------------------------------------------------------------------
* Init */
/**
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
{
/**
All parameters in this plugin have the same ranges.
*/
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
parameter.ranges.def = 0.0f;
/**
Set parameter data.
*/
switch (index)
{
case 0:
parameter.hints = kParameterIsAutomable|kParameterIsInteger;
parameter.name = "color";
parameter.symbol = "color";
parameter.enumValues.count = 2;
parameter.enumValues.restrictedMode = true;
{
ParameterEnumerationValue* const values = new ParameterEnumerationValue[2];
parameter.enumValues.values = values;
values[0].label = "Green";
values[0].value = METER_COLOR_GREEN;
values[1].label = "Blue";
values[1].value = METER_COLOR_BLUE;
}
break;
case 1:
parameter.hints = kParameterIsAutomable|kParameterIsOutput;
parameter.name = "out-left";
parameter.symbol = "out_left";
break;
case 2:
parameter.hints = kParameterIsAutomable|kParameterIsOutput;
parameter.name = "out-right";
parameter.symbol = "out_right";
break;
}
}
/**
Set a state key and default value.
This function will be called once, shortly after the plugin is created.
*/
void initState(uint32_t, String&, String&) override
{
// we are using states but don't want them saved in the host
}
/* --------------------------------------------------------------------------------------------------------
* Internal data */
/**
Get the current value of a parameter.
*/
float getParameterValue(uint32_t index) const override
{
switch (index)
{
case 0: return fColor;
case 1: return fOutLeft;
case 2: return fOutRight;
}
return 0.0f;
}
/**
Change a parameter value.
*/
void setParameterValue(uint32_t index, float value) override
{
// this is only called for input paramters, and we only have one of those.
if (index != 0) return;
fColor = value;
}
/**
Change an internal state.
*/
void setState(const char* key, const char*) override
{
if (std::strcmp(key, "reset") != 0)
return;
fNeedsReset = true;
}
/* --------------------------------------------------------------------------------------------------------
* Process */
/**
Run/process function for plugins without MIDI input.
*/
void run(const float** inputs, float** outputs, uint32_t frames) override
{
float tmp;
float tmpLeft = 0.0f;
float tmpRight = 0.0f;
for (uint32_t i=0; i<frames; ++i)
{
// left
tmp = std::abs(inputs[0][i]);
if (tmp > tmpLeft)
tmpLeft = tmp;
// right
tmp = std::abs(inputs[1][i]);
if (tmp > tmpRight)
tmpRight = tmp;
}
if (tmpLeft > 1.0f)
tmpLeft = 1.0f;
if (tmpRight > 1.0f)
tmpRight = 1.0f;
if (fNeedsReset)
{
fOutLeft = tmpLeft;
fOutRight = tmpRight;
fNeedsReset = false;
}
else
{
if (tmpLeft > fOutLeft)
fOutLeft = tmpLeft;
if (tmpRight > fOutRight)
fOutRight = tmpRight;
}
// copy inputs over outputs if needed
if (outputs[0] != inputs[0])
std::memcpy(outputs[0], inputs[0], sizeof(float)*frames);
if (outputs[1] != inputs[1])
std::memcpy(outputs[1], inputs[1], sizeof(float)*frames);
}
// -------------------------------------------------------------------------------------------------------
private:
/**
Parameters.
*/
float fColor, fOutLeft, fOutRight;
/**
Boolean used to reset meter values.
The UI will send a "reset" message which sets this as true.
*/
volatile bool fNeedsReset;
/**
Set our plugin class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginMeters)
};
/* ------------------------------------------------------------------------------------------------------------
* Plugin entry point, called by DPF to create a new plugin instance. */
Plugin* createPlugin()
{
return new ExamplePluginMeters();
}
// -----------------------------------------------------------------------------------------------------------
END_NAMESPACE_DISTRHO

+ 254
- 0
examples/Meters/ExampleUIMeters.cpp View File

@@ -0,0 +1,254 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "DistrhoUI.hpp"

START_NAMESPACE_DISTRHO

/**
We need the Color class from DGL.
*/
using DGL::Color;

/**
Smooth meters a bit.
*/
static const float kSmoothMultiplier = 3.0f;

// -----------------------------------------------------------------------------------------------------------

class ExampleUIMeters : public UI
{
public:
ExampleUIMeters()
: UI(128, 512),
// default color is green
fColor(93, 231, 61),
// which is value 0
fColorValue(0),
// init meter values to 0
fOutLeft(0.0f),
fOutRight(0.0f)
{
}

protected:
/* --------------------------------------------------------------------------------------------------------
* DSP/Plugin Callbacks */

/**
A parameter has changed on the plugin side.
This is called by the host to inform the UI about parameter changes.
*/
void parameterChanged(uint32_t index, float value) override
{
switch (index)
{
case 0: // color
updateColor(std::round(value));
break;

case 1: // out-left
value = (fOutLeft * kSmoothMultiplier + value) / (kSmoothMultiplier + 1.0f);

/**/ if (value < 0.001f) value = 0.0f;
else if (value > 0.999f) value = 1.0f;

if (fOutLeft != value)
{
fOutLeft = value;
repaint();
}
break;

case 2: // out-right
value = (fOutRight * kSmoothMultiplier + value) / (kSmoothMultiplier + 1.0f);

/**/ if (value < 0.001f) value = 0.0f;
else if (value > 0.999f) value = 1.0f;

if (fOutRight != value)
{
fOutRight = value;
repaint();
}
break;
}
}

/**
A state has changed on the plugin side.
This is called by the host to inform the UI about state changes.
*/
void stateChanged(const char*, const char*)
{
// nothing here
}

/* --------------------------------------------------------------------------------------------------------
* Widget Callbacks */

/**
The NanoVG drawing function.
*/
void onNanoDisplay() override
{
static const Color kColorBlack(0, 0, 0);
static const Color kColorRed(255, 0, 0);
static const Color kColorYellow(255, 255, 0);

// get meter values
const float outLeft(fOutLeft);
const float outRight(fOutRight);

// tell DSP side to reset meter values
setState("reset", "");

// useful vars
const float halfWidth = static_cast<float>(getWidth())/2;
const float redYellowHeight = static_cast<float>(getHeight())*0.2f;
const float yellowBaseHeight = static_cast<float>(getHeight())*0.4f;
const float baseBaseHeight = static_cast<float>(getHeight())*0.6f;

// create gradients
Paint fGradient1 = linearGradient(0.0f, 0.0f, 0.0f, redYellowHeight, kColorRed, kColorYellow);
Paint fGradient2 = linearGradient(0.0f, redYellowHeight, 0.0f, yellowBaseHeight, kColorYellow, fColor);

// paint left meter
beginPath();
rect(0.0f, 0.0f, halfWidth-1.0f, redYellowHeight);
fillPaint(fGradient1);
fill();
closePath();

beginPath();
rect(0.0f, redYellowHeight-0.5f, halfWidth-1.0f, yellowBaseHeight);
fillPaint(fGradient2);
fill();
closePath();

beginPath();
rect(0.0f, redYellowHeight+yellowBaseHeight-1.5f, halfWidth-1.0f, baseBaseHeight);
fillColor(fColor);
fill();
closePath();

// paint left black matching output level
beginPath();
rect(0.0f, 0.0f, halfWidth-1.0f, (1.0f-outLeft)*getHeight());
fillColor(kColorBlack);
fill();
closePath();

// paint right meter
beginPath();
rect(halfWidth+1.0f, 0.0f, halfWidth-2.0f, redYellowHeight);
fillPaint(fGradient1);
fill();
closePath();

beginPath();
rect(halfWidth+1.0f, redYellowHeight-0.5f, halfWidth-2.0f, yellowBaseHeight);
fillPaint(fGradient2);
fill();
closePath();

beginPath();
rect(halfWidth+1.0f, redYellowHeight+yellowBaseHeight-1.5f, halfWidth-2.0f, baseBaseHeight);
fillColor(fColor);
fill();
closePath();

// paint right black matching output level
beginPath();
rect(halfWidth+1.0f, 0.0f, halfWidth-2.0f, (1.0f-outRight)*getHeight());
fillColor(kColorBlack);
fill();
closePath();
}

/**
Mouse press event.
This UI will change color when clicked.
*/
bool onMouse(const MouseEvent& ev) override
{
// Test for left-clicked + pressed first.
if (ev.button != 1 || ! ev.press)
return false;

const int newColor(fColorValue == 0 ? 1 : 0);
updateColor(newColor);
setParameterValue(0, newColor);

return true;
}

// -------------------------------------------------------------------------------------------------------

private:
/**
Color and its matching parameter value.
*/
Color fColor;
int fColorValue;

/**
Meter values.
These are the parameter outputs from the DSP side.
*/
float fOutLeft, fOutRight;

/**
Update color if needed.
*/
void updateColor(const int color)
{
if (fColorValue == color)
return;

fColorValue = color;

switch (color)
{
case METER_COLOR_GREEN:
fColor = Color(93, 231, 61);
break;
case METER_COLOR_BLUE:
fColor = Color(82, 238, 248);
break;
}

repaint();
}

/**
Set our UI class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExampleUIMeters)
};

/* ------------------------------------------------------------------------------------------------------------
* UI entry point, called by DPF to create a new UI instance. */

UI* createUI()
{
return new ExampleUIMeters();
}

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO

+ 53
- 0
examples/Meters/Makefile View File

@@ -0,0 +1,53 @@
#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#

# --------------------------------------------------------------
# Project name, used for binaries

NAME = d_meters

# --------------------------------------------------------------
# Files to build

FILES_DSP = \
ExamplePluginMeters.cpp

FILES_UI = \
ExampleUIMeters.cpp

# --------------------------------------------------------------
# Do some magic

include ../Makefile.mk

# --------------------------------------------------------------
# Enable all possible plugin types

ifeq ($(HAVE_DGL),true)
ifeq ($(HAVE_JACK),true)
TARGETS += jack
endif
endif

ifeq ($(LINUX),true)
ifeq ($(HAVE_DGL),true)
ifeq ($(HAVE_LIBLO),true)
TARGETS += dssi
endif
endif
endif

ifeq ($(HAVE_DGL),true)
TARGETS += lv2_sep
else
TARGETS += lv2_dsp
endif

TARGETS += vst

all: $(TARGETS)

# --------------------------------------------------------------

+ 8
- 0
examples/Meters/README.md View File

@@ -0,0 +1,8 @@
# Meters example

This example will show how parameter outputs can be used for UI meters in DPF.<br/>
The plugin will inspect the host audio buffer but it won't change it in any way.<br/>

In this example the UI will display a simple meter based on the plugin's parameter outputs.<br/>
In order to make drawing easier the UI uses NanoVG instead of raw OpenGL.<br/>
Please see the Parameters and States examples before studying this one.<br/>

+ 31
- 0
examples/MidiThrough/DistrhoPluginInfo.h View File

@@ -0,0 +1,31 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED

#define DISTRHO_PLUGIN_BRAND "DISTRHO"
#define DISTRHO_PLUGIN_NAME "MidiThrough"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/MidiThrough"

#define DISTRHO_PLUGIN_HAS_UI 0
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 0
#define DISTRHO_PLUGIN_NUM_OUTPUTS 0
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1
#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 35
- 0
examples/MidiThrough/Makefile View File

@@ -0,0 +1,35 @@
#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#

# --------------------------------------------------------------
# Project name, used for binaries

NAME = d_midiThrough

# --------------------------------------------------------------
# Files to build

FILES_DSP = \
MidiThroughExamplePlugin.cpp

# --------------------------------------------------------------
# Do some magic

include ../Makefile.mk

# --------------------------------------------------------------
# Enable all possible plugin types

ifeq ($(LINUX),true)
TARGETS += jack
endif

TARGETS += lv2_dsp
TARGETS += vst

all: $(TARGETS)

# --------------------------------------------------------------

+ 137
- 0
examples/MidiThrough/MidiThroughExamplePlugin.cpp View File

@@ -0,0 +1,137 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DistrhoPlugin.hpp"
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
/**
Plugin that demonstrates the latency API in DPF.
*/
class MidiThroughExamplePlugin : public Plugin
{
public:
MidiThroughExamplePlugin()
: Plugin(0, 0, 0) {}
protected:
/* --------------------------------------------------------------------------------------------------------
* Information */
/**
Get the plugin label.
This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
*/
const char* getLabel() const override
{
return "MidiThrough";
}
/**
Get an extensive comment/description about the plugin.
*/
const char* getDescription() const override
{
return "Plugin that demonstrates the latency API in DPF.";
}
/**
Get the plugin author/maker.
*/
const char* getMaker() const override
{
return "DISTRHO";
}
/**
Get the plugin homepage.
*/
const char* getHomePage() const override
{
return "https://github.com/DISTRHO/plugin-examples";
}
/**
Get the plugin license name (a single line of text).
For commercial plugins this should return some short copyright information.
*/
const char* getLicense() const override
{
return "ISC";
}
/**
Get the plugin version, in hexadecimal.
*/
uint32_t getVersion() const override
{
return d_version(1, 0, 0);
}
/**
Get the plugin unique Id.
This value is used by LADSPA, DSSI and VST plugin formats.
*/
int64_t getUniqueId() const override
{
return d_cconst('d', 'M', 'T', 'r');
}
/* --------------------------------------------------------------------------------------------------------
* Init and Internal data, unused in this plugin */
void initParameter(uint32_t, Parameter&) override {}
float getParameterValue(uint32_t) const override { return 0.0f;}
void setParameterValue(uint32_t, float) override {}
/* --------------------------------------------------------------------------------------------------------
* Audio/MIDI Processing */
/**
Run/process function for plugins with MIDI input.
In this case we just pass-through all MIDI events.
*/
void run(const float**, float**, uint32_t,
const MidiEvent* midiEvents, uint32_t midiEventCount) override
{
for (uint32_t i=0; i<midiEventCount; ++i)
writeMidiEvent(midiEvents[i]);
}
// -------------------------------------------------------------------------------------------------------
private:
// nothing here :)
/**
Set our plugin class as non-copyable and add a leak detector just in case.
*/
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiThroughExamplePlugin)
};
/* ------------------------------------------------------------------------------------------------------------
* Plugin entry point, called by DPF to create a new plugin instance. */
Plugin* createPlugin()
{
return new MidiThroughExamplePlugin();
}
// -----------------------------------------------------------------------------------------------------------
END_NAMESPACE_DISTRHO

+ 6
- 0
examples/MidiThrough/README.md View File

@@ -0,0 +1,6 @@
# MidiThrough example

This example will show how to use MIDI output in DPF based plugins.<br/>

It simply calls writeMidiEvent() in its process function for every event it receives.


+ 30
- 0
examples/Parameters/DistrhoPluginInfo.h View File

@@ -0,0 +1,30 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED

#define DISTRHO_PLUGIN_BRAND "DISTRHO"
#define DISTRHO_PLUGIN_NAME "Parameters"
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Parameters"

#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 292
- 0
examples/Parameters/ExamplePluginParameters.cpp View File

@@ -0,0 +1,292 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DistrhoPlugin.hpp"
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.
*/
class ExamplePluginParameters : public Plugin
{
public:
ExamplePluginParameters()
: Plugin(9, 2, 0) // 9 parameters, 2 programs, 0 states
{
/**
Initialize all our parameters to their defaults.
In this example all parameters have 0 as default, so we can simply zero them.
*/
std::memset(fParamGrid, 0, sizeof(float)*9);
}
protected:
/* --------------------------------------------------------------------------------------------------------
* Information */
/**
Get the plugin label.
A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
*/
const char* getLabel() const override
{
return "parameters";
}
/**
Get an extensive comment/description about the plugin.
*/
const char* getDescription() const override
{
return "Simple plugin to demonstrate parameter usage (including UI).\n\
The plugin will be treated as an effect, but it will not change the host audio.";
}
/**
Get the plugin author/maker.
*/
const char* getMaker() const override
{
return "DISTRHO";
}
/**
Get the plugin homepage.
*/
const char* getHomePage() const override
{
return "https://github.com/DISTRHO/plugin-examples";
}
/**
Get the plugin license name (a single line of text).
For commercial plugins this should return some short copyright information.
*/
const char* getLicense() const override
{
return "ISC";
}
/**
Get the plugin version, in hexadecimal.
*/
uint32_t getVersion() const override
{
return d_version(1, 0, 0);
}
/**
Get the plugin unique Id.
This value is used by LADSPA, DSSI and VST plugin formats.
*/
int64_t getUniqueId() const override
{
return d_cconst('d', 'P', 'r', 'm');
}
/* --------------------------------------------------------------------------------------------------------
* Init */
/**
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
{
/**
All parameters in this plugin are similar except for name.
As such, we initialize the common details first, then set the unique name later.
*/
/**
Changing parameters does not cause any realtime-unsafe operations, so we can mark them as automable.
Also set as boolean because they work as on/off switches.
*/
parameter.hints = kParameterIsAutomable|kParameterIsBoolean;
/**
Minimum 0 (off), maximum 1 (on).
Default is off.
*/
parameter.ranges.min = 0.0f;