From b194cc2146f11b8794c5249e830c57f1f7ecbf4d Mon Sep 17 00:00:00 2001 From: StoneyDSP Date: Fri, 8 Mar 2024 06:21:10 +0100 Subject: [PATCH] initial juce::AudioProcessor overrides --- .vscode/settings.json | 7 +- include/StoneyDSP/Biquads/PluginEditor.hpp | 7 ++ include/StoneyDSP/Biquads/PluginProcessor.hpp | 39 +++++++- src/StoneyDSP/Biquads/PluginEditor.cpp | 5 +- src/StoneyDSP/Biquads/PluginProcessor.cpp | 88 ++++++++++++++++--- 5 files changed, 129 insertions(+), 17 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1cbd599..068e37f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -170,9 +170,8 @@ "files.associations": { "**.bash**": "shellscript", "**.cmake": "cmake", - "ignore": "ignore", ".editorconfig": "editorconfig", - + "ignore": "ignore", "array": "cpp", "atomic": "cpp", "bit": "cpp", @@ -191,7 +190,6 @@ "cstring": "cpp", "ctime": "cpp", "cwchar": "cpp", - "exception": "cpp", "initializer_list": "cpp", "ios": "cpp", @@ -266,6 +264,7 @@ "xlocmes": "cpp", "xlocmon": "cpp", "xloctime": "cpp", - "xtree": "cpp" + "xtree": "cpp", + "*.mm": "cpp" } } diff --git a/include/StoneyDSP/Biquads/PluginEditor.hpp b/include/StoneyDSP/Biquads/PluginEditor.hpp index 0c49ec6..cea1da2 100644 --- a/include/StoneyDSP/Biquads/PluginEditor.hpp +++ b/include/StoneyDSP/Biquads/PluginEditor.hpp @@ -30,5 +30,12 @@ class BiquadsAudioProcessorEditor final : public juce::AudioProcessorEditor // access the processor object that created it. BiquadsAudioProcessor& processorRef; + juce::AudioProcessorValueTreeState& state; + + juce::UndoManager& undoManager; + + juce::ArrowButton undoButton { "Undo", 0.5f , juce::Colours::white }; + juce::ArrowButton redoButton { "Redo", 0.0f , juce::Colours::white }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BiquadsAudioProcessorEditor) }; diff --git a/include/StoneyDSP/Biquads/PluginProcessor.hpp b/include/StoneyDSP/Biquads/PluginProcessor.hpp index 316ad32..f5cc79e 100644 --- a/include/StoneyDSP/Biquads/PluginProcessor.hpp +++ b/include/StoneyDSP/Biquads/PluginProcessor.hpp @@ -12,9 +12,9 @@ #pragma once -#include +// #include -// #include +#include // #include "PluginParameters.h" // #include "PluginWrapper.h" @@ -27,6 +27,11 @@ class BiquadsAudioProcessor final : public juce::AudioProcessor BiquadsAudioProcessor(); ~BiquadsAudioProcessor() override; + //========================================================================== + juce::AudioProcessorParameter* getBypassParameter() const override; + bool isBypassed() const noexcept; + void setBypassParameter(juce::AudioParameterBool* newBypass) noexcept; + //============================================================================== void prepareToPlay (double sampleRate, int samplesPerBlock) override; void releaseResources() override; @@ -57,7 +62,37 @@ class BiquadsAudioProcessor final : public juce::AudioProcessor //============================================================================== void getStateInformation (juce::MemoryBlock& destData) override; + void getCurrentProgramStateInformation(juce::MemoryBlock& destData) override; void setStateInformation (const void* data, int sizeInBytes) override; + void setCurrentProgramStateInformation(const void* data, int sizeInBytes) override; + + //========================================================================== + /** Undo Manager. */ + juce::UndoManager undoManager; + /** + * @brief Get a reference to the UndoManager object. + * + * @return juce::UndoManager& + */ + juce::UndoManager& getUndoManager() { return undoManager; }; + + //========================================================================== + /** Audio processor value tree. */ + juce::AudioProcessorValueTreeState apvts; + /** + * @brief Get a reference to the AudioProcessorValueTreeState object. + * + * @return juce::AudioProcessorValueTreeState& + */ + juce::AudioProcessorValueTreeState& getAPVTS() { return apvts; }; + /** + * @brief Create a juce::AudioProcessorValueTreeState::ParameterLayout object. + * + * @return juce::AudioProcessorValueTreeState::ParameterLayout + */ + static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout(); + + juce::AudioParameterBool* bypassState { nullptr }; private: //============================================================================== diff --git a/src/StoneyDSP/Biquads/PluginEditor.cpp b/src/StoneyDSP/Biquads/PluginEditor.cpp index 979f254..ce5c706 100644 --- a/src/StoneyDSP/Biquads/PluginEditor.cpp +++ b/src/StoneyDSP/Biquads/PluginEditor.cpp @@ -3,7 +3,10 @@ //============================================================================== BiquadsAudioProcessorEditor::BiquadsAudioProcessorEditor (BiquadsAudioProcessor& p) - : AudioProcessorEditor (&p), processorRef (p) +: AudioProcessorEditor (&p) +, processorRef(p) +, state(p.getAPVTS()) +, undoManager(p.getUndoManager()) { juce::ignoreUnused (processorRef); // Make sure that before the constructor has finished, you've set the diff --git a/src/StoneyDSP/Biquads/PluginProcessor.cpp b/src/StoneyDSP/Biquads/PluginProcessor.cpp index 54f319a..2509fcc 100644 --- a/src/StoneyDSP/Biquads/PluginProcessor.cpp +++ b/src/StoneyDSP/Biquads/PluginProcessor.cpp @@ -1,16 +1,30 @@ +/** + * @file PluginProcessor.cpp + * @author StoneyDSP (nathanjhood@googlemail.com) + * @brief + * @version 0.1 + * @date 2023-09-07 + * + * @copyright Copyright (c) 2023 + * + */ + #include "StoneyDSP/Biquads/PluginProcessor.hpp" #include "StoneyDSP/Biquads/PluginEditor.hpp" //============================================================================== BiquadsAudioProcessor::BiquadsAudioProcessor() - : AudioProcessor (BusesProperties() - #if ! JucePlugin_IsMidiEffect - #if ! JucePlugin_IsSynth - .withInput ("Input", juce::AudioChannelSet::stereo(), true) - #endif - .withOutput ("Output", juce::AudioChannelSet::stereo(), true) - #endif - ) +: AudioProcessor (BusesProperties() +#if ! JucePlugin_IsMidiEffect + #if ! JucePlugin_IsSynth + .withInput ("Input", juce::AudioChannelSet::stereo(), true) + #endif + .withOutput ("Output", juce::AudioChannelSet::stereo(), true) +#endif +) +, undoManager() +, apvts(*this, &undoManager, "Parameters", createParameterLayout()) +, bypassState (dynamic_cast(apvts.getParameter("bypassID"))) { } @@ -18,6 +32,27 @@ BiquadsAudioProcessor::~BiquadsAudioProcessor() { } +//============================================================================== +juce::AudioProcessorParameter* BiquadsAudioProcessor::getBypassParameter() const +{ + return bypassState; +} + +bool BiquadsAudioProcessor::isBypassed() const noexcept +{ + return bypassState->get() == true; +} + +void BiquadsAudioProcessor::setBypassParameter(juce::AudioParameterBool* newBypass) noexcept +{ + if (bypassState != newBypass) + { + bypassState = newBypass; + releaseResources(); + reset(); + } +} + //============================================================================== const juce::String BiquadsAudioProcessor::getName() const { @@ -164,20 +199,53 @@ juce::AudioProcessorEditor* BiquadsAudioProcessor::createEditor() return new BiquadsAudioProcessorEditor (*this); } +juce::AudioProcessorValueTreeState::ParameterLayout BiquadsAudioProcessor::createParameterLayout() +{ + juce::AudioProcessorValueTreeState::ParameterLayout parameterLayout; + + parameterLayout.add(std::make_unique("bypassID", "Bypass", false)); + + // Parameters::setParameterLayout(parameterLayout); + + return parameterLayout; +} + //============================================================================== void BiquadsAudioProcessor::getStateInformation (juce::MemoryBlock& destData) { // You should use this method to store your parameters in the memory block. // You could do that either as raw data, or use the XML or ValueTree classes // as intermediaries to make it easy to save and load complex data. - juce::ignoreUnused (destData); + auto state = apvts.copyState(); + std::unique_ptr xml(state.createXml()); + copyXmlToBinary(*xml, destData); +} + +void BiquadsAudioProcessor::getCurrentProgramStateInformation(juce::MemoryBlock& destData) +{ + auto state = apvts.copyState(); + std::unique_ptr xml(state.createXml()); + copyXmlToBinary(*xml, destData); } void BiquadsAudioProcessor::setStateInformation (const void* data, int sizeInBytes) { // You should use this method to restore your parameters from this memory block, // whose contents will have been created by the getStateInformation() call. - juce::ignoreUnused (data, sizeInBytes); + std::unique_ptr xmlState(getXmlFromBinary(data, sizeInBytes)); + + if (xmlState.get() != nullptr) + if (xmlState->hasTagName(apvts.state.getType())) + apvts.replaceState(juce::ValueTree::fromXml(*xmlState)); +} + +void BiquadsAudioProcessor::setCurrentProgramStateInformation(const void* data, int sizeInBytes) +{ + std::unique_ptr xmlState(getXmlFromBinary(data, sizeInBytes)); + + if (xmlState.get() != nullptr) + if (xmlState->hasTagName(apvts.state.getType())) + apvts.replaceState(juce::ValueTree::fromXml(*xmlState)); } //==============================================================================