diff --git a/dpf/FEATURES.md b/dpf/FEATURES.md
index 3bba8f1..7106f3b 100644
--- a/dpf/FEATURES.md
+++ b/dpf/FEATURES.md
@@ -4,29 +4,29 @@ This file describes the available features for each plugin format.
The limitations could be due to the plugin format itself or within DPF.
If the limitation is within DPF, a link is provided to a description below on the reason for it.
-| Feature | JACK/Standalone | LADSPA | DSSI | LV2 | VST2 | VST3 | Feature |
-|---------------------|---------------------------------------|-------------------------|---------------------|-------------------------------|--------------------------------|----------------------------------|---------------------|
-| Audio port groups | [Yes*](#jack-audio-port-groups) | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Audio port groups |
-| Audio port as CV | Yes | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Audio port as CV |
-| Audio sidechan | Yes | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | Audio sidechan |
-| Bypass control | No | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | Bypass control |
-| MIDI input | Yes | No | Yes | Yes | Yes | Yes | MIDI input |
-| MIDI output | Yes | No | No | Yes | Yes | Yes | MIDI output |
-| Parameter changes | Yes | No | No | [No*](#lv2-parameter-changes) | Yes | Yes | Parameter changes |
-| Parameter groups | No | No | No | Yes | Yes | [No*](#vst3-is-work-in-progress) | Parameter groups |
-| Parameter outputs | No | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Parameter outputs |
-| Parameter triggers | Yes | No | No | Yes | [No*](#parameter-triggers) | [No*](#parameter-triggers) | Parameter triggers |
-| Programs | [Yes*](#jack-parameters-and-programs) | [No*](#ladspa-programs) | [Yes*](#dssi-state) | Yes | [No*](#vst2-programs) | Yes | Programs |
-| States | Yes | No | [Yes*](#dssi-state) | Yes | Yes | Yes | States |
-| Full/internal state | Yes | No | No | Yes | Yes | Yes | Full/internal state |
-| Time position | Yes | No | No | Yes | Yes | Yes | Time position |
-| UI | [Yes*](#jack-custom-ui-only) | No | External only | Yes | Embed only | Embed only | UI |
-| UI bg/fg colors | No | No | No | Yes | No | No? | UI bg/fg colors |
-| UI direct access | Yes | No | No | Yes | Yes | Yes | UI direct access |
-| UI host-filebrowser | No | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | UI host-filebrowser |
-| UI host-resize | Yes | No | Yes | Yes | No | [No*](#vst3-is-work-in-progress) | UI host-resize |
-| UI remote control | No | No | Yes | Yes | No | Yes | UI remote control |
-| UI send midi note | Yes | No | Yes | Yes | Yes | Yes | UI send midi note |
+| Feature | JACK/Standalone | LADSPA | DSSI | LV2 | VST2 | VST3 | CLAP | Feature |
+|---------------------|---------------------------------------|--------------------|---------------------|-------------------------------|----------------------------|----------------------------|-------------------------------|---------------------|
+| Audio port groups | [Yes*](#jack-audio-port-groups) | No | No | Yes | No | Yes | Yes | Audio port groups |
+| Audio port as CV | Yes | No | No | Yes | No | [Yes*](#vst3-cv) | [No*](#work-in-progress) | Audio port as CV |
+| Audio sidechan | Yes | No | No | Yes | [No*](#vst2-deprecated) | Yes | Yes | Audio sidechan |
+| Bypass control | No | No | No | Yes | [No*](#vst2-deprecated) | Yes | Yes | Bypass control |
+| MIDI input | Yes | No | Yes | Yes | Yes | Yes | Yes | MIDI input |
+| MIDI output | Yes | No | No | Yes | Yes | Yes | Yes | MIDI output |
+| Parameter changes | Yes | No | No | [No*](#lv2-parameter-changes) | Yes | Yes | Yes | Parameter changes |
+| Parameter groups | No | No | No | Yes | Yes | [No*](#work-in-progress) | Yes | Parameter groups |
+| Parameter outputs | No | No | No | Yes | No | Yes | Yes | Parameter outputs |
+| Parameter triggers | Yes | No | No | Yes | [No*](#parameter-triggers) | [No*](#parameter-triggers) | [No*](#parameter-triggers) | Parameter triggers |
+| Programs | [Yes*](#jack-parameters-and-programs) | [No*](#ladspa-rdf) | [Yes*](#dssi-state) | Yes | [No*](#vst2-programs) | Yes | No | Programs |
+| States | Yes | No | [Yes*](#dssi-state) | Yes | Yes | Yes | Yes | States |
+| Full/internal state | Yes | No | No | Yes | Yes | Yes | Yes | Full/internal state |
+| Time position | Yes | No | No | Yes | Yes | Yes | Yes | Time position |
+| UI | [Yes*](#jack-custom-ui-only) | No | External only | Yes | Embed only | Embed only | Yes | UI |
+| UI bg/fg colors | No | No | No | Yes | No | No? | No | UI bg/fg colors |
+| UI direct access | Yes | No | No | Yes | Yes | Yes | Yes | UI direct access |
+| UI host-filebrowser | No | No | No | Yes | [No*](#vst2-deprecated) | [No*](#work-in-progress) | [No*](#work-in-progress) | UI host-filebrowser |
+| UI host-resize | Yes | No | Yes | Yes | No | Yes | Yes | UI host-resize |
+| UI remote control | No | No | Yes | Yes | No | Yes | No | UI remote control |
+| UI send midi note | Yes | No | Yes | Yes | Yes | Yes | Yes | UI send midi note |
For things that could be unclear:
@@ -59,7 +59,7 @@ MIDI CCs are used for parameter changes (matching the `midiCC` value you set on
There is no generic plugin editor view.
If your plugin has no custom UI, the standalone executable will run but not show any window.
-## LADSPA programs
+## LADSPA RDF
Programs for LADSPA could be done via LRDF but this is not supported in DPF.
@@ -78,7 +78,7 @@ But if we involve programs, they would need to pass through the UI in order to w
Although this is already implemented in DPF (through a custom extension), this is not implemented on most hosts.
So for now you can pretty much treat it as if not supported.
-## VST2 potential support
+## VST2 deprecated
Not supported in DPF at the moment.
It could eventually be, but likely not due to VST2 being phased out by Steinberg.
@@ -88,6 +88,11 @@ Contact DPF authors if you require such a feature.
VST2 program support requires saving state of all programs in memory, which is very expensive and thus not done in DPF.
-## VST3 is work in progress
+## VST3 CV
+
+Although VST3 officially supports CV (Control Voltage) tagged audio ports,
+at the moment no host supports such feature and thus it is not possible to validate it.
+
+## Work in progress
Feature is possible, just not implemented yet in DPF.
diff --git a/dpf/README.md b/dpf/README.md
index 998c0af..18b7115 100644
--- a/dpf/README.md
+++ b/dpf/README.md
@@ -3,21 +3,21 @@
[](https://github.com/DISTRHO/DPF/actions/workflows/cmake.yml)
[](https://github.com/DISTRHO/DPF/actions/workflows/example-plugins.yml)
-DPF is 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 is 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.
-All current plugin format implementations are complete.
-A JACK/Standalone mode is also available, allowing you to quickly test plugins.
+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.
-Plugin DSP and UI communication is done via key-value string pairs.
-You send messages from the UI to the DSP side, which is automatically saved in the host when required.
-(You can also store state internally if needed, but this breaks DSSI compatibility).
+Plugin DSP and UI communication is done via key-value string pairs.
+You send messages from the UI to the DSP side, which is automatically saved in the host when required.
+(You can also store state internally if needed, but this breaks DSSI compatibility).
-Getting time information from the host is possible.
-It uses the same format as the JACK Transport API, making porting some code easier.
+Getting time information from the host is possible.
+It uses the same format as the JACK Transport API, making porting some code easier.
+Provided features and implementation status for specific plugin formats can be seen in [FEATURES.md](FEATURES.md).
## Licensing
@@ -31,43 +31,11 @@ Bug reports happen on the [DPF github project](https://github.com/DISTRHO/DPF/is
Online documentation is available at [https://distrho.github.io/DPF/](https://distrho.github.io/DPF/).
-Online help and discussion about DPF happens in the [kx.studio chat, DPF room](https://chat.kx.studio/).
+Online help and discussion about DPF happens in the [kx.studio chat, DPF room](https://chat.kx.studio/channel/dpf).
## List of plugins made with DPF:
- - [DISTRHO glBars](https://github.com/DISTRHO/glBars)
- - [DISTRHO Kars](https://github.com/DISTRHO/Kars)
- - [DISTRHO Mini-Series](https://github.com/DISTRHO/Mini-Series)
- - [DISTRHO MVerb](https://github.com/DISTRHO/MVerb)
- - [DISTRHO ndc Plugs](https://github.com/DISTRHO/ndc-Plugs)
- - [DISTRHO Nekobi](https://github.com/DISTRHO/Nekobi)
- - [DISTRHO ProM](https://github.com/DISTRHO/ProM)
- - [Dragonfly Reverb](https://michaelwillis.github.io/dragonfly-reverb)
- - [Fogpad-port](https://github.com/linuxmao-org/fogpad-port)
- - [master_me](https://github.com/trummerschlunk/master_me)
- - [Ninjas2](https://github.com/rghvdberg/ninjas2)
- - [osamc-lv2-workshop](https://github.com/osamc-lv2-workshop/lv2-workshop) (simple plugins code examples)
- - [QuadraFuzz](https://github.com/jpcima/quadrafuzz)
- - [Regrader-Port](https://github.com/linuxmao-org/regrader-port)
- - [Rezonateur](https://github.com/jpcima/rezonateur)
- - [Spectacle-analyzer](https://github.com/jpcima/spectacle/)
- - [Stone Phaser](https://github.com/jpcima/stone-phaser)
- - [String-machine](https://github.com/jpcima/string-machine)
- - [Uhhyou Plugins](https://github.com/ryukau/LV2Plugins)
- - [VL1-emulator](https://github.com/linuxmao-org/VL1-emulator)
- - [Wolf Shaper](https://github.com/pdesaulniers/wolf-shaper)
- - [Wolf Spectrum](https://github.com/pdesaulniers/wolf-spectrum)
- - [YK Chorus](https://github.com/SpotlightKid/ykchorus)
- - [ZamAudio Suite](https://github.com/zamaudio/zam-plugins)
- ## Work in progress
- - [CV-LFO-blender-LV2](https://github.com/BramGiesen/cv-lfo-blender-lv2)
- - [fverb](https://github.com/jpcima/fverb)
- - [Juice Plugins](https://github.com/DISTRHO/JuicePlugins)
- - [gunshot](https://github.com/soerenbnoergaard/gunshot)
- - [midiomatic](https://github.com/SpotlightKid/midiomatic)
- - [Shiro Plugins](https://github.com/ninodewit/SHIRO-Plugins/)
- - [Shiru Plugins](https://github.com/linuxmao-org/shiru-plugins)
-
-Checking the [github "DPF" tag](https://github.com/topics/dpf) can potentially bring up other DPF-made plugins.
-
-Plugin examples are available in the `example/` folder inside this repo.
+
+See [this wiki page](https://github.com/DISTRHO/DPF/wiki/Plugins-made-with-DPF) for a list of plugins made with DPF.
+
+Plugin examples are also available in the `example/` folder inside this repo.
diff --git a/dpf/dgl/src/TopLevelWidgetPrivateData.cpp b/dpf/dgl/src/TopLevelWidgetPrivateData.cpp
index fc86225..02c2a0b 100644
--- a/dpf/dgl/src/TopLevelWidgetPrivateData.cpp
+++ b/dpf/dgl/src/TopLevelWidgetPrivateData.cpp
@@ -28,6 +28,17 @@ TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w)
selfw(s),
window(w)
{
+ /* if window already has a top-level-widget, make the new one match the first one in size
+ * this is needed because window creation and resize is a synchronous operation in some systems.
+ * as such, there's a chance the non-1st top-level-widgets would never get a valid size.
+ */
+ if (!window.pData->topLevelWidgets.empty())
+ {
+ TopLevelWidget* const first = window.pData->topLevelWidgets.front();
+
+ selfw->pData->size = first->getSize();
+ }
+
window.pData->topLevelWidgets.push_back(self);
}
diff --git a/dpf/dgl/src/pugl-upstream/src/win.c b/dpf/dgl/src/pugl-upstream/src/win.c
index 13d042c..8356520 100644
--- a/dpf/dgl/src/pugl-upstream/src/win.c
+++ b/dpf/dgl/src/pugl-upstream/src/win.c
@@ -35,6 +35,16 @@
#define PUGL_LOCAL_CLIENT_MSG (WM_USER + 52)
#define PUGL_USER_TIMER_MIN 9470
+#ifdef __cplusplus
+# define PUGL_INIT_STRUCT \
+ {}
+#else
+# define PUGL_INIT_STRUCT \
+ { \
+ 0 \
+ }
+#endif
+
typedef BOOL(WINAPI* PFN_SetProcessDPIAware)(void);
typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*);
typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*);
@@ -80,7 +90,7 @@ puglRegisterWindowClass(const char* name)
module = GetModuleHandle(NULL);
}
- WNDCLASSEX wc = {0};
+ WNDCLASSEX wc = PUGL_INIT_STRUCT;
if (GetClassInfoEx(module, name, &wc)) {
return true; // Already registered
}
@@ -472,8 +482,8 @@ initKeyEvent(PuglKeyEvent* event,
}
} else if (!dead) {
// Translate unshifted key
- BYTE keyboardState[256] = {0};
- wchar_t buf[5] = {0};
+ BYTE keyboardState[256] = PUGL_INIT_STRUCT;
+ wchar_t buf[5] = PUGL_INIT_STRUCT;
event->key = puglDecodeUTF16(
buf, ToUnicode(vkey, vcode, keyboardState, buf, 4, 1 << 2));
@@ -689,7 +699,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
pt.y = GET_Y_LPARAM(lParam);
if (!view->impl->mouseTracked) {
- TRACKMOUSEEVENT tme = {0};
+ TRACKMOUSEEVENT tme = PUGL_INIT_STRUCT;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
diff --git a/dpf/distrho/DistrhoPlugin.hpp b/dpf/distrho/DistrhoPlugin.hpp
index 41493e5..02d2cda 100644
--- a/dpf/distrho/DistrhoPlugin.hpp
+++ b/dpf/distrho/DistrhoPlugin.hpp
@@ -72,6 +72,12 @@ static const uint32_t kCVPortHasPositiveUnipolarRange = 0x40;
*/
static const uint32_t kCVPortHasScaledRange = 0x80;
+/**
+ CV port is optional, allowing hosts that do no CV ports to load the plugin.
+ When loaded in hosts that don't support CV, the float* buffer for this port will be null.
+ */
+static const uint32_t kCVPortIsOptional = 0x100;
+
/** @} */
/* ------------------------------------------------------------------------------------------------------------
diff --git a/dpf/distrho/src/DistrhoPluginCLAP.cpp b/dpf/distrho/src/DistrhoPluginCLAP.cpp
index 2226b3f..bf39a20 100644
--- a/dpf/distrho/src/DistrhoPluginCLAP.cpp
+++ b/dpf/distrho/src/DistrhoPluginCLAP.cpp
@@ -14,6 +14,14 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+/* TODO items:
+ * CV: write a specification
+ * INFO: define url, manual url, support url and string version
+ * PARAMETERS: test parameter triggers
+ * States: skip DSP/UI only states as appropriate
+ * UI: expose external-only UIs
+ */
+
#include "DistrhoPluginInternal.hpp"
#include "extra/ScopedPointer.hpp"
@@ -1070,8 +1078,7 @@ public:
fPlugin.run(audioInputs, audioOutputs, frames);
#endif
- // TODO set last frame
- flushParameters(nullptr, process->out_events);
+ flushParameters(nullptr, process->out_events, frames - 1);
fOutputEvents = nullptr;
}
@@ -1210,7 +1217,9 @@ public:
return true;
}
- void flushParameters(const clap_input_events_t* const in, const clap_output_events_t* const out)
+ void flushParameters(const clap_input_events_t* const in,
+ const clap_output_events_t* const out,
+ const uint32_t frameOffset)
{
if (const uint32_t len = in != nullptr ? in->size(in) : 0)
{
@@ -1231,7 +1240,7 @@ public:
if (out != nullptr)
{
clap_event_param_value_t clapEvent = {
- { sizeof(clap_event_param_value_t), 0, 0, CLAP_EVENT_PARAM_VALUE, CLAP_EVENT_IS_LIVE },
+ { sizeof(clap_event_param_value_t), frameOffset, 0, CLAP_EVENT_PARAM_VALUE, CLAP_EVENT_IS_LIVE },
0, nullptr, 0, 0, 0, 0, 0.0
};
@@ -2336,7 +2345,7 @@ static CLAP_ABI bool clap_plugin_params_text_to_value(const clap_plugin_t* plugi
static CLAP_ABI void clap_plugin_params_flush(const clap_plugin_t* plugin, const clap_input_events_t* in, const clap_output_events_t* out)
{
PluginCLAP* const instance = static_cast(plugin->plugin_data);
- return instance->flushParameters(in, out);
+ return instance->flushParameters(in, out, 0);
}
static const clap_plugin_params_t clap_plugin_params = {
diff --git a/dpf/distrho/src/DistrhoPluginLV2export.cpp b/dpf/distrho/src/DistrhoPluginLV2export.cpp
index a42a50f..24d9e22 100644
--- a/dpf/distrho/src/DistrhoPluginLV2export.cpp
+++ b/dpf/distrho/src/DistrhoPluginLV2export.cpp
@@ -532,6 +532,9 @@ void lv2_generate_ttl(const char* const basename)
}
}
+ if ((port.hints & (kAudioPortIsCV|kCVPortIsOptional)) == (kAudioPortIsCV|kCVPortIsOptional))
+ pluginString += " lv2:portProperty lv2:connectionOptional;\n";
+
if (i+1 == DISTRHO_PLUGIN_NUM_INPUTS)
pluginString += " ] ;\n";
else
@@ -817,11 +820,10 @@ void lv2_generate_ttl(const char* const basename)
// MIDI CC binding
if (const uint8_t midiCC = plugin.getParameterMidiCC(i))
{
- char midiCCBuf[7];
- snprintf(midiCCBuf, sizeof(midiCCBuf), "B0%02x00", midiCC);
- pluginString += " midi:binding \"";
- pluginString += midiCCBuf;
- pluginString += "\"^^midi:MidiEvent ;\n";
+ pluginString += " midi:binding [\n";
+ pluginString += " a midi:Controller ;\n";
+ pluginString += " midi:controllerNumber " + String(midiCC) + " ;\n";
+ pluginString += " ] ;\n";
}
// unit
diff --git a/dpf/distrho/src/DistrhoPluginVST3.cpp b/dpf/distrho/src/DistrhoPluginVST3.cpp
index 7ce39b8..3fca785 100644
--- a/dpf/distrho/src/DistrhoPluginVST3.cpp
+++ b/dpf/distrho/src/DistrhoPluginVST3.cpp
@@ -14,28 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "DistrhoPluginInternal.hpp"
-#include "../DistrhoPluginUtils.hpp"
-#include "../extra/ScopedPointer.hpp"
-
-#define DPF_VST3_MAX_BUFFER_SIZE 32768
-#define DPF_VST3_MAX_SAMPLE_RATE 384000
-#define DPF_VST3_MAX_LATENCY DPF_VST3_MAX_SAMPLE_RATE * 10
-
-#if DISTRHO_PLUGIN_HAS_UI
-# include "../extra/RingBuffer.hpp"
-#endif
-
-#include "travesty/audio_processor.h"
-#include "travesty/component.h"
-#include "travesty/edit_controller.h"
-#include "travesty/factory.h"
-#include "travesty/host.h"
-
-#include