Signed-off-by: falkTX <falktx@falktx.com>pull/341/head
| @@ -30,6 +30,10 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| inline void flush() { | |||||
| z = 0.0f; | |||||
| } | |||||
| inline float process(float in) { | inline float process(float in) { | ||||
| return z = (in * b) + (z * a); | return z = (in * b) + (z * a); | ||||
| } | } | ||||
| @@ -22,7 +22,7 @@ | |||||
| This is used to identify your plugin before a Plugin instance can be created. | This is used to identify your plugin before a Plugin instance can be created. | ||||
| @note This macro is required. | @note This macro is required. | ||||
| */ | */ | ||||
| #define DISTRHO_PLUGIN_NAME "ImguiSimpleGain" | |||||
| #define DISTRHO_PLUGIN_NAME "ImGuiSimpleGain" | |||||
| /** | /** | ||||
| Number of audio inputs the plugin has. | Number of audio inputs the plugin has. | ||||
| @@ -93,7 +93,7 @@ | |||||
| @see Plugin::initProgramName(uint32_t, String&) | @see Plugin::initProgramName(uint32_t, String&) | ||||
| @see Plugin::loadProgram(uint32_t) | @see Plugin::loadProgram(uint32_t) | ||||
| */ | */ | ||||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 0 | |||||
| /** | /** | ||||
| Wherever the plugin uses internal non-parameter data. | Wherever the plugin uses internal non-parameter data. | ||||
| @@ -7,7 +7,7 @@ | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Project name, used for binaries | # Project name, used for binaries | ||||
| NAME = d_ImguiSimpleGain | |||||
| NAME = d_ImGuiSimpleGain | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Files to build | # Files to build | ||||
| @@ -30,7 +30,7 @@ BUILD_CXX_FLAGS += -I../../../DPF-Widgets/opengl/ | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Enable all selected plugin types | # Enable all selected plugin types | ||||
| TARGETS += jack lv2_sep vst3 | |||||
| TARGETS += jack lv2_sep vst2 vst3 | |||||
| ifeq ($(HAVE_LIBLO),true) | ifeq ($(HAVE_LIBLO),true) | ||||
| TARGETS += dssi | TARGETS += dssi | ||||
| @@ -31,109 +31,65 @@ START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| PluginSimpleGain::PluginSimpleGain() | PluginSimpleGain::PluginSimpleGain() | ||||
| : Plugin(paramCount, presetCount, 0) // paramCount param(s), presetCount program(s), 0 states | |||||
| : Plugin(paramCount, 0, 0), // parameters, programs, states | |||||
| fSampleRate(getSampleRate()), | |||||
| fGainDB(0.0f), | |||||
| fGainLinear(1.0f) | |||||
| { | { | ||||
| 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; | |||||
| fSmoothGain = new CParamSmooth(20.0f, fSampleRate); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Init | // Init | ||||
| void PluginSimpleGain::initParameter(uint32_t index, Parameter& parameter) { | |||||
| if (index >= paramCount) | |||||
| return; | |||||
| void PluginSimpleGain::initParameter(uint32_t index, Parameter& parameter) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(index == 0,); | |||||
| parameter.ranges.min = -90.0f; | parameter.ranges.min = -90.0f; | ||||
| parameter.ranges.max = 30.0f; | parameter.ranges.max = 30.0f; | ||||
| parameter.ranges.def = -0.0f; | parameter.ranges.def = -0.0f; | ||||
| parameter.unit = "db"; | |||||
| parameter.hints = kParameterIsAutomable; | 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; | |||||
| } | |||||
| parameter.name = "Gain"; | |||||
| parameter.shortName = "Gain"; | |||||
| parameter.symbol = "gain"; | |||||
| parameter.unit = "dB"; | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Internal data | // 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. | Get the current value of a parameter. | ||||
| */ | */ | ||||
| float PluginSimpleGain::getParameterValue(uint32_t index) const { | |||||
| return fParams[index]; | |||||
| float PluginSimpleGain::getParameterValue(uint32_t index) const | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(index == 0, 0.0f); | |||||
| return fGainDB; | |||||
| } | } | ||||
| /** | /** | ||||
| Change a parameter value. | 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; | |||||
| } | |||||
| } | |||||
| void PluginSimpleGain::setParameterValue(uint32_t index, float value) | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(index == 0,); | |||||
| /** | |||||
| 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]); | |||||
| } | |||||
| } | |||||
| fGainDB = value; | |||||
| fGainLinear = DB_CO(CLAMP(value, -90.0, 30.0)); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Process | // Process | ||||
| void PluginSimpleGain::activate() { | |||||
| // plugin is activated | |||||
| void PluginSimpleGain::activate() | |||||
| { | |||||
| fSmoothGain->flush(); | |||||
| } | } | ||||
| void PluginSimpleGain::run(const float** inputs, float** outputs, | |||||
| uint32_t frames) { | |||||
| void PluginSimpleGain::run(const float** inputs, float** outputs, uint32_t frames) | |||||
| { | |||||
| // get the left and right audio inputs | // get the left and right audio inputs | ||||
| const float* const inpL = inputs[0]; | const float* const inpL = inputs[0]; | ||||
| const float* const inpR = inputs[1]; | const float* const inpR = inputs[1]; | ||||
| @@ -143,16 +99,29 @@ void PluginSimpleGain::run(const float** inputs, float** outputs, | |||||
| float* const outR = outputs[1]; | float* const outR = outputs[1]; | ||||
| // apply gain against all samples | // 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; | |||||
| for (uint32_t i=0; i < frames; ++i) | |||||
| { | |||||
| const float gain = fSmoothGain->process(fGainLinear); | |||||
| outL[i] = inpL[i] * gain; | |||||
| outR[i] = inpR[i] * gain; | |||||
| } | } | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| Plugin* createPlugin() { | |||||
| /** | |||||
| Optional callback to inform the plugin about a sample rate change. | |||||
| */ | |||||
| void PluginSimpleGain::sampleRateChanged(double newSampleRate) | |||||
| { | |||||
| fSampleRate = newSampleRate; | |||||
| fSmoothGain->setSampleRate(newSampleRate); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| Plugin* createPlugin() | |||||
| { | |||||
| return new PluginSimpleGain(); | return new PluginSimpleGain(); | ||||
| } | } | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "DistrhoPlugin.hpp" | #include "DistrhoPlugin.hpp" | ||||
| #include "CParamSmooth.hpp" | #include "CParamSmooth.hpp" | ||||
| #include "extra/ScopedPointer.hpp" | |||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -59,57 +60,50 @@ public: | |||||
| PluginSimpleGain(); | PluginSimpleGain(); | ||||
| ~PluginSimpleGain(); | |||||
| protected: | protected: | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Information | // Information | ||||
| const char* getLabel() const noexcept override { | |||||
| const char* getLabel() const noexcept override | |||||
| { | |||||
| return "SimpleGain"; | 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* getDescription() const override | |||||
| { | |||||
| return "A simple audio volume gain plugin with ImGui for its GUI"; | |||||
| } | } | ||||
| const char* getHomePage() const override { | |||||
| return "https://example.com/plugins/simplegain"; | |||||
| const char* getMaker() const noexcept override | |||||
| { | |||||
| return "Jean Pierre Cimalando, falkTX"; | |||||
| } | } | ||||
| const char* getLicense() const noexcept override { | |||||
| return "https://spdx.org/licenses/MIT"; | |||||
| const char* getLicense() const noexcept override | |||||
| { | |||||
| return "MIT"; | |||||
| } | } | ||||
| uint32_t getVersion() const noexcept override { | |||||
| return d_version(0, 1, 0); | |||||
| uint32_t getVersion() const noexcept override | |||||
| { | |||||
| return d_version(1, 0, 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'); | |||||
| int64_t getUniqueId() const noexcept override | |||||
| { | |||||
| return d_cconst('d', 'I', 'm', 'G'); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Init | // Init | ||||
| void initParameter(uint32_t index, Parameter& parameter) override; | void initParameter(uint32_t index, Parameter& parameter) override; | ||||
| void initProgramName(uint32_t index, String& programName) override; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Internal data | // Internal data | ||||
| float getParameterValue(uint32_t index) const override; | float getParameterValue(uint32_t index) const override; | ||||
| void setParameterValue(uint32_t index, float value) override; | void setParameterValue(uint32_t index, float value) override; | ||||
| void loadProgram(uint32_t index) override; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Optional | // Optional | ||||
| @@ -121,39 +115,19 @@ protected: | |||||
| // Process | // Process | ||||
| void activate() override; | void activate() override; | ||||
| void run(const float**, float** outputs, uint32_t frames) override; | void run(const float**, float** outputs, uint32_t frames) override; | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| private: | private: | ||||
| float fParams[paramCount]; | |||||
| double fSampleRate; | |||||
| float gain; | |||||
| CParamSmooth *smooth_gain; | |||||
| double fSampleRate; | |||||
| float fGainDB; | |||||
| float fGainLinear; | |||||
| ScopedPointer<CParamSmooth> fSmoothGain; | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginSimpleGain) | 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 | END_NAMESPACE_DISTRHO | ||||
| @@ -32,13 +32,15 @@ START_NAMESPACE_DISTRHO | |||||
| // Init / Deinit | // Init / Deinit | ||||
| UISimpleGain::UISimpleGain() | UISimpleGain::UISimpleGain() | ||||
| : UI(600, 400) | |||||
| : UI(600, 400), | |||||
| fGain(0.0f), | |||||
| fResizeHandle(this) | |||||
| { | { | ||||
| setGeometryConstraints(600, 400, true); | setGeometryConstraints(600, 400, true); | ||||
| } | |||||
| UISimpleGain::~UISimpleGain() | |||||
| { | |||||
| // hide handle if UI is resizable | |||||
| if (isResizable()) | |||||
| fResizeHandle.hide(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -50,46 +52,15 @@ UISimpleGain::~UISimpleGain() | |||||
| */ | */ | ||||
| void UISimpleGain::parameterChanged(uint32_t index, float value) | 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; | |||||
| } | |||||
| DISTRHO_SAFE_ASSERT_RETURN(index == 0,); | |||||
| (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; | |||||
| fGain = value; | |||||
| repaint(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Widget callbacks | // Widget callbacks | ||||
| /** | /** | ||||
| A function called to draw the view contents. | A function called to draw the view contents. | ||||
| */ | */ | ||||
| @@ -97,28 +68,27 @@ void UISimpleGain::onImGuiDisplay() | |||||
| { | { | ||||
| const float width = getWidth(); | const float width = getWidth(); | ||||
| const float height = getHeight(); | const float height = getHeight(); | ||||
| const float margin = 20.0f; | |||||
| const float margin = 20.0f * getScaleFactor(); | |||||
| ImGui::SetNextWindowPos(ImVec2(margin, margin)); | ImGui::SetNextWindowPos(ImVec2(margin, margin)); | ||||
| ImGui::SetNextWindowSize(ImVec2(width - 2 * margin, height - 2 * 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"; | |||||
| if (ImGui::Begin("Simple gain", nullptr, ImGuiWindowFlags_NoResize)) | |||||
| { | |||||
| static char aboutText[256] = "This is a demo plugin made with ImGui.\n"; | |||||
| ImGui::InputTextMultiline("About", aboutText, sizeof(aboutText)); | ImGui::InputTextMultiline("About", aboutText, sizeof(aboutText)); | ||||
| float& gain = params[PluginSimpleGain::paramGain]; | |||||
| if (ImGui::SliderFloat("Gain (dB)", &gain, -90.0f, 30.0f)) | |||||
| if (ImGui::SliderFloat("Gain (dB)", &fGain, -90.0f, 30.0f)) | |||||
| { | { | ||||
| if (ImGui::IsItemActivated()) | if (ImGui::IsItemActivated()) | ||||
| { | |||||
| editParameter(PluginSimpleGain::paramGain, true); | |||||
| } | |||||
| setParameterValue(PluginSimpleGain::paramGain, gain); | |||||
| editParameter(0, true); | |||||
| setParameterValue(0, fGain); | |||||
| } | } | ||||
| if (ImGui::IsItemDeactivated()) | if (ImGui::IsItemDeactivated()) | ||||
| { | { | ||||
| editParameter(PluginSimpleGain::paramGain, false); | |||||
| editParameter(0, false); | |||||
| } | } | ||||
| } | } | ||||
| ImGui::End(); | ImGui::End(); | ||||
| @@ -28,24 +28,25 @@ | |||||
| #define UI_SIMPLEGAIN_H | #define UI_SIMPLEGAIN_H | ||||
| #include "DistrhoUI.hpp" | #include "DistrhoUI.hpp" | ||||
| #include "PluginSimpleGain.hpp" | |||||
| #include "../generic/ResizeHandle.hpp" | |||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| class UISimpleGain : public UI { | |||||
| class UISimpleGain : public UI | |||||
| { | |||||
| public: | public: | ||||
| UISimpleGain(); | UISimpleGain(); | ||||
| ~UISimpleGain(); | |||||
| protected: | protected: | ||||
| // DSP/Plugin callbacks | |||||
| void parameterChanged(uint32_t, float value) override; | void parameterChanged(uint32_t, float value) override; | ||||
| void programLoaded(uint32_t index) override; | |||||
| void sampleRateChanged(double newSampleRate) override; | |||||
| // Widget callbacks | |||||
| void onImGuiDisplay() override; | void onImGuiDisplay() override; | ||||
| private: | private: | ||||
| float params[PluginSimpleGain::paramCount] {}; | |||||
| float fGain; | |||||
| ResizeHandle fResizeHandle; | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UISimpleGain) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UISimpleGain) | ||||
| }; | }; | ||||