diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h index 51be1c8d79..9224d2695d 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h @@ -35,11 +35,23 @@ namespace juce class JUCE_API AudioParameterBool : public AudioProcessorParameterWithID { public: - /** Creates a AudioParameterBool with an ID and name. - On creation, its value is set to the default value. + /** Creates a AudioParameterBool with the specified parameters. + + @param parameterID The parameter ID to use + @param name The parameter name to use + @param defaultValue The default value + @param label An optional label for the parameter's value + @param stringFromBool An optional lambda function that converts a bool + value to a string with a maximum length. This may + be used by hosts to display the parameter's value. + @param boolFromString An optional lambda function that parses a string and + converts it into a bool value. Some hosts use this + to allow users to type in parameter values. */ AudioParameterBool (const String& parameterID, const String& name, bool defaultValue, - const String& label = String()); + const String& label = String(), + std::function stringFromBool = nullptr, + std::function boolFromString = nullptr); /** Destructor. */ ~AudioParameterBool(); @@ -71,7 +83,8 @@ private: float value; const float defaultValue; - StringArray onStrings, offStrings; + std::function stringFromBoolFunction; + std::function boolFromStringFunction; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterBool) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h index 94374e5890..24e25cc313 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h @@ -36,13 +36,26 @@ namespace juce class JUCE_API AudioParameterChoice : public AudioProcessorParameterWithID { public: - /** Creates a AudioParameterChoice with an ID, name, and list of items. - On creation, its value is set to the default index. + /** Creates a AudioParameterChoice with the specified parameters. + + @param parameterID The parameter ID to use + @param name The parameter name to use + @param choices The set of choices to use + @param defaultItemIndex The index of the default choice + @param label An optional label for the parameter's value + @param stringFromIndex An optional lambda function that converts a choice + index to a string with a maximum length. This may + be used by hosts to display the parameter's value. + @param indexFromString An optional lambda function that parses a string and + converts it into a choice index. Some hosts use this + to allow users to type in parameter values. */ AudioParameterChoice (const String& parameterID, const String& name, const StringArray& choices, int defaultItemIndex, - const String& label = String()); + const String& label = String(), + std::function stringFromIndex = nullptr, + std::function indexFromString = nullptr); /** Destructor. */ ~AudioParameterChoice(); @@ -71,10 +84,6 @@ protected: private: //============================================================================== - float value; - const int maxIndex; - const float defaultValue; - float getValue() const override; void setValue (float newValue) override; float getDefaultValue() const override; @@ -87,6 +96,12 @@ private: float convertTo0to1 (int) const noexcept; int convertFrom0to1 (float) const noexcept; + float value; + const int maxIndex; + const float defaultValue; + std::function stringFromIndexFunction; + std::function indexFromStringFunction; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterChoice) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h index 60a7f93859..b09cb20571 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h @@ -36,14 +36,28 @@ namespace juce class JUCE_API AudioParameterFloat : public AudioProcessorParameterWithID { public: - /** Creates a AudioParameterFloat with an ID, name, and range. - On creation, its value is set to the default value. + /** Creates a AudioParameterFloat with the specified parameters. + + @param parameterID The parameter ID to use + @param name The parameter name to use + @param normalisableRange The NormalisableRange to use + @param defaultValue The non-normalised default value + @param label An optional label for the parameter's value + @param category An optional parameter category + @param stringFromValue An optional lambda function that converts a non-normalised + value to a string with a maximum length. This may + be used by hosts to display the parameter's value. + @param valueFromString An optional lambda function that parses a string and + converts it into a non-normalised value. Some hosts use + this to allow users to type in parameter values. */ AudioParameterFloat (const String& parameterID, const String& name, NormalisableRange normalisableRange, float defaultValue, const String& label = String(), - Category category = AudioProcessorParameter::genericParameter); + Category category = AudioProcessorParameter::genericParameter, + std::function stringFromValue = nullptr, + std::function valueFromString = nullptr); /** Creates a AudioParameterFloat with an ID, name, and range. On creation, its value is set to the default value. @@ -77,9 +91,6 @@ protected: private: //============================================================================== - float value; - const float defaultValue; - float getValue() const override; void setValue (float newValue) override; float getDefaultValue() const override; @@ -87,6 +98,11 @@ private: String getText (float, int) const override; float getValueForText (const String&) const override; + float value; + const float defaultValue; + std::function stringFromValueFunction; + std::function valueFromStringFunction; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterFloat) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h index 4788f82c2c..61f8e77f3d 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h @@ -36,14 +36,27 @@ namespace juce class JUCE_API AudioParameterInt : public AudioProcessorParameterWithID { public: - /** Creates an AudioParameterInt with an ID, name, and range. - Note that the min and max range values are inclusive. - On creation, its value is set to the default value. + /** Creates a AudioParameterInt with the specified parameters. + + @param parameterID The parameter ID to use + @param name The parameter name to use + @param minValue The minimum parameter value + @param maxValue The maximum parameter value + @param defaultValue The default value + @param label An optional label for the parameter's value + @param stringFromInt An optional lambda function that converts a int + value to a string with a maximum length. This may + be used by hosts to display the parameter's value. + @param intFromString An optional lambda function that parses a string + and converts it into an int. Some hosts use this + to allow users to type in parameter values. */ AudioParameterInt (const String& parameterID, const String& name, int minValue, int maxValue, int defaultValue, - const String& label = String()); + const String& label = String(), + std::function stringFromInt = nullptr, + std::function intFromString = nullptr); /** Destructor. */ ~AudioParameterInt(); @@ -69,10 +82,6 @@ protected: private: //============================================================================== - const int minValue, maxValue, rangeOfValues; - float value; - const float defaultValue; - float getValue() const override; void setValue (float newValue) override; float getDefaultValue() const override; @@ -84,6 +93,12 @@ private: float convertTo0to1 (int) const noexcept; int convertFrom0to1 (float) const noexcept; + const int minValue, maxValue, rangeOfValues; + float value; + const float defaultValue; + std::function stringFromIntFunction; + std::function intFromStringFunction; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterInt) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp index acda82fd72..f162a7d8a3 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp @@ -45,14 +45,27 @@ AudioProcessorParameter::Category AudioProcessorParameterWithID::getCategory() c //============================================================================== AudioParameterFloat::AudioParameterFloat (const String& idToUse, const String& nameToUse, NormalisableRange r, float def, - const String& labelToUse, Category categoryToUse) + const String& labelToUse, Category categoryToUse, + std::function stringFromValue, + std::function valueFromString) : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse, categoryToUse), - range (r), value (def), defaultValue (def) + range (r), value (def), defaultValue (def), + stringFromValueFunction (stringFromValue), + valueFromStringFunction (valueFromString) { + if (stringFromValueFunction == nullptr) + stringFromValueFunction = [] (float v, int length) + { + String asText (v, 2); + return length > 0 ? asText.substring (0, length) : asText; + }; + + if (valueFromStringFunction == nullptr) + valueFromStringFunction = [] (const String& text) { return text.getFloatValue(); }; } AudioParameterFloat::AudioParameterFloat (String pid, String nm, float minValue, float maxValue, float def) - : AudioProcessorParameterWithID (pid, nm), range (minValue, maxValue), value (def), defaultValue (def) + : AudioParameterFloat (pid, nm, { minValue, maxValue }, def) { } @@ -62,15 +75,10 @@ float AudioParameterFloat::getValue() const { retur void AudioParameterFloat::setValue (float newValue) { value = range.convertFrom0to1 (newValue); valueChanged (get()); } float AudioParameterFloat::getDefaultValue() const { return range.convertTo0to1 (defaultValue); } int AudioParameterFloat::getNumSteps() const { return AudioProcessorParameterWithID::getNumSteps(); } -float AudioParameterFloat::getValueForText (const String& text) const { return range.convertTo0to1 (text.getFloatValue()); } +String AudioParameterFloat::getText (float v, int length) const { return stringFromValueFunction (range.convertFrom0to1 (v), length); } +float AudioParameterFloat::getValueForText (const String& text) const { return range.convertTo0to1 (valueFromStringFunction (text)); } void AudioParameterFloat::valueChanged (float) {} -String AudioParameterFloat::getText (float v, int length) const -{ - String asText (range.convertFrom0to1 (v), 2); - return length > 0 ? asText.substring (0, length) : asText; -} - AudioParameterFloat& AudioParameterFloat::operator= (float newValue) { if (value != newValue) @@ -82,13 +90,23 @@ AudioParameterFloat& AudioParameterFloat::operator= (float newValue) //============================================================================== AudioParameterInt::AudioParameterInt (const String& idToUse, const String& nameToUse, int mn, int mx, int def, - const String& labelToUse) + const String& labelToUse, + std::function stringFromInt, + std::function intFromString) : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse), minValue (mn), maxValue (mx), rangeOfValues (maxValue - minValue), value ((float) def), - defaultValue (convertTo0to1 (def)) + defaultValue (convertTo0to1 (def)), + stringFromIntFunction (stringFromInt), + intFromStringFunction (intFromString) { jassert (minValue < maxValue); // must have a non-zero range of values! + + if (stringFromIntFunction == nullptr) + stringFromIntFunction = [] (int v, int) { return String (v); }; + + if (intFromStringFunction == nullptr) + intFromStringFunction = [] (const String& text) { return text.getIntValue(); }; } AudioParameterInt::~AudioParameterInt() {} @@ -101,8 +119,8 @@ float AudioParameterInt::getValue() const { retur void AudioParameterInt::setValue (float newValue) { value = (float) convertFrom0to1 (newValue); valueChanged (get()); } float AudioParameterInt::getDefaultValue() const { return defaultValue; } int AudioParameterInt::getNumSteps() const { return rangeOfValues + 1; } -float AudioParameterInt::getValueForText (const String& text) const { return convertTo0to1 (text.getIntValue()); } -String AudioParameterInt::getText (float v, int /*length*/) const { return String (convertFrom0to1 (v)); } +float AudioParameterInt::getValueForText (const String& text) const { return convertTo0to1 (intFromStringFunction (text)); } +String AudioParameterInt::getText (float v, int length) const { return stringFromIntFunction (convertFrom0to1 (v), length); } void AudioParameterInt::valueChanged (int) {} AudioParameterInt& AudioParameterInt::operator= (int newValue) @@ -116,18 +134,45 @@ AudioParameterInt& AudioParameterInt::operator= (int newValue) //============================================================================== AudioParameterBool::AudioParameterBool (const String& idToUse, const String& nameToUse, - bool def, const String& labelToUse) + bool def, const String& labelToUse, + std::function stringFromBool, + std::function boolFromString) : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse), value (def ? 1.0f : 0.0f), - defaultValue (value) + defaultValue (value), + stringFromBoolFunction (stringFromBool), + boolFromStringFunction (boolFromString) { - onStrings.add (TRANS("on")); - onStrings.add (TRANS("yes")); - onStrings.add (TRANS("true")); + if (stringFromBoolFunction == nullptr) + stringFromBoolFunction = [] (bool v, int) { return v ? TRANS("On") : TRANS("Off"); }; - offStrings.add (TRANS("off")); - offStrings.add (TRANS("no")); - offStrings.add (TRANS("false")); + if (boolFromStringFunction == nullptr) + { + StringArray onStrings; + onStrings.add (TRANS("on")); + onStrings.add (TRANS("yes")); + onStrings.add (TRANS("true")); + + StringArray offStrings; + offStrings.add (TRANS("off")); + offStrings.add (TRANS("no")); + offStrings.add (TRANS("false")); + + boolFromStringFunction = [onStrings, offStrings] (const String& text) + { + String lowercaseText (text.toLowerCase()); + + for (auto& testText : onStrings) + if (lowercaseText == testText) + return true; + + for (auto& testText : offStrings) + if (lowercaseText == testText) + return false; + + return text.getIntValue() != 0; + }; + } } AudioParameterBool::~AudioParameterBool() {} @@ -142,22 +187,12 @@ void AudioParameterBool::valueChanged (bool) {} float AudioParameterBool::getValueForText (const String& text) const { - String lowercaseText (text.toLowerCase()); - - for (auto& testText : onStrings) - if (lowercaseText == testText) - return 1.0f; - - for (auto& testText : offStrings) - if (lowercaseText == testText) - return 0.0f; - - return text.getIntValue() != 0 ? 1.0f : 0.0f; + return boolFromStringFunction (text) ? 1.0f : 0.0f; } -String AudioParameterBool::getText (float v, int /*length*/) const +String AudioParameterBool::getText (float v, int maximumLength) const { - return v < 0.5f ? TRANS("Off") : TRANS("On"); + return stringFromBoolFunction (v >= 0.5f, maximumLength); } AudioParameterBool& AudioParameterBool::operator= (bool newValue) @@ -171,13 +206,23 @@ AudioParameterBool& AudioParameterBool::operator= (bool newValue) //============================================================================== AudioParameterChoice::AudioParameterChoice (const String& idToUse, const String& nameToUse, - const StringArray& c, int def, const String& labelToUse) + const StringArray& c, int def, const String& labelToUse, + std::function stringFromIndex, + std::function indexFromString) : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse), choices (c), value ((float) def), maxIndex (choices.size() - 1), - defaultValue (convertTo0to1 (def)) + defaultValue (convertTo0to1 (def)), + stringFromIndexFunction (stringFromIndex), + indexFromStringFunction (indexFromString) { jassert (choices.size() > 0); // you must supply an actual set of items to choose from! + + if (stringFromIndexFunction == nullptr) + stringFromIndexFunction = [this] (int index, int) { return choices [index]; }; + + if (indexFromStringFunction == nullptr) + indexFromStringFunction = [this] (const String& text) { return choices.indexOf (text); }; } AudioParameterChoice::~AudioParameterChoice() {} @@ -191,8 +236,8 @@ void AudioParameterChoice::setValue (float newValue) { value float AudioParameterChoice::getDefaultValue() const { return defaultValue; } int AudioParameterChoice::getNumSteps() const { return choices.size(); } bool AudioParameterChoice::isDiscrete() const { return true; } -float AudioParameterChoice::getValueForText (const String& text) const { return convertTo0to1 (choices.indexOf (text)); } -String AudioParameterChoice::getText (float v, int /*length*/) const { return choices [convertFrom0to1 (v)]; } +float AudioParameterChoice::getValueForText (const String& text) const { return convertTo0to1 (indexFromStringFunction (text)); } +String AudioParameterChoice::getText (float v, int length) const { return stringFromIndexFunction (convertFrom0to1 (v), length); } void AudioParameterChoice::valueChanged (int) {} AudioParameterChoice& AudioParameterChoice::operator= (int newValue)