diff --git a/examples/ExampleCompressor/PluginEditor.cpp b/examples/ExampleCompressor/PluginEditor.cpp index 092a1d9cb..eba413350 100644 --- a/examples/ExampleCompressor/PluginEditor.cpp +++ b/examples/ExampleCompressor/PluginEditor.cpp @@ -1,76 +1,123 @@ #include "PluginEditor.h" -void PluginEditor::LevelDetectorEditor::resized() +struct LevelDetectorEditor : juce::Component { - auto bounds = getLocalBounds(); - paramsView->setBounds (bounds.removeFromTop (proportionOfHeight (0.5f))); - viz->setBounds (bounds); -} + LevelDetectorEditor (chowdsp::PluginState& state, + Params& pluginParams, + chow_comp::LevelDetectorVisualizer& levelViz, + chowdsp::ComponentArena<>& arena) + : params { arena.allocator, "Level Detector Params", false }, + viz { &levelViz } + { + params.add (pluginParams.attack, pluginParams.release, pluginParams.levelDetectorMode); -void PluginEditor::GainComputerEditor::resized() -{ - auto bounds = getLocalBounds(); - paramsView->setBounds (bounds.removeFromTop (proportionOfHeight (0.5f))); - plot.setBounds (bounds); - updatePlot(); -} + paramsView = arena.allocate (state, params); + addAndMakeVisible (paramsView); -void PluginEditor::GainComputerEditor::setupPlot (chowdsp::PluginState& state, Params& plugParams) -{ - pluginParams = &plugParams; - gainComputer.prepare (48000.0, inputBuffer.getNumSamples()); - callbacks += { - state.addParameterListener (pluginParams->threshold, chowdsp::ParameterListenerThread::MessageThread, [this] - { updatePlot(); }), - state.addParameterListener (pluginParams->ratio, chowdsp::ParameterListenerThread::MessageThread, [this] - { updatePlot(); }), - state.addParameterListener (pluginParams->knee, chowdsp::ParameterListenerThread::MessageThread, [this] - { updatePlot(); }), - state.addParameterListener (pluginParams->architecture, chowdsp::ParameterListenerThread::MessageThread, [this] - { updatePlot(); }), - }; - for (auto [n, sample] : chowdsp::enumerate (inputBuffer.getWriteSpan (0))) - sample = juce::Decibels::decibelsToGain (juce::jmap ((float) n, - 0.0f, - (float) inputBuffer.getNumSamples(), - plot.params.xMin, - plot.params.xMax)); - updatePlot(); -} + addAndMakeVisible (viz); + } + + void resized() override + { + auto bounds = getLocalBounds(); + paramsView->setBounds (bounds.removeFromTop (proportionOfHeight (0.5f))); + viz->setBounds (bounds); + } + + chowdsp::ParamHolder params; + chowdsp::ParametersView* paramsView {}; + juce::Component* viz {}; +}; -void PluginEditor::GainComputerEditor::updatePlot() +struct GainComputerEditor : juce::Component { - gainComputer.setMode (*magic_enum::enum_index (pluginParams->architecture->get())); - gainComputer.setThreshold (pluginParams->threshold->get()); - gainComputer.setRatio (pluginParams->ratio->get()); - gainComputer.setKnee (pluginParams->knee->get()); - gainComputer.reset(); + GainComputerEditor (chowdsp::PluginState& state, + Params& plugParams, + chowdsp::ComponentArena<>& arena) + : params { arena.allocator, "Gain Computer Params", false } + { + params.add (plugParams.threshold, plugParams.ratio, plugParams.knee, plugParams.architecture, plugParams.autoMakeup); - gainComputer.processBlock (inputBuffer, outputBuffer); + paramsView = arena.allocate (state, params); + addAndMakeVisible (paramsView); - plot.setThreshold (pluginParams->threshold->get()); - plot.updatePlotPath (inputBuffer.getReadSpan (0), outputBuffer.getReadSpan (0)); -} + addAndMakeVisible (plot); + setupPlot (state, plugParams); + } + + void resized() override + { + auto bounds = getLocalBounds(); + paramsView->setBounds (bounds.removeFromTop (proportionOfHeight (0.5f))); + plot.setBounds (bounds); + updatePlot(); + } + + void setupPlot (chowdsp::PluginState& state, Params& plugParams) + { + pluginParams = &plugParams; + gainComputer.prepare (48000.0, inputBuffer.getNumSamples()); + callbacks += { + state.addParameterListener (pluginParams->threshold, chowdsp::ParameterListenerThread::MessageThread, [this] + { updatePlot(); }), + state.addParameterListener (pluginParams->ratio, chowdsp::ParameterListenerThread::MessageThread, [this] + { updatePlot(); }), + state.addParameterListener (pluginParams->knee, chowdsp::ParameterListenerThread::MessageThread, [this] + { updatePlot(); }), + state.addParameterListener (pluginParams->architecture, chowdsp::ParameterListenerThread::MessageThread, [this] + { updatePlot(); }), + }; + for (auto [n, sample] : chowdsp::enumerate (inputBuffer.getWriteSpan (0))) + sample = juce::Decibels::decibelsToGain (juce::jmap ((float) n, + 0.0f, + (float) inputBuffer.getNumSamples(), + plot.params.xMin, + plot.params.xMax)); + updatePlot(); + } + + void updatePlot() + { + gainComputer.setMode (*magic_enum::enum_index (pluginParams->architecture->get())); + gainComputer.setThreshold (pluginParams->threshold->get()); + gainComputer.setRatio (pluginParams->ratio->get()); + gainComputer.setKnee (pluginParams->knee->get()); + gainComputer.reset(); + + gainComputer.processBlock (inputBuffer, outputBuffer); + + plot.setThreshold (pluginParams->threshold->get()); + plot.updatePlotPath (inputBuffer.getReadSpan (0), outputBuffer.getReadSpan (0)); + } + + chowdsp::ParamHolder params; + chowdsp::ParametersView* paramsView {}; + + Params* pluginParams = nullptr; + GainComputer gainComputer; + chow_comp::GainComputerPlot plot; + + chowdsp::ScopedCallbackList callbacks; + static constexpr int plotNumSamples = 128; + chowdsp::StaticBuffer inputBuffer { 1, plotNumSamples }; + chowdsp::StaticBuffer outputBuffer { 1, plotNumSamples }; +}; PluginEditor::PluginEditor (ExampleCompressorPlugin& plugin) - : juce::AudioProcessorEditor (plugin), - meter (plugin.compressor.gainReductionMeterTask) + : juce::AudioProcessorEditor (plugin) { - auto& params = plugin.getState().params; - levelDetectorEditor.params.add (params.attack, params.release, params.levelDetectorMode); - levelDetectorEditor.paramsView.emplace (plugin.getState(), levelDetectorEditor.params); - levelDetectorEditor.addAndMakeVisible (*levelDetectorEditor.paramsView); - levelDetectorEditor.viz = &plugin.compressor.levelDetector.levelDetectorViz; - levelDetectorEditor.addAndMakeVisible (levelDetectorEditor.viz); + levelDetectorEditor = arena.allocate (plugin.getState(), + plugin.getState().params, + plugin.compressor.levelDetector.levelDetectorViz, + arena); addAndMakeVisible (levelDetectorEditor); - gainComputerEditor.params.add (params.threshold, params.ratio, params.knee, params.architecture, params.autoMakeup); - gainComputerEditor.paramsView.emplace (plugin.getState(), gainComputerEditor.params); - gainComputerEditor.addAndMakeVisible (*gainComputerEditor.paramsView); - gainComputerEditor.addAndMakeVisible (gainComputerEditor.plot); - gainComputerEditor.setupPlot (plugin.getState(), params); + gainComputerEditor = arena.allocate (plugin.getState(), + plugin.getState().params, + arena); addAndMakeVisible (gainComputerEditor); + meter = arena.allocate (plugin.compressor.gainReductionMeterTask); addAndMakeVisible (meter); setSize (900, 400); @@ -84,7 +131,7 @@ void PluginEditor::paint (juce::Graphics& g) void PluginEditor::resized() { auto bounds = getLocalBounds(); - levelDetectorEditor.setBounds (bounds.removeFromLeft (proportionOfWidth (0.46f))); - gainComputerEditor.setBounds (bounds.removeFromLeft (proportionOfWidth (0.46f))); - meter.setBounds (bounds); + levelDetectorEditor->setBounds (bounds.removeFromLeft (proportionOfWidth (0.46f))); + gainComputerEditor->setBounds (bounds.removeFromLeft (proportionOfWidth (0.46f))); + meter->setBounds (bounds); } diff --git a/examples/ExampleCompressor/PluginEditor.h b/examples/ExampleCompressor/PluginEditor.h index 84da68e50..711490eec 100644 --- a/examples/ExampleCompressor/PluginEditor.h +++ b/examples/ExampleCompressor/PluginEditor.h @@ -12,35 +12,10 @@ class PluginEditor : public juce::AudioProcessorEditor void resized() override; private: - struct LevelDetectorEditor : juce::Component - { - void resized() override; - - chowdsp::ParamHolder params { "Level Detector Params", false }; - std::optional paramsView; - juce::Component* viz; - } levelDetectorEditor; - - struct GainComputerEditor : juce::Component - { - void resized() override; - void setupPlot (chowdsp::PluginState& state, Params& pluginParams); - void updatePlot(); - - chowdsp::ParamHolder params { "Gain Computer Params", false }; - std::optional paramsView; - - Params* pluginParams = nullptr; - GainComputer gainComputer; - chow_comp::GainComputerPlot plot; - - chowdsp::ScopedCallbackList callbacks; - static constexpr int plotNumSamples = 128; - chowdsp::StaticBuffer inputBuffer { 1, plotNumSamples }; - chowdsp::StaticBuffer outputBuffer { 1, plotNumSamples }; - } gainComputerEditor; - - chow_comp::GainReductionMeter meter; + chowdsp::ComponentArena<> arena {}; + juce::Component* levelDetectorEditor {}; + juce::Component* gainComputerEditor {}; + juce::Component* meter; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginEditor) }; diff --git a/examples/SimpleEQ/SimpleEQPlugin.h b/examples/SimpleEQ/SimpleEQPlugin.h index de2ab3993..5a676daf8 100644 --- a/examples/SimpleEQ/SimpleEQPlugin.h +++ b/examples/SimpleEQ/SimpleEQPlugin.h @@ -42,7 +42,7 @@ struct Params : chowdsp::ParamHolder add (eqParams, linPhaseMode); } - EQParams eqParams { + EQParams eqParams { this, { BandParams { 0, "eq_band_0", "Band ", 100, bandTypeChoices, 10, 250.0f }, BandParams { 1, "eq_band_1", "Band ", 100, bandTypeChoices, 10, 1000.0f }, diff --git a/examples/StatefulPlugin/StatefulPlugin.h b/examples/StatefulPlugin/StatefulPlugin.h index e7dbcf783..ce91d092d 100644 --- a/examples/StatefulPlugin/StatefulPlugin.h +++ b/examples/StatefulPlugin/StatefulPlugin.h @@ -5,7 +5,7 @@ struct LevelParams : chowdsp::ParamHolder { - LevelParams() : chowdsp::ParamHolder ("Level") + explicit LevelParams (ParamHolder* parent) : ParamHolder { parent, "Level" } { add (percent, gain); } @@ -22,7 +22,7 @@ struct PluginParameterState : chowdsp::ParamHolder add (levelParams, mode, onOff); } - LevelParams levelParams; + LevelParams levelParams { this }; chowdsp::ChoiceParameter::Ptr mode { juce::ParameterID { "mode", 100 }, "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { juce::ParameterID { "on_off", 100 }, "On/Off", true }; }; diff --git a/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.cpp b/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.cpp index 124bb4477..6e3be7cdb 100644 --- a/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.cpp +++ b/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.cpp @@ -1,20 +1,25 @@ #if JUCE_MODULE_AVAILABLE_chowdsp_plugin_state +#include + namespace chowdsp::EQ { template -StandardEQParameters::StandardEQParameters (EQParameterHandles&& paramHandles, - const juce::String& paramHolderName) - : ParamHolder (paramHolderName), - eqParams (std::move (paramHandles)) +StandardEQParameters::StandardEQParameters (ParamHolder* parent, + EQParameterHandles&& paramHandles, + std::string_view paramHolderName) + : ParamHolder { parent, paramHolderName }, + eqParams { std::move (paramHandles) } { for (auto& bandParams : eqParams) { - bandParams.paramHolder.add (bandParams.onOffParam, + bandParams.paramHolder.emplace (this, + format (*arena, "{} {}", bandParams.bandNamePrefix, bandParams.bandIndex + 1)); + bandParams.paramHolder->add (bandParams.onOffParam, bandParams.typeParam, bandParams.freqParam, bandParams.qParam, bandParams.gainParam); - add (bandParams.paramHolder); + add (*bandParams.paramHolder); } } diff --git a/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.h b/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.h index 932025baf..8fea1b08b 100644 --- a/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.h +++ b/modules/dsp/chowdsp_eq/EQ/chowdsp_StandardEQParameters.h @@ -94,14 +94,14 @@ struct StandardEQParameters : ParamHolder }; /** Internal use only! */ - chowdsp::ParamHolder paramHolder { bandNamePrefix + juce::String (bandIndex + 1) }; + std::optional paramHolder { std::nullopt }; }; /** Set of parameter handles for the entire EQ. */ using EQParameterHandles = std::array; /** Constructor */ - explicit StandardEQParameters (EQParameterHandles&& paramHandles, const juce::String& name = {}); + explicit StandardEQParameters (ParamHolder* parent, EQParameterHandles&& paramHandles, std::string_view name = {}); /** Parameter handles */ EQParameterHandles eqParams; diff --git a/modules/gui/chowdsp_gui/PluginComponents/chowdsp_ParametersView.cpp b/modules/gui/chowdsp_gui/PluginComponents/chowdsp_ParametersView.cpp index 6a124c914..cb83f9207 100644 --- a/modules/gui/chowdsp_gui/PluginComponents/chowdsp_ParametersView.cpp +++ b/modules/gui/chowdsp_gui/PluginComponents/chowdsp_ParametersView.cpp @@ -166,10 +166,10 @@ namespace parameters_view_detail std::unique_ptr createItemComponent() override { - return std::make_unique (name, name); + return std::make_unique (toString (name), toString (name)); } - juce::String name; + std::string_view name; }; } // namespace parameters_view_detail #endif diff --git a/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.cpp b/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.cpp index 3611aa5d3..ce46dc6e4 100644 --- a/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.cpp +++ b/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.cpp @@ -1,35 +1,47 @@ namespace chowdsp { JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wswitch-enum") -inline ParamHolder::ParamHolder (const juce::String& phName, bool phIsOwning) - : name (phName), - isOwning (phIsOwning) +inline ParamHolder::ParamHolder (ParamHolder* parent, std::string_view phName, bool phIsOwning) + : arena { + [parent] + { + if (parent != nullptr) + { + jassert (parent->arena != nullptr); + return OptionalPointer { parent->arena.get(), false }; + } + return OptionalPointer { static_cast (1024) }; + }(), + }, + name { phName }, + isOwning { phIsOwning } +{ +} + +inline ParamHolder::ParamHolder (ChainedArenaAllocator& alloc, std::string_view phName, bool phIsOwning) + : arena { &alloc, false }, name { phName }, isOwning { phIsOwning } { - juce::ignoreUnused (isOwning); } inline ParamHolder::~ParamHolder() { - if (isOwning) + for (auto& thing : things) { - for (auto& thing : things) + if (getShouldDelete (thing)) { - if (getShouldDelete (thing)) + switch (getType (thing)) { - switch (getType (thing)) - { - case FloatParam: - delete reinterpret_cast (thing.get_ptr()); - break; - case ChoiceParam: - delete reinterpret_cast (thing.get_ptr()); - break; - case BoolParam: - delete reinterpret_cast (thing.get_ptr()); - break; - default: - break; - } + case FloatParam: + delete reinterpret_cast (thing.get_ptr()); + break; + case ChoiceParam: + delete reinterpret_cast (thing.get_ptr()); + break; + case BoolParam: + delete reinterpret_cast (thing.get_ptr()); + break; + default: + break; } } } @@ -53,7 +65,7 @@ std::enable_if_t, void> { const auto paramID = toStringView (choiceParam->paramID); ThingPtr paramPtr { reinterpret_cast (isOwning ? choiceParam.release() : choiceParam.get()), - getFlags (ChoiceParam, isOwning) }; + getFlags (ChoiceParam, isOwning) }; allParamsMap.insert ({ paramID, paramPtr }); things.insert (std::move (paramPtr)); add (others...); @@ -65,7 +77,7 @@ std::enable_if_t, void> { const auto paramID = toStringView (boolParam->paramID); ThingPtr paramPtr { reinterpret_cast (isOwning ? boolParam.release() : boolParam.get()), - getFlags (BoolParam, isOwning) }; + getFlags (BoolParam, isOwning) }; allParamsMap.insert ({ paramID, paramPtr }); things.insert (std::move (paramPtr)); add (others...); @@ -132,7 +144,7 @@ inline void ParamHolder::clear() allParamsMap.clear(); things.clear(); - arena.clear(); + arena->clear(); // @TODO: is this actually what we want to do? what if there's the stuff in the arena? } inline void ParamHolder::connectParametersToProcessor (juce::AudioProcessor& processor) @@ -295,13 +307,13 @@ void ParamHolder::deserialize (typename Serializer::DeserializedType deserial, P { case FloatParam: deserializeParam (reinterpret_cast (paramPtr.get_ptr()), paramDeserial); - break; + break; case ChoiceParam: deserializeParam (reinterpret_cast (paramPtr.get_ptr()), paramDeserial); - break; + break; case BoolParam: deserializeParam (reinterpret_cast (paramPtr.get_ptr()), paramDeserial); - break; + break; default: jassertfalse; break; diff --git a/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.h b/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.h index 478365060..acc70f5f6 100644 --- a/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.h +++ b/modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.h @@ -14,8 +14,9 @@ class ParamHolder * or make it "non-owning" so it doesn't take ownership of the parameter * pointers. */ - explicit ParamHolder (const juce::String& name = {}, bool isOwning = true); - virtual ~ParamHolder(); + explicit ParamHolder (ParamHolder* parent = nullptr, std::string_view name = {}, bool isOwning = true); + explicit ParamHolder (ChainedArenaAllocator& alloc, std::string_view name = {}, bool isOwning = true); + ~ParamHolder(); ParamHolder (ParamHolder&&) noexcept = default; ParamHolder& operator= (ParamHolder&&) noexcept = default; @@ -69,7 +70,7 @@ class ParamHolder void connectParametersToProcessor (juce::AudioProcessor& processor); /** Returns the paramHolder name */ - [[nodiscard]] juce::String getName() const noexcept { return name; } + [[nodiscard]] std::string_view getName() const noexcept { return name; } /** Internal use only! */ template @@ -106,7 +107,10 @@ class ParamHolder void applyVersionStreaming (const Version&); /** Assign this function to apply version streaming to your non-parameter state. */ - std::function versionStreamingCallback = nullptr; + juce::FixedSizeFunction<8, void (const Version&)> versionStreamingCallback {}; + +protected: + OptionalPointer arena {}; private: void add() const @@ -114,8 +118,6 @@ class ParamHolder // base case! } - ChainedArenaAllocator arena { 1024 }; - enum ThingInfo : uint8_t { FloatParam = 0, @@ -126,7 +128,7 @@ class ParamHolder ShouldDelete = 4, }; using ThingPtr = PackedPointer; - ChunkList things { arena }; + ChunkList things { arena }; static ThingInfo getType (const ThingPtr& thingPtr) { @@ -144,10 +146,9 @@ class ParamHolder using MapKey = std::string_view; using MapValue = ThingPtr; using MapAllocator = STLArenaAllocator, ChainedArenaAllocator>; - MapAllocator mapAllocator { arena }; - std::unordered_map, std::equal_to, MapAllocator> allParamsMap { mapAllocator }; + std::unordered_map, std::equal_to, MapAllocator> allParamsMap { MapAllocator { arena } }; - juce::String name; + std::string_view name; bool isOwning; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamHolder) diff --git a/tests/gui_tests/chowdsp_gui_test/ParametersViewTest.cpp b/tests/gui_tests/chowdsp_gui_test/ParametersViewTest.cpp index 76064e1ca..ba6e540eb 100644 --- a/tests/gui_tests/chowdsp_gui_test/ParametersViewTest.cpp +++ b/tests/gui_tests/chowdsp_gui_test/ParametersViewTest.cpp @@ -6,7 +6,7 @@ namespace params_view_test { struct LevelParams : chowdsp::ParamHolder { - explicit LevelParams (const juce::String& paramPrefix = "", int version = 100) + explicit LevelParams (chowdsp::ChainedArenaAllocator& arena, const juce::String& paramPrefix = "", int version = 100) : prefix (paramPrefix), versionHint (version) { @@ -27,7 +27,7 @@ struct PluginParameterState : chowdsp::ParamHolder add (levelParams, mode, onOff); } - LevelParams levelParams; + LevelParams levelParams { *arena }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; }; diff --git a/tests/plugin_tests/chowdsp_plugin_state_test/ParamHolderTest.cpp b/tests/plugin_tests/chowdsp_plugin_state_test/ParamHolderTest.cpp index 4d05a8aad..720eba50a 100644 --- a/tests/plugin_tests/chowdsp_plugin_state_test/ParamHolderTest.cpp +++ b/tests/plugin_tests/chowdsp_plugin_state_test/ParamHolderTest.cpp @@ -33,7 +33,7 @@ TEST_CASE ("ParamHolder Test", "[plugin][state]") SECTION ("clear()") { - chowdsp::ParamHolder params { "Params", false }; + chowdsp::ParamHolder params { nullptr, "Params", false }; chowdsp::PercentParameter::Ptr pct_param { "percent", "Percent", 0.5f }; chowdsp::PercentParameter::Ptr pct_param2 { "percent2", "Percent 2", 0.5f }; params.add (pct_param, pct_param2); diff --git a/tests/plugin_tests/chowdsp_plugin_state_test/StatePluginInterfaceTest.cpp b/tests/plugin_tests/chowdsp_plugin_state_test/StatePluginInterfaceTest.cpp index 2afcdc140..bb118d266 100644 --- a/tests/plugin_tests/chowdsp_plugin_state_test/StatePluginInterfaceTest.cpp +++ b/tests/plugin_tests/chowdsp_plugin_state_test/StatePluginInterfaceTest.cpp @@ -4,7 +4,8 @@ struct LevelParams2 : chowdsp::ParamHolder { - LevelParams2() + explicit LevelParams2 (ParamHolder* parent) + : ParamHolder { parent } { add (percent, gain); } @@ -20,7 +21,7 @@ struct PluginParameterState2 : chowdsp::ParamHolder add (levelParams, mode, onOff); } - LevelParams2 levelParams; + LevelParams2 levelParams { this }; chowdsp::ChoiceParameter::Ptr mode { juce::ParameterID { "mode", 100 }, "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { juce::ParameterID { "on_off", 100 }, "On/Off", true }; }; diff --git a/tests/plugin_tests/chowdsp_plugin_state_test/StateSerializationTest.cpp b/tests/plugin_tests/chowdsp_plugin_state_test/StateSerializationTest.cpp index 4a82fba68..70d50b8f5 100644 --- a/tests/plugin_tests/chowdsp_plugin_state_test/StateSerializationTest.cpp +++ b/tests/plugin_tests/chowdsp_plugin_state_test/StateSerializationTest.cpp @@ -3,8 +3,9 @@ struct LevelParams : chowdsp::ParamHolder { - explicit LevelParams (const juce::String& paramPrefix = "", int version = 100) - : prefix (paramPrefix), + explicit LevelParams (ParamHolder* parent, const juce::String& paramPrefix = "", int version = 100) + : ParamHolder (parent), + prefix (paramPrefix), versionHint (version) { add (percent, gain); @@ -24,7 +25,7 @@ struct PluginParameterState : chowdsp::ParamHolder add (levelParams, mode, onOff); } - LevelParams levelParams; + LevelParams levelParams { this }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; }; @@ -74,7 +75,7 @@ struct PluginParameterStateNewParam : chowdsp::ParamHolder add (levelParams, mode, onOff, newParam); } - LevelParams levelParams; + LevelParams levelParams { this }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; chowdsp::GainDBParameter::Ptr newParam { "gain_new", "New Gain", juce::NormalisableRange { -45.0f, 12.0f }, 3.3f }; @@ -89,8 +90,8 @@ struct PluginParameterStateDoubleOfSameType : chowdsp::ParamHolder add (levelParams1, levelParams2, mode, onOff); } - LevelParams levelParams1 { "level_params1" }; - LevelParams levelParams2 { "level_params2", 101 }; + LevelParams levelParams1 { this, "level_params1" }; + LevelParams levelParams2 { this, "level_params2", 101 }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; }; @@ -104,9 +105,9 @@ struct PluginParameterStateTripleOfSameType : chowdsp::ParamHolder add (levelParams1, levelParams2, levelParams3, mode, onOff); } - LevelParams levelParams1 { "level_params1" }; - LevelParams levelParams2 { "level_params2", 101 }; - LevelParams levelParams3 { "level_params3", 102 }; + LevelParams levelParams1 { this, "level_params1" }; + LevelParams levelParams2 { this, "level_params2", 101 }; + LevelParams levelParams3 { this, "level_params3", 102 }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; }; @@ -131,7 +132,7 @@ struct PluginParameterStateNewGroup : chowdsp::ParamHolder add (levelParams, mode, onOff, newGroup); } - LevelParams levelParams; + LevelParams levelParams { this }; chowdsp::ChoiceParameter::Ptr mode { "mode", "Mode", juce::StringArray { "Percent", "Gain", "Percent / Gain", "Gain / Percent" }, 2 }; chowdsp::BoolParameter::Ptr onOff { "on_off", "On/Off", true }; NewGroup newGroup; diff --git a/tests/plugin_tests/chowdsp_plugin_state_test/VersionStreamingTest.cpp b/tests/plugin_tests/chowdsp_plugin_state_test/VersionStreamingTest.cpp index 4bb84eeb3..aa5e43f99 100644 --- a/tests/plugin_tests/chowdsp_plugin_state_test/VersionStreamingTest.cpp +++ b/tests/plugin_tests/chowdsp_plugin_state_test/VersionStreamingTest.cpp @@ -12,9 +12,10 @@ struct Params : chowdsp::ParamHolder chowdsp::BoolParameter::Ptr param { "bool", "Bool", false }; - struct InnerParams : chowdsp::ParamHolder + struct InnerParams : ParamHolder { - InnerParams() + explicit InnerParams (ParamHolder* parent) + : ParamHolder { parent } { add (param); versionStreamingCallback = [this] (const chowdsp::Version& version) @@ -25,7 +26,7 @@ struct Params : chowdsp::ParamHolder } chowdsp::BoolParameter::Ptr param { "bool2", "Bool", false }; - } innerParams; + } innerParams { this }; }; struct NonParams : chowdsp::NonParamState