commit 1682712841083a7591352dad59c316b8b6ac528b
parent a06479325ea510f4df80ffe3c0981d4bf8bf3feb
Author: falkTX <falktx@falktx.com>
Date: Sat, 15 May 2021 16:33:00 +0100
Add ImguiSimpleGain example, WIP
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
10 files changed, 1151 insertions(+), 0 deletions(-)
diff --git a/examples/ImguiSimpleGain/CParamSmooth.hpp b/examples/ImguiSimpleGain/CParamSmooth.hpp
@@ -0,0 +1,41 @@
+/**
+ * One-pole LPF for smooth parameter changes
+ *
+ * https://www.musicdsp.org/en/latest/Filters/257-1-pole-lpf-for-smooth-parameter-changes.html
+ */
+
+#ifndef C_PARAM_SMOOTH_H
+#define C_PARAM_SMOOTH_H
+
+#include <math.h>
+
+#define TWO_PI 6.283185307179586476925286766559f
+
+class CParamSmooth {
+public:
+ CParamSmooth(float smoothingTimeMs, float samplingRate)
+ : t(smoothingTimeMs)
+ {
+ setSampleRate(samplingRate);
+ }
+
+ ~CParamSmooth() { }
+
+ void setSampleRate(float samplingRate) {
+ if (samplingRate != fs) {
+ fs = samplingRate;
+ a = exp(-TWO_PI / (t * 0.001f * samplingRate));
+ b = 1.0f - a;
+ z = 0.0f;
+ }
+ }
+
+ inline float process(float in) {
+ return z = (in * b) + (z * a);
+ }
+private:
+ float a, b, t, z;
+ double fs = 0.0;
+};
+
+#endif // #ifndef C_PARAM_SMOOTH_H
diff --git a/examples/ImguiSimpleGain/DistrhoPluginInfo.h b/examples/ImguiSimpleGain/DistrhoPluginInfo.h
@@ -0,0 +1,145 @@
+/*
+ * Simple Gain audio effect for DISTRHO Plugin Framework (DPF)
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ * Copyright (C) 2021 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.
+ */
+
+/**
+ The plugin name.@n
+ This is used to identify your plugin before a Plugin instance can be created.
+ @note This macro is required.
+ */
+#define DISTRHO_PLUGIN_NAME "ImguiSimpleGain"
+
+/**
+ Number of audio inputs the plugin has.
+ @note This macro is required.
+ */
+#define DISTRHO_PLUGIN_NUM_INPUTS 2
+
+/**
+ Number of audio outputs the plugin has.
+ @note This macro is required.
+ */
+#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
+
+/**
+ The plugin URI when exporting in LV2 format.
+ @note This macro is required.
+ */
+#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/imguisimplegain"
+
+/**
+ Wherever the plugin has a custom %UI.
+ @see DISTRHO_UI_USE_NANOVG
+ @see UI
+ */
+#define DISTRHO_PLUGIN_HAS_UI 1
+
+/**
+ Wherever the plugin processing is realtime-safe.@n
+ TODO - list rtsafe requirements
+ */
+#define DISTRHO_PLUGIN_IS_RT_SAFE 1
+
+/**
+ Wherever the plugin is a synth.@n
+ @ref DISTRHO_PLUGIN_WANT_MIDI_INPUT is automatically enabled when this is too.
+ @see DISTRHO_PLUGIN_WANT_MIDI_INPUT
+ */
+#define DISTRHO_PLUGIN_IS_SYNTH 0
+
+/**
+ Enable direct access between the %UI and plugin code.
+ @see UI::getPluginInstancePointer()
+ @note DO NOT USE THIS UNLESS STRICTLY NECESSARY!!
+ Try to avoid it at all costs!
+ */
+#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
+
+/**
+ Wherever the plugin introduces latency during audio or midi processing.
+ @see Plugin::setLatency(uint32_t)
+ */
+#define DISTRHO_PLUGIN_WANT_LATENCY 0
+
+/**
+ Wherever the plugin wants MIDI input.@n
+ This is automatically enabled if @ref DISTRHO_PLUGIN_IS_SYNTH is true.
+ */
+#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 0
+
+/**
+ Wherever the plugin wants MIDI output.
+ @see Plugin::writeMidiEvent(const MidiEvent&)
+ */
+#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0
+
+/**
+ Wherever the plugin provides its own internal programs.
+ @see Plugin::initProgramName(uint32_t, String&)
+ @see Plugin::loadProgram(uint32_t)
+ */
+#define DISTRHO_PLUGIN_WANT_PROGRAMS 1
+
+/**
+ Wherever the plugin uses internal non-parameter data.
+ @see Plugin::initState(uint32_t, String&, String&)
+ @see Plugin::setState(const char*, const char*)
+ */
+#define DISTRHO_PLUGIN_WANT_STATE 0
+
+/**
+ Wherever the plugin wants time position information from the host.
+ @see Plugin::getTimePosition()
+ */
+#define DISTRHO_PLUGIN_WANT_TIMEPOS 0
+
+/**
+ Wherever the %UI uses NanoVG for drawing instead of the default raw OpenGL calls.@n
+ When enabled your %UI instance will subclass @ref NanoWidget instead of @ref Widget.
+ */
+#define DISTRHO_UI_USE_NANOVG 0
+
+/**
+ The %UI URI when exporting in LV2 format.@n
+ By default this is set to @ref DISTRHO_PLUGIN_URI with "#UI" as suffix.
+ */
+#define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI"
+
+/**
+ Wherever the %UI uses a custom toolkit implementation based on OpenGL.@n
+ When enabled, the macros @ref DISTRHO_UI_CUSTOM_INCLUDE_PATH and @ref DISTRHO_UI_CUSTOM_WIDGET_TYPE are required.
+ */
+#define DISTRHO_UI_USE_CUSTOM 1
+
+/**
+ The include path to the header file used by the custom toolkit implementation.
+ This path must be relative to dpf/distrho/DistrhoUI.hpp
+ @see DISTRHO_UI_USE_CUSTOM
+ */
+#define DISTRHO_UI_CUSTOM_INCLUDE_PATH "ImGuiUI.hpp"
+
+/**
+ The top-level-widget typedef to use for the custom toolkit.
+ This widget class MUST be a subclass of DGL TopLevelWindow class.
+ It is recommended that you keep this widget class inside the DGL namespace,
+ and define widget type as e.g. DGL_NAMESPACE::MyCustomTopLevelWidget.
+ @see DISTRHO_UI_USE_CUSTOM
+ */
+#define DISTRHO_UI_CUSTOM_WIDGET_TYPE DGL_NAMESPACE::ImGuiUI
+
+#define DISTRHO_UI_USER_RESIZABLE 1
diff --git a/examples/ImguiSimpleGain/ImGuiSrc.cpp b/examples/ImguiSimpleGain/ImGuiSrc.cpp
@@ -0,0 +1,35 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * 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 <imgui.h>
+#if !defined(IMGUI_GL2) && !defined(IMGUI_GL3)
+# define IMGUI_GL2 1
+#endif
+#if defined(IMGUI_GL2)
+# include <imgui_impl_opengl2.h>
+#elif defined(IMGUI_GL3)
+# include <imgui_impl_opengl3.h>
+#endif
+
+#include <imgui.cpp>
+#include <imgui_draw.cpp>
+#include <imgui_tables.cpp>
+#include <imgui_widgets.cpp>
+#if defined(IMGUI_GL2)
+#include <imgui_impl_opengl2.cpp>
+#elif defined(IMGUI_GL3)
+#include <imgui_impl_opengl3.cpp>
+#endif
diff --git a/examples/ImguiSimpleGain/ImGuiUI.cpp b/examples/ImguiSimpleGain/ImGuiUI.cpp
@@ -0,0 +1,316 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * 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 "Application.hpp"
+
+#include <GL/glew.h>
+
+#include "ImGuiUI.hpp"
+#include <imgui.h>
+#if !defined(IMGUI_GL2) && !defined(IMGUI_GL3)
+# define IMGUI_GL2 1
+#endif
+#if defined(IMGUI_GL2)
+# include <imgui_impl_opengl2.h>
+#elif defined(IMGUI_GL3)
+# include <imgui_impl_opengl3.h>
+#endif
+#include <chrono>
+#include <cmath>
+
+START_NAMESPACE_DGL
+
+struct ImGuiUI::Impl
+{
+ explicit Impl(ImGuiUI* self);
+ ~Impl();
+
+ void setupGL();
+ void cleanupGL();
+
+ // perhaps DPF will implement this in the future
+ float getScaleFactor() const { return 1.0f; }
+
+ static int mouseButtonToImGui(int button);
+
+ ImGuiUI* fSelf = nullptr;
+ ImGuiContext* fContext = nullptr;
+ Color fBackgroundColor{0.25f, 0.25f, 0.25f};
+ int fRepaintIntervalMs = 15;
+
+ using Clock = std::chrono::steady_clock;
+ Clock::time_point fLastRepainted;
+ bool fWasEverPainted = false;
+};
+
+ImGuiUI::ImGuiUI(Window& windowToMapTo)
+ : TopLevelWidget(windowToMapTo),
+ fImpl(new ImGuiUI::Impl(this))
+{
+ getApp().addIdleCallback(this);
+}
+
+ImGuiUI::~ImGuiUI()
+{
+ delete fImpl;
+}
+
+void ImGuiUI::setBackgroundColor(Color color)
+{
+ fImpl->fBackgroundColor = color;
+}
+
+void ImGuiUI::setRepaintInterval(int intervalMs)
+{
+ fImpl->fRepaintIntervalMs = intervalMs;
+}
+
+void ImGuiUI::onDisplay()
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+
+#if defined(IMGUI_GL2)
+ ImGui_ImplOpenGL2_NewFrame();
+#elif defined(IMGUI_GL3)
+ ImGui_ImplOpenGL3_NewFrame();
+#endif
+
+ ImGui::NewFrame();
+ onImGuiDisplay();
+ ImGui::Render();
+
+ ImGuiIO &io = ImGui::GetIO();
+
+ glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
+
+ Color backgroundColor = fImpl->fBackgroundColor;
+ glClearColor(
+ backgroundColor.red, backgroundColor.green,
+ backgroundColor.blue, backgroundColor.alpha);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glLoadIdentity();
+
+#if defined(IMGUI_GL2)
+ ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
+#elif defined(IMGUI_GL3)
+ ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+#endif
+
+ fImpl->fLastRepainted = Impl::Clock::now();
+ fImpl->fWasEverPainted = true;
+}
+
+bool ImGuiUI::onKeyboard(const KeyboardEvent& event)
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ if (event.press)
+ io.AddInputCharacter(event.key);
+
+ int imGuiKey = event.key;
+ if (imGuiKey >= 0 && imGuiKey < 128)
+ {
+ if (imGuiKey >= 'a' && imGuiKey <= 'z')
+ imGuiKey = imGuiKey - 'a' + 'A';
+ io.KeysDown[imGuiKey] = event.press;
+ }
+
+ return io.WantCaptureKeyboard;
+}
+
+bool ImGuiUI::onSpecial(const SpecialEvent& event)
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ int imGuiKey = IM_ARRAYSIZE(io.KeysDown) - event.key;
+ io.KeysDown[imGuiKey] = event.press;
+
+ switch (event.key)
+ {
+ case kKeyShift:
+ io.KeyShift = event.press;
+ break;
+ case kKeyControl:
+ io.KeyCtrl = event.press;
+ break;
+ case kKeyAlt:
+ io.KeyAlt = event.press;
+ break;
+ case kKeySuper:
+ io.KeySuper = event.press;
+ break;
+ default:
+ break;
+ }
+
+ return io.WantCaptureKeyboard;
+}
+
+bool ImGuiUI::onMouse(const MouseEvent& event)
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ int imGuiButton = Impl::mouseButtonToImGui(event.button);
+ if (imGuiButton != -1)
+ io.MouseDown[imGuiButton] = event.press;
+
+ return io.WantCaptureMouse;
+}
+
+bool ImGuiUI::onMotion(const MotionEvent& event)
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ const float scaleFactor = fImpl->getScaleFactor();
+ io.MousePos.x = std::round(scaleFactor * event.pos.getX());
+ io.MousePos.y = std::round(scaleFactor * event.pos.getY());
+
+ return false;
+}
+
+bool ImGuiUI::onScroll(const ScrollEvent& event)
+{
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ io.MouseWheel += event.delta.getY();
+ io.MouseWheelH += event.delta.getX();
+
+ return io.WantCaptureMouse;
+}
+
+void ImGuiUI::onResize(const ResizeEvent& event)
+{
+ TopLevelWidget::onResize(event);
+
+ const uint width = event.size.getWidth();
+ const uint height = event.size.getHeight();
+
+ ImGui::SetCurrentContext(fImpl->fContext);
+ ImGuiIO &io = ImGui::GetIO();
+
+ const float scaleFactor = fImpl->getScaleFactor();
+ io.DisplaySize.x = std::round(scaleFactor * width);
+ io.DisplaySize.y = std::round(scaleFactor * height);
+}
+
+void ImGuiUI::idleCallback()
+{
+ bool shouldRepaint;
+
+ if (fImpl->fWasEverPainted)
+ {
+ Impl::Clock::duration elapsed =
+ Impl::Clock::now() - fImpl->fLastRepainted;
+ std::chrono::milliseconds elapsedMs =
+ std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
+ shouldRepaint = elapsedMs.count() > fImpl->fRepaintIntervalMs;
+ }
+ else
+ {
+ shouldRepaint = true;
+ }
+
+ if (shouldRepaint)
+ repaint();
+}
+
+ImGuiUI::Impl::Impl(ImGuiUI* self)
+ : fSelf(self)
+{
+ setupGL();
+}
+
+ImGuiUI::Impl::~Impl()
+{
+ cleanupGL();
+}
+
+void ImGuiUI::Impl::setupGL()
+{
+ DISTRHO_SAFE_ASSERT_RETURN(glewInit() == 0,);
+
+ IMGUI_CHECKVERSION();
+ fContext = ImGui::CreateContext();
+ ImGui::SetCurrentContext(fContext);
+
+ ImGuiIO &io = ImGui::GetIO();
+ const float scaleFactor = getScaleFactor();
+ io.DisplaySize.x = std::round(scaleFactor * fSelf->getWidth());
+ io.DisplaySize.y = std::round(scaleFactor * fSelf->getHeight());
+ io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
+ io.IniFilename = nullptr;
+
+ io.KeyMap[ImGuiKey_Tab] = '\t';
+ io.KeyMap[ImGuiKey_LeftArrow] = IM_ARRAYSIZE(io.KeysDown) - kKeyLeft;
+ io.KeyMap[ImGuiKey_RightArrow] = IM_ARRAYSIZE(io.KeysDown) - kKeyRight;
+ io.KeyMap[ImGuiKey_UpArrow] = IM_ARRAYSIZE(io.KeysDown) - kKeyUp;
+ io.KeyMap[ImGuiKey_DownArrow] = IM_ARRAYSIZE(io.KeysDown) - kKeyDown;
+ io.KeyMap[ImGuiKey_PageUp] = IM_ARRAYSIZE(io.KeysDown) - kKeyPageUp;
+ io.KeyMap[ImGuiKey_PageDown] = IM_ARRAYSIZE(io.KeysDown) - kKeyPageDown;
+ io.KeyMap[ImGuiKey_Home] = IM_ARRAYSIZE(io.KeysDown) - kKeyHome;
+ io.KeyMap[ImGuiKey_End] = IM_ARRAYSIZE(io.KeysDown) - kKeyEnd;
+ io.KeyMap[ImGuiKey_Insert] = IM_ARRAYSIZE(io.KeysDown) - kKeyInsert;
+ io.KeyMap[ImGuiKey_Delete] = 127;
+ io.KeyMap[ImGuiKey_Backspace] = '\b';
+ io.KeyMap[ImGuiKey_Space] = ' ';
+ io.KeyMap[ImGuiKey_Enter] = '\r';
+ io.KeyMap[ImGuiKey_Escape] = 27;
+ io.KeyMap[ImGuiKey_A] = 'A';
+ io.KeyMap[ImGuiKey_C] = 'C';
+ io.KeyMap[ImGuiKey_V] = 'V';
+ io.KeyMap[ImGuiKey_X] = 'X';
+ io.KeyMap[ImGuiKey_Y] = 'Y';
+ io.KeyMap[ImGuiKey_Z] = 'Z';
+
+#if defined(IMGUI_GL2)
+ ImGui_ImplOpenGL2_Init();
+#elif defined(IMGUI_GL3)
+ ImGui_ImplOpenGL3_Init();
+#endif
+}
+
+void ImGuiUI::Impl::cleanupGL()
+{
+ ImGui::SetCurrentContext(fContext);
+#if defined(IMGUI_GL2)
+ ImGui_ImplOpenGL2_Shutdown();
+#elif defined(IMGUI_GL3)
+ ImGui_ImplOpenGL3_Shutdown();
+#endif
+ ImGui::DestroyContext(fContext);
+}
+
+int ImGuiUI::Impl::mouseButtonToImGui(int button)
+{
+ switch (button)
+ {
+ default:
+ return -1;
+ case 1:
+ return 0;
+ case 2:
+ return 2;
+ case 3:
+ return 1;
+ }
+}
+
+END_NAMESPACE_DGL
diff --git a/examples/ImguiSimpleGain/ImGuiUI.hpp b/examples/ImguiSimpleGain/ImGuiUI.hpp
@@ -0,0 +1,56 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "TopLevelWidget.hpp"
+#include "Color.hpp"
+
+#ifndef DGL_OPENGL
+# error ImGUI is only available in OpenGL mode
+#endif
+
+START_NAMESPACE_DGL
+
+/**
+ ImGui user interface class.
+*/
+class ImGuiUI : public TopLevelWidget,
+ public IdleCallback {
+public:
+ ImGuiUI(Window& windowToMapTo);
+ ~ImGuiUI() override;
+ void setBackgroundColor(Color color);
+ void setRepaintInterval(int intervalMs);
+
+protected:
+ virtual void onImGuiDisplay() = 0;
+
+ virtual void onDisplay() override;
+ virtual bool onKeyboard(const KeyboardEvent& event) override;
+ virtual bool onSpecial(const SpecialEvent& event) override;
+ virtual bool onMouse(const MouseEvent& event) override;
+ virtual bool onMotion(const MotionEvent& event) override;
+ virtual bool onScroll(const ScrollEvent& event) override;
+ virtual void onResize(const ResizeEvent& event) override;
+ virtual void idleCallback() override;
+
+private:
+ struct Impl;
+ Impl* fImpl;
+};
+
+END_NAMESPACE_DGL
diff --git a/examples/ImguiSimpleGain/Makefile b/examples/ImguiSimpleGain/Makefile
@@ -0,0 +1,51 @@
+#!/usr/bin/make -f
+# Makefile for DISTRHO Plugins #
+# ---------------------------- #
+# Created by falkTX, Christopher Arndt, and Patrick Desaulniers
+#
+
+# --------------------------------------------------------------
+# Project name, used for binaries
+
+NAME = d_ImguiSimpleGain
+
+# --------------------------------------------------------------
+# Files to build
+
+FILES_DSP = \
+ PluginSimpleGain.cpp
+
+FILES_UI = \
+ UISimpleGain.cpp \
+ ImGuiUI.cpp \
+ ImGuiSrc.cpp
+
+# --------------------------------------------------------------
+# Do some magic
+
+include ../../Makefile.plugins.mk
+
+BUILD_CXX_FLAGS += -I../../../imgui -I../../../imgui/backends
+BUILD_CXX_FLAGS += $(shell $(PKG_CONFIG) glew --cflags)
+LINK_FLAGS += $(shell $(PKG_CONFIG) glew --libs)
+
+# --------------------------------------------------------------
+# Enable all selected plugin types
+
+ifeq ($(HAVE_JACK),true)
+ifeq ($(HAVE_OPENGL),true)
+TARGETS += jack
+endif
+endif
+
+ifeq ($(HAVE_OPENGL),true)
+TARGETS += lv2_sep
+else
+TARGETS += lv2_dsp
+endif
+
+TARGETS += vst
+
+all: $(TARGETS)
+
+# --------------------------------------------------------------
diff --git a/examples/ImguiSimpleGain/PluginSimpleGain.cpp b/examples/ImguiSimpleGain/PluginSimpleGain.cpp
@@ -0,0 +1,161 @@
+/*
+ * Simple Gain audio effect based on DISTRHO Plugin Framework (DPF)
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "PluginSimpleGain.hpp"
+
+START_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------
+
+PluginSimpleGain::PluginSimpleGain()
+ : Plugin(paramCount, presetCount, 0) // paramCount param(s), presetCount program(s), 0 states
+{
+ smooth_gain = new CParamSmooth(20.0f, getSampleRate());
+
+ for (unsigned p = 0; p < paramCount; ++p) {
+ Parameter param;
+ initParameter(p, param);
+ setParameterValue(p, param.ranges.def);
+ }
+}
+
+PluginSimpleGain::~PluginSimpleGain() {
+ delete smooth_gain;
+}
+
+// -----------------------------------------------------------------------
+// Init
+
+void PluginSimpleGain::initParameter(uint32_t index, Parameter& parameter) {
+ if (index >= paramCount)
+ return;
+
+ parameter.ranges.min = -90.0f;
+ parameter.ranges.max = 30.0f;
+ parameter.ranges.def = -0.0f;
+ parameter.unit = "db";
+ parameter.hints = kParameterIsAutomable;
+
+ switch (index) {
+ case paramGain:
+ parameter.name = "Gain (dB)";
+ parameter.shortName = "Gain";
+ parameter.symbol = "gain";
+ break;
+ }
+}
+
+/**
+ Set the name of the program @a index.
+ This function will be called once, shortly after the plugin is created.
+*/
+void PluginSimpleGain::initProgramName(uint32_t index, String& programName) {
+ if (index < presetCount) {
+ programName = factoryPresets[index].name;
+ }
+}
+
+// -----------------------------------------------------------------------
+// Internal data
+
+/**
+ Optional callback to inform the plugin about a sample rate change.
+*/
+void PluginSimpleGain::sampleRateChanged(double newSampleRate) {
+ fSampleRate = newSampleRate;
+ smooth_gain->setSampleRate(newSampleRate);
+}
+
+/**
+ Get the current value of a parameter.
+*/
+float PluginSimpleGain::getParameterValue(uint32_t index) const {
+ return fParams[index];
+}
+
+/**
+ Change a parameter value.
+*/
+void PluginSimpleGain::setParameterValue(uint32_t index, float value) {
+ fParams[index] = value;
+
+ switch (index) {
+ case paramGain:
+ gain = DB_CO(CLAMP(fParams[paramGain], -90.0, 30.0));
+ break;
+ }
+}
+
+/**
+ Load a program.
+ The host may call this function from any context,
+ including realtime processing.
+*/
+void PluginSimpleGain::loadProgram(uint32_t index) {
+ if (index < presetCount) {
+ for (int i=0; i < paramCount; i++) {
+ setParameterValue(i, factoryPresets[index].params[i]);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+// Process
+
+void PluginSimpleGain::activate() {
+ // plugin is activated
+}
+
+
+
+void PluginSimpleGain::run(const float** inputs, float** outputs,
+ uint32_t frames) {
+
+ // get the left and right audio inputs
+ const float* const inpL = inputs[0];
+ const float* const inpR = inputs[1];
+
+ // get the left and right audio outputs
+ float* const outL = outputs[0];
+ float* const outR = outputs[1];
+
+ // apply gain against all samples
+ for (uint32_t i=0; i < frames; ++i) {
+ float gainval = smooth_gain->process(gain);
+ outL[i] = inpL[i] * gainval;
+ outR[i] = inpR[i] * gainval;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Plugin* createPlugin() {
+ return new PluginSimpleGain();
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
diff --git a/examples/ImguiSimpleGain/PluginSimpleGain.hpp b/examples/ImguiSimpleGain/PluginSimpleGain.hpp
@@ -0,0 +1,161 @@
+/*
+ * Simple Gain audio effect based on DISTRHO Plugin Framework (DPF)
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef PLUGIN_SIMPLEGAIN_H
+#define PLUGIN_SIMPLEGAIN_H
+
+#include "DistrhoPlugin.hpp"
+#include "CParamSmooth.hpp"
+
+START_NAMESPACE_DISTRHO
+
+#ifndef MIN
+#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+#endif
+
+#ifndef CLAMP
+#define CLAMP(v, min, max) (MIN((max), MAX((min), (v))))
+#endif
+
+#ifndef DB_CO
+#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
+#endif
+
+// -----------------------------------------------------------------------
+
+class PluginSimpleGain : public Plugin {
+public:
+ enum Parameters {
+ paramGain = 0,
+ paramCount
+ };
+
+ PluginSimpleGain();
+
+ ~PluginSimpleGain();
+
+protected:
+ // -------------------------------------------------------------------
+ // Information
+
+ const char* getLabel() const noexcept override {
+ return "SimpleGain";
+ }
+
+ const char* getDescription() const override {
+ return "A simple audio volume gain plugin";
+ }
+
+ const char* getMaker() const noexcept override {
+ return "example.com";
+ }
+
+ const char* getHomePage() const override {
+ return "https://example.com/plugins/simplegain";
+ }
+
+ const char* getLicense() const noexcept override {
+ return "https://spdx.org/licenses/MIT";
+ }
+
+ uint32_t getVersion() const noexcept override {
+ return d_version(0, 1, 0);
+ }
+
+ // Go to:
+ //
+ // http://service.steinberg.de/databases/plugin.nsf/plugIn
+ //
+ // Get a proper plugin UID and fill it in here!
+ int64_t getUniqueId() const noexcept override {
+ return d_cconst('a', 'b', 'c', 'd');
+ }
+
+ // -------------------------------------------------------------------
+ // Init
+
+ void initParameter(uint32_t index, Parameter& parameter) override;
+ void initProgramName(uint32_t index, String& programName) override;
+
+ // -------------------------------------------------------------------
+ // Internal data
+
+ float getParameterValue(uint32_t index) const override;
+ void setParameterValue(uint32_t index, float value) override;
+ void loadProgram(uint32_t index) override;
+
+ // -------------------------------------------------------------------
+ // Optional
+
+ // Optional callback to inform the plugin about a sample rate change.
+ void sampleRateChanged(double newSampleRate) override;
+
+ // -------------------------------------------------------------------
+ // Process
+
+ void activate() override;
+
+ void run(const float**, float** outputs, uint32_t frames) override;
+
+
+ // -------------------------------------------------------------------
+
+private:
+ float fParams[paramCount];
+ double fSampleRate;
+ float gain;
+ CParamSmooth *smooth_gain;
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginSimpleGain)
+};
+
+struct Preset {
+ const char* name;
+ float params[PluginSimpleGain::paramCount];
+};
+
+const Preset factoryPresets[] = {
+ {
+ "Unity Gain",
+ {0.0f}
+ }
+ //,{
+ // "Another preset", // preset name
+ // {-14.0f, ...} // array of presetCount float param values
+ //}
+};
+
+const uint presetCount = sizeof(factoryPresets) / sizeof(Preset);
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
+
+#endif // #ifndef PLUGIN_SIMPLEGAIN_H
diff --git a/examples/ImguiSimpleGain/UISimpleGain.cpp b/examples/ImguiSimpleGain/UISimpleGain.cpp
@@ -0,0 +1,130 @@
+/*
+ * Simple Gain audio effect based on DISTRHO Plugin Framework (DPF)
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "UISimpleGain.hpp"
+#include <imgui.h>
+// #include "Window.hpp"
+
+START_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------
+// Init / Deinit
+
+UISimpleGain::UISimpleGain()
+: UI(600, 400)
+{
+ setGeometryConstraints(600, 400, true);
+}
+
+UISimpleGain::~UISimpleGain() {
+
+}
+
+// -----------------------------------------------------------------------
+// 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 UISimpleGain::parameterChanged(uint32_t index, float value) {
+ params[index] = value;
+
+ switch (index) {
+ case PluginSimpleGain::paramGain:
+ // do something when Gain param is set, such as update a widget
+ break;
+ }
+
+ (void)value;
+}
+
+/**
+ A program has been loaded on the plugin side.
+ This is called by the host to inform the UI about program changes.
+*/
+void UISimpleGain::programLoaded(uint32_t index) {
+ if (index < presetCount) {
+ for (int i=0; i < PluginSimpleGain::paramCount; i++) {
+ // set values for each parameter and update their widgets
+ parameterChanged(i, factoryPresets[index].params[i]);
+ }
+ }
+}
+
+/**
+ Optional callback to inform the UI about a sample rate change on the plugin side.
+*/
+void UISimpleGain::sampleRateChanged(double newSampleRate) {
+ (void)newSampleRate;
+}
+
+// -----------------------------------------------------------------------
+// Widget callbacks
+
+
+/**
+ A function called to draw the view contents.
+*/
+void UISimpleGain::onImGuiDisplay() {
+ float width = getWidth();
+ float height = getHeight();
+ float margin = 20.0f;
+
+ ImGui::SetNextWindowPos(ImVec2(margin, margin));
+ ImGui::SetNextWindowSize(ImVec2(width - 2 * margin, height - 2 * margin));
+
+ if (ImGui::Begin("Simple gain")) {
+ static char aboutText[256] =
+ "This is a demo plugin made with ImGui.\n";
+ ImGui::InputTextMultiline("About", aboutText, sizeof(aboutText));
+
+ float& gain = params[PluginSimpleGain::paramGain];
+ if (ImGui::SliderFloat("Gain (dB)", &gain, -90.0f, 30.0f))
+ {
+ if (ImGui::IsItemActivated())
+ {
+ editParameter(PluginSimpleGain::paramGain, true);
+ }
+ setParameterValue(PluginSimpleGain::paramGain, gain);
+ }
+ if (ImGui::IsItemDeactivated())
+ {
+ editParameter(PluginSimpleGain::paramGain, false);
+ }
+ }
+ ImGui::End();
+}
+
+// -----------------------------------------------------------------------
+
+UI* createUI() {
+ return new UISimpleGain();
+}
+
+// -----------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
diff --git a/examples/ImguiSimpleGain/UISimpleGain.hpp b/examples/ImguiSimpleGain/UISimpleGain.hpp
@@ -0,0 +1,55 @@
+/*
+ * Simple Gain audio effect based on DISTRHO Plugin Framework (DPF)
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UI_SIMPLEGAIN_H
+#define UI_SIMPLEGAIN_H
+
+#include "DistrhoUI.hpp"
+#include "PluginSimpleGain.hpp"
+
+START_NAMESPACE_DISTRHO
+
+class UISimpleGain : public UI {
+public:
+ UISimpleGain();
+ ~UISimpleGain();
+
+protected:
+ void parameterChanged(uint32_t, float value) override;
+ void programLoaded(uint32_t index) override;
+ void sampleRateChanged(double newSampleRate) override;
+
+ void onImGuiDisplay() override;
+
+private:
+ float params[PluginSimpleGain::paramCount] {};
+
+ DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UISimpleGain)
+};
+
+END_NAMESPACE_DISTRHO
+
+#endif