280 lines
13 KiB
C++
280 lines
13 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2017 - ROLI Ltd.
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
|
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
|
27th April 2017).
|
|
|
|
End User License Agreement: www.juce.com/juce-5-licence
|
|
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
namespace juce
|
|
{
|
|
|
|
/**
|
|
This class contains a ValueTree which is used to manage an AudioProcessor's entire state.
|
|
|
|
It has its own internal class of parameter object which are linked to values
|
|
within its ValueTree, and which are each identified by a string ID.
|
|
|
|
You can get access to the underlying ValueTree object via the state member variable,
|
|
so you can add extra properties to it as necessary.
|
|
|
|
It also provides some utility child classes for connecting parameters directly to
|
|
GUI controls like sliders.
|
|
|
|
To use:
|
|
1) Create an AudioProcessorValueTreeState, and give it some parameters using createAndAddParameter().
|
|
2) Initialise the state member variable with a type name.
|
|
|
|
@tags{Audio}
|
|
*/
|
|
class JUCE_API AudioProcessorValueTreeState : private Timer,
|
|
private ValueTree::Listener
|
|
{
|
|
public:
|
|
/** Creates a state object for a given processor.
|
|
|
|
The UndoManager is optional and can be a nullptr.
|
|
After creating your state object, you should add parameters with the
|
|
createAndAddParameter() method. Note that each AudioProcessorValueTreeState
|
|
should be attached to only one processor, and must have the same lifetime as the
|
|
processor, as they will have dependencies on each other.
|
|
*/
|
|
AudioProcessorValueTreeState (AudioProcessor& processorToConnectTo,
|
|
UndoManager* undoManagerToUse);
|
|
|
|
/** Destructor. */
|
|
~AudioProcessorValueTreeState();
|
|
|
|
/** Creates and returns a new parameter object for controlling a parameter
|
|
with the given ID.
|
|
|
|
Calling this will create and add a special type of AudioProcessorParameter to the
|
|
AudioProcessor to which this state is attached.
|
|
|
|
@param parameterID A unique string ID for the new parameter
|
|
@param parameterName The name that the parameter will return from AudioProcessorParameter::getName()
|
|
@param labelText The label that the parameter will return from AudioProcessorParameter::getLabel()
|
|
@param valueRange A mapping that will be used to determine the value range which this parameter uses
|
|
@param defaultValue A default value for the parameter (in non-normalised units)
|
|
@param valueToTextFunction A function that will convert a non-normalised value to a string for the
|
|
AudioProcessorParameter::getText() method. This can be nullptr to use the
|
|
default implementation
|
|
@param textToValueFunction The inverse of valueToTextFunction
|
|
@param isMetaParameter Set this value to true if this should be a meta parameter
|
|
@param isAutomatableParameter Set this value to false if this parameter should not be automatable
|
|
@param isDiscrete Set this value to true to make this parameter take discrete values in a host.
|
|
@see AudioProcessorParameter::isDiscrete
|
|
@param category Which category the parameter should use.
|
|
@see AudioProcessorParameter::Category
|
|
@param isBoolean Set this value to true to make this parameter appear as a boolean toggle in
|
|
a hosts view of your plug-ins parameters
|
|
@see AudioProcessorParameter::isBoolean
|
|
|
|
@returns the parameter object that was created
|
|
*/
|
|
AudioProcessorParameterWithID* createAndAddParameter (const String& parameterID,
|
|
const String& parameterName,
|
|
const String& labelText,
|
|
NormalisableRange<float> valueRange,
|
|
float defaultValue,
|
|
std::function<String (float)> valueToTextFunction,
|
|
std::function<float (const String&)> textToValueFunction,
|
|
bool isMetaParameter = false,
|
|
bool isAutomatableParameter = true,
|
|
bool isDiscrete = false,
|
|
AudioProcessorParameter::Category category
|
|
= AudioProcessorParameter::genericParameter,
|
|
bool isBoolean = false);
|
|
|
|
/** Returns a parameter by its ID string. */
|
|
AudioProcessorParameterWithID* getParameter (StringRef parameterID) const noexcept;
|
|
|
|
/** Returns a pointer to a floating point representation of a particular
|
|
parameter which a realtime process can read to find out its current value.
|
|
*/
|
|
float* getRawParameterValue (StringRef parameterID) const noexcept;
|
|
|
|
/** A listener class that can be attached to an AudioProcessorValueTreeState.
|
|
Use AudioProcessorValueTreeState::addParameterListener() to register a callback.
|
|
*/
|
|
struct JUCE_API Listener
|
|
{
|
|
Listener();
|
|
virtual ~Listener();
|
|
|
|
/** This callback method is called by the AudioProcessorValueTreeState when a parameter changes. */
|
|
virtual void parameterChanged (const String& parameterID, float newValue) = 0;
|
|
};
|
|
|
|
/** Attaches a callback to one of the parameters, which will be called when the parameter changes. */
|
|
void addParameterListener (StringRef parameterID, Listener* listener);
|
|
|
|
/** Removes a callback that was previously added with addParameterCallback(). */
|
|
void removeParameterListener (StringRef parameterID, Listener* listener);
|
|
|
|
/** Returns a Value object that can be used to control a particular parameter. */
|
|
Value getParameterAsValue (StringRef parameterID) const;
|
|
|
|
/** Returns the range that was set when the given parameter was created. */
|
|
NormalisableRange<float> getParameterRange (StringRef parameterID) const noexcept;
|
|
|
|
/** Returns a copy of the state value tree.
|
|
|
|
The AudioProcessorValueTreeState's ValueTree is updated internally on the
|
|
message thread, but there may be cases when you may want to access the state
|
|
from a different thread (getStateInformation is a good example). This method
|
|
flushes all pending audio parameter value updates and returns a copy of the
|
|
state in a thread safe way.
|
|
|
|
Note: This method uses locks to synchronise thread access, so whilst it is
|
|
thread-safe, it is not realtime-safe. Do not call this method from within
|
|
your audio processing code!
|
|
*/
|
|
ValueTree copyState();
|
|
|
|
/** Replaces the state value tree.
|
|
|
|
The AudioProcessorValueTreeState's ValueTree is updated internally on the
|
|
message thread, but there may be cases when you may want to modify the state
|
|
from a different thread (setStateInformation is a good example). This method
|
|
allows you to replace the state in a thread safe way.
|
|
|
|
Note: This method uses locks to synchronise thread access, so whilst it is
|
|
thread-safe, it is not realtime-safe. Do not call this method from within
|
|
your audio processing code!
|
|
*/
|
|
void replaceState (const ValueTree& newState);
|
|
|
|
/** A reference to the processor with which this state is associated. */
|
|
AudioProcessor& processor;
|
|
|
|
/** The state of the whole processor.
|
|
|
|
This must be initialised after all calls to createAndAddParameter().
|
|
You can replace this with your own ValueTree object, and can add properties and
|
|
children to the tree. This class will automatically add children for each of the
|
|
parameter objects that are created by createAndAddParameter().
|
|
*/
|
|
ValueTree state;
|
|
|
|
/** Provides access to the undo manager that this object is using. */
|
|
UndoManager* const undoManager;
|
|
|
|
//==============================================================================
|
|
/** An object of this class maintains a connection between a Slider and a parameter
|
|
in an AudioProcessorValueTreeState.
|
|
|
|
During the lifetime of this SliderAttachment object, it keeps the two things in
|
|
sync, making it easy to connect a slider to a parameter. When this object is
|
|
deleted, the connection is broken. Make sure that your AudioProcessorValueTreeState
|
|
and Slider aren't deleted before this object!
|
|
*/
|
|
class JUCE_API SliderAttachment
|
|
{
|
|
public:
|
|
SliderAttachment (AudioProcessorValueTreeState& stateToControl,
|
|
const String& parameterID,
|
|
Slider& sliderToControl);
|
|
~SliderAttachment();
|
|
|
|
private:
|
|
struct Pimpl;
|
|
friend struct ContainerDeletePolicy<Pimpl>;
|
|
std::unique_ptr<Pimpl> pimpl;
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderAttachment)
|
|
};
|
|
|
|
//==============================================================================
|
|
/** An object of this class maintains a connection between a ComboBox and a parameter
|
|
in an AudioProcessorValueTreeState.
|
|
|
|
During the lifetime of this ComboBoxAttachment object, it keeps the two things in
|
|
sync, making it easy to connect a combo box to a parameter. When this object is
|
|
deleted, the connection is broken. Make sure that your AudioProcessorValueTreeState
|
|
and ComboBox aren't deleted before this object!
|
|
*/
|
|
class JUCE_API ComboBoxAttachment
|
|
{
|
|
public:
|
|
ComboBoxAttachment (AudioProcessorValueTreeState& stateToControl,
|
|
const String& parameterID,
|
|
ComboBox& comboBoxToControl);
|
|
~ComboBoxAttachment();
|
|
|
|
private:
|
|
struct Pimpl;
|
|
friend struct ContainerDeletePolicy<Pimpl>;
|
|
std::unique_ptr<Pimpl> pimpl;
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBoxAttachment)
|
|
};
|
|
|
|
//==============================================================================
|
|
/** An object of this class maintains a connection between a Button and a parameter
|
|
in an AudioProcessorValueTreeState.
|
|
|
|
During the lifetime of this ButtonAttachment object, it keeps the two things in
|
|
sync, making it easy to connect a button to a parameter. When this object is
|
|
deleted, the connection is broken. Make sure that your AudioProcessorValueTreeState
|
|
and Button aren't deleted before this object!
|
|
*/
|
|
class JUCE_API ButtonAttachment
|
|
{
|
|
public:
|
|
ButtonAttachment (AudioProcessorValueTreeState& stateToControl,
|
|
const String& parameterID,
|
|
Button& buttonToControl);
|
|
~ButtonAttachment();
|
|
|
|
private:
|
|
struct Pimpl;
|
|
friend struct ContainerDeletePolicy<Pimpl>;
|
|
std::unique_ptr<Pimpl> pimpl;
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment)
|
|
};
|
|
|
|
private:
|
|
//==============================================================================
|
|
struct Parameter;
|
|
friend struct Parameter;
|
|
|
|
ValueTree getOrCreateChildValueTree (const String&);
|
|
bool flushParameterValuesToValueTree();
|
|
void timerCallback() override;
|
|
|
|
void valueTreePropertyChanged (ValueTree&, const Identifier&) override;
|
|
void valueTreeChildAdded (ValueTree&, ValueTree&) override;
|
|
void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override;
|
|
void valueTreeChildOrderChanged (ValueTree&, int, int) override;
|
|
void valueTreeParentChanged (ValueTree&) override;
|
|
void valueTreeRedirected (ValueTree&) override;
|
|
void updateParameterConnectionsToChildTrees();
|
|
|
|
Identifier valueType { "PARAM" },
|
|
valuePropertyID { "value" },
|
|
idPropertyID { "id" };
|
|
|
|
CriticalSection valueTreeChanging;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorValueTreeState)
|
|
};
|
|
|
|
} // namespace juce
|