| @@ -76,6 +76,7 @@ class AudioProcessor; | |||
| #include "processors/juce_AudioPlayHead.h" | |||
| #include "processors/juce_AudioProcessorEditor.h" | |||
| #include "processors/juce_AudioProcessorListener.h" | |||
| #include "processors/juce_AudioProcessorParameter.h" | |||
| #include "processors/juce_AudioProcessor.h" | |||
| #include "processors/juce_PluginDescription.h" | |||
| #include "processors/juce_AudioPluginInstance.h" | |||
| @@ -118,20 +118,6 @@ void AudioProcessor::setParameterNotifyingHost (const int parameterIndex, | |||
| sendParamChangeMessageToListeners (parameterIndex, newValue); | |||
| } | |||
| String AudioProcessor::getParameterName (int parameterIndex, int maximumStringLength) | |||
| { | |||
| return getParameterName (parameterIndex).substring (0, maximumStringLength); | |||
| } | |||
| String AudioProcessor::getParameterText (int parameterIndex, int maximumStringLength) | |||
| { | |||
| return getParameterText (parameterIndex).substring (0, maximumStringLength); | |||
| } | |||
| int AudioProcessor::getDefaultNumParameterSteps() noexcept { return 0x7fffffff; } | |||
| int AudioProcessor::getParameterNumSteps (int /*parameterIndex*/) { return getDefaultNumParameterSteps(); } | |||
| float AudioProcessor::getParameterDefaultValue (int /*parameterIndex*/) { return 0.0f; } | |||
| AudioProcessorListener* AudioProcessor::getListenerLocked (const int index) const noexcept | |||
| { | |||
| const ScopedLock sl (listenerLock); | |||
| @@ -202,10 +188,129 @@ void AudioProcessor::updateHostDisplay() | |||
| l->audioProcessorChanged (this); | |||
| } | |||
| String AudioProcessor::getParameterLabel (int) const { return String(); } | |||
| bool AudioProcessor::isParameterOrientationInverted (int) const { return false; } | |||
| bool AudioProcessor::isParameterAutomatable (int) const { return true; } | |||
| bool AudioProcessor::isMetaParameter (int) const { return false; } | |||
| const OwnedArray<AudioProcessorParameter>& AudioProcessor::getParameters() const noexcept | |||
| { | |||
| return managedParameters; | |||
| } | |||
| int AudioProcessor::getNumParameters() | |||
| { | |||
| return managedParameters.size(); | |||
| } | |||
| float AudioProcessor::getParameter (int index) | |||
| { | |||
| if (AudioProcessorParameter* p = getParamChecked (index)) | |||
| return p->getValue(); | |||
| return 0; | |||
| } | |||
| void AudioProcessor::setParameter (int index, float newValue) | |||
| { | |||
| if (AudioProcessorParameter* p = getParamChecked (index)) | |||
| p->setValue (newValue); | |||
| } | |||
| float AudioProcessor::getParameterDefaultValue (int index) | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->getDefaultValue(); | |||
| return 0; | |||
| } | |||
| const String AudioProcessor::getParameterName (int index) | |||
| { | |||
| if (AudioProcessorParameter* p = getParamChecked (index)) | |||
| return p->getName (512); | |||
| return String(); | |||
| } | |||
| String AudioProcessor::getParameterName (int index, int maximumStringLength) | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->getName (maximumStringLength); | |||
| return getParameterName (index).substring (0, maximumStringLength); | |||
| } | |||
| const String AudioProcessor::getParameterText (int index) | |||
| { | |||
| return getParameterText (index, 1024); | |||
| } | |||
| String AudioProcessor::getParameterText (int index, int maximumStringLength) | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->getText (p->getValue(), maximumStringLength); | |||
| return getParameterText (index).substring (0, maximumStringLength); | |||
| } | |||
| int AudioProcessor::getParameterNumSteps (int index) | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->getNumSteps(); | |||
| return AudioProcessor::getDefaultNumParameterSteps(); | |||
| } | |||
| int AudioProcessor::getDefaultNumParameterSteps() noexcept | |||
| { | |||
| return 0x7fffffff; | |||
| } | |||
| String AudioProcessor::getParameterLabel (int index) const | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->getLabel(); | |||
| return String(); | |||
| } | |||
| bool AudioProcessor::isParameterAutomatable (int index) const | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->isAutomatable(); | |||
| return true; | |||
| } | |||
| bool AudioProcessor::isParameterOrientationInverted (int index) const | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->isOrientationInverted(); | |||
| return false; | |||
| } | |||
| bool AudioProcessor::isMetaParameter (int index) const | |||
| { | |||
| if (AudioProcessorParameter* p = managedParameters[index]) | |||
| return p->isMetaParameter(); | |||
| return false; | |||
| } | |||
| AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const noexcept | |||
| { | |||
| AudioProcessorParameter* p = managedParameters[index]; | |||
| // If you hit this, then you're either trying to access parameters that are out-of-range, | |||
| // or you're not using addParameter and the managed parameter list, but have failed | |||
| // to override some essential virtual methods and implement them appropriately. | |||
| jassert (p != nullptr); | |||
| return p; | |||
| } | |||
| void AudioProcessor::addParameter (AudioProcessorParameter* p) | |||
| { | |||
| p->processor = this; | |||
| p->parameterIndex = managedParameters.size(); | |||
| managedParameters.add (p); | |||
| } | |||
| void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) | |||
| { | |||
| @@ -296,6 +401,31 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeIn | |||
| void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} | |||
| void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} | |||
| //============================================================================== | |||
| AudioProcessorParameter::AudioProcessorParameter() noexcept | |||
| : processor (nullptr), parameterIndex (-1) | |||
| {} | |||
| AudioProcessorParameter::~AudioProcessorParameter() {} | |||
| void AudioProcessorParameter::setValueNotifyingHost (float newValue) | |||
| { | |||
| // This method can't be used until the parameter has been attached to a processor! | |||
| jassert (processor != nullptr && parameterIndex >= 0); | |||
| return processor->setParameterNotifyingHost (parameterIndex, newValue); | |||
| } | |||
| bool AudioProcessorParameter::isOrientationInverted() const { return false; } | |||
| bool AudioProcessorParameter::isAutomatable() const { return true; } | |||
| bool AudioProcessorParameter::isMetaParameter() const { return false; } | |||
| int AudioProcessorParameter::getNumSteps() const { return AudioProcessor::getDefaultNumParameterSteps(); } | |||
| String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const | |||
| { | |||
| return String (value, 2); | |||
| } | |||
| //============================================================================== | |||
| bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo& other) const noexcept | |||
| { | |||
| @@ -377,10 +377,10 @@ public: | |||
| /** This must return the correct value immediately after the object has been | |||
| created, and mustn't change the number of parameters later. | |||
| */ | |||
| virtual int getNumParameters() = 0; | |||
| virtual int getNumParameters(); | |||
| /** Returns the name of a particular parameter. */ | |||
| virtual const String getParameterName (int parameterIndex) = 0; | |||
| virtual const String getParameterName (int parameterIndex); | |||
| /** Called by the host to find out the value of one of the filter's parameters. | |||
| @@ -390,10 +390,10 @@ public: | |||
| It's also likely to be called by non-UI threads, so the code in here should | |||
| be thread-aware. | |||
| */ | |||
| virtual float getParameter (int parameterIndex) = 0; | |||
| virtual float getParameter (int parameterIndex); | |||
| /** Returns the value of a parameter as a text string. */ | |||
| virtual const String getParameterText (int parameterIndex) = 0; | |||
| virtual const String getParameterText (int parameterIndex); | |||
| /** Returns the name of a parameter as a text string with a preferred maximum length. | |||
| If you want to provide customised short versions of your parameter names that | |||
| @@ -455,7 +455,7 @@ public: | |||
| The value passed will be between 0 and 1.0. | |||
| */ | |||
| virtual void setParameter (int parameterIndex, float newValue) = 0; | |||
| virtual void setParameter (int parameterIndex, float newValue); | |||
| /** Your filter can call this when it needs to change one of its parameters. | |||
| @@ -507,6 +507,16 @@ public: | |||
| */ | |||
| void updateHostDisplay(); | |||
| //============================================================================== | |||
| /** Adds a parameter to the list. | |||
| The parameter object will be managed and deleted automatically by the list | |||
| when no longer needed. | |||
| */ | |||
| void addParameter (AudioProcessorParameter*); | |||
| /** Returns the current list of parameters. */ | |||
| const OwnedArray<AudioProcessorParameter>& getParameters() const noexcept; | |||
| //============================================================================== | |||
| /** Returns the number of preset programs the filter supports. | |||
| @@ -663,6 +673,9 @@ private: | |||
| CriticalSection callbackLock, listenerLock; | |||
| String inputSpeakerArrangement, outputSpeakerArrangement; | |||
| OwnedArray<AudioProcessorParameter> managedParameters; | |||
| AudioProcessorParameter* getParamChecked (int) const noexcept; | |||
| #if JUCE_DEBUG | |||
| BigInteger changingParams; | |||
| #endif | |||
| @@ -0,0 +1,143 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||
| Permission is granted to use this software under the terms of either: | |||
| a) the GPL v2 (or any later version) | |||
| b) the Affero GPL v3 | |||
| Details of these licenses can be found at: www.gnu.org/licenses | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.juce.com for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED | |||
| #define JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED | |||
| //============================================================================== | |||
| /** An abstract base class for parameter objects that can be added to an | |||
| AudioProcessor. | |||
| @see AudioProcessor::addParameter | |||
| */ | |||
| class JUCE_API AudioProcessorParameter | |||
| { | |||
| public: | |||
| AudioProcessorParameter() noexcept; | |||
| /** Destructor. */ | |||
| virtual ~AudioProcessorParameter(); | |||
| /** Called by the host to find out the value of this parameter. | |||
| Hosts will expect the value returned to be between 0 and 1.0. | |||
| This could be called quite frequently, so try to make your code efficient. | |||
| It's also likely to be called by non-UI threads, so the code in here should | |||
| be thread-aware. | |||
| */ | |||
| virtual float getValue() const = 0; | |||
| /** The host will call this method to change the value of one of the filter's parameters. | |||
| The host may call this at any time, including during the audio processing | |||
| callback, so the filter has to process this very fast and avoid blocking. | |||
| If you want to set the value of a parameter internally, e.g. from your | |||
| editor component, then don't call this directly - instead, use the | |||
| setValueNotifyingHost() method, which will also send a message to | |||
| the host telling it about the change. If the message isn't sent, the host | |||
| won't be able to automate your parameters properly. | |||
| The value passed will be between 0 and 1.0. | |||
| */ | |||
| virtual void setValue (float newValue) = 0; | |||
| /** Your filter can call this when it needs to change one of its parameters. | |||
| This could happen when the editor or some other internal operation changes | |||
| a parameter. This method will call the setParameter() method to change the | |||
| value, and will then send a message to the host telling it about the change. | |||
| Note that to make sure the host correctly handles automation, you should call | |||
| the beginParameterChangeGesture() and endParameterChangeGesture() methods to | |||
| tell the host when the user has started and stopped changing the parameter. | |||
| */ | |||
| void setValueNotifyingHost (float newValue); | |||
| /** This should return the default value for this parameter. */ | |||
| virtual float getDefaultValue() const = 0; | |||
| /** Returns the name to display for this parameter, which should be made | |||
| to fit within the given string length. | |||
| */ | |||
| virtual String getName (int maximumStringLength) const = 0; | |||
| /** Some parameters may be able to return a label string for | |||
| their units. For example "Hz" or "%". | |||
| */ | |||
| virtual String getLabel() const = 0; | |||
| /** Returns the number of discrete interval steps that this parameter's range | |||
| should be quantised into. | |||
| If you want a continuous range of values, don't override this method, and allow | |||
| the default implementation to return AudioProcessor::getDefaultNumParameterSteps(). | |||
| If your parameter is boolean, then you may want to make this return 2. | |||
| The value that is returned may or may not be used, depending on the host. | |||
| */ | |||
| virtual int getNumSteps() const; | |||
| /** Returns a textual version of the supplied parameter value. | |||
| The default implementation just returns the floating point value | |||
| as a string, but this could do anything you need for a custom type | |||
| of value. | |||
| */ | |||
| virtual String getText (float value, int /*maximumStringLength*/) const; | |||
| /** Should parse a string and return the appropriate value for it. */ | |||
| virtual float getValueForText (const String& text) const = 0; | |||
| /** This can be overridden to tell the host that this parameter operates in the | |||
| reverse direction. | |||
| (Not all plugin formats or hosts will actually use this information). | |||
| */ | |||
| virtual bool isOrientationInverted() const; | |||
| /** Returns true if the host can automate this parameter. | |||
| By default, this returns true. | |||
| */ | |||
| virtual bool isAutomatable() const; | |||
| /** Should return true if this parameter is a "meta" parameter. | |||
| A meta-parameter is a parameter that changes other params. It is used | |||
| by some hosts (e.g. AudioUnit hosts). | |||
| By default this returns false. | |||
| */ | |||
| virtual bool isMetaParameter() const; | |||
| /** Returns the index of this parameter in its parent processor's parameter list. */ | |||
| int getParameterIndex() const noexcept { return parameterIndex; } | |||
| private: | |||
| friend class AudioProcessor; | |||
| AudioProcessor* processor; | |||
| int parameterIndex; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameter) | |||
| }; | |||
| #endif // JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED | |||