From 78973314038e24baa45ff27892bf44ccf3778ace Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 11 Jan 2017 18:02:40 +0000 Subject: [PATCH] Added support for level meter parameter categories --- examples/PlugInSamples/GenericEditor.h | 4 + .../AAX/juce_AAX_Wrapper.cpp | 137 +++++++++++++++--- .../AU/juce_AU_Wrapper.mm | 10 +- .../AU/juce_AUv3_Wrapper.mm | 9 ++ .../VST/juce_VST_Wrapper.cpp | 6 +- .../VST3/juce_VST3_Wrapper.cpp | 7 +- .../processors/juce_AudioProcessor.cpp | 15 +- .../processors/juce_AudioProcessor.h | 8 + .../processors/juce_AudioProcessorParameter.h | 22 +++ .../juce_GenericAudioProcessorEditor.cpp | 3 + .../utilities/juce_AudioParameterFloat.h | 3 +- .../juce_AudioProcessorParameterWithID.h | 7 +- .../juce_AudioProcessorParameters.cpp | 14 +- 13 files changed, 208 insertions(+), 37 deletions(-) diff --git a/examples/PlugInSamples/GenericEditor.h b/examples/PlugInSamples/GenericEditor.h index 120b904156..8bf7aedb79 100644 --- a/examples/PlugInSamples/GenericEditor.h +++ b/examples/PlugInSamples/GenericEditor.h @@ -43,6 +43,10 @@ public: { if (const AudioParameterFloat* param = dynamic_cast(params[i])) { + const bool isLevelMeter = (((param->category & 0xffff0000) >> 16) == 2); + if (isLevelMeter) + continue; + Slider* aSlider; paramSliders.add (aSlider = new Slider (param->name)); diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index 3e7263d7f3..9b0ad04f7d 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -299,29 +299,33 @@ namespace AAXClasses PluginInstanceInfo* pluginInstance; int32_t* isPrepared; int32_t* sideChainBuffers; + + float* const* meterTapBuffers; }; struct JUCEAlgorithmIDs { enum { - inputChannels = AAX_FIELD_INDEX (JUCEAlgorithmContext, inputChannels), - outputChannels = AAX_FIELD_INDEX (JUCEAlgorithmContext, outputChannels), - bufferSize = AAX_FIELD_INDEX (JUCEAlgorithmContext, bufferSize), - bypass = AAX_FIELD_INDEX (JUCEAlgorithmContext, bypass), + inputChannels = AAX_FIELD_INDEX (JUCEAlgorithmContext, inputChannels), + outputChannels = AAX_FIELD_INDEX (JUCEAlgorithmContext, outputChannels), + bufferSize = AAX_FIELD_INDEX (JUCEAlgorithmContext, bufferSize), + bypass = AAX_FIELD_INDEX (JUCEAlgorithmContext, bypass), #if JucePlugin_WantsMidiInput || JucePlugin_IsMidiEffect - midiNodeIn = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeIn), + midiNodeIn = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeIn), #endif #if JucePlugin_ProducesMidiOutput || JucePlugin_IsSynth || JucePlugin_IsMidiEffect - midiNodeOut = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeOut), + midiNodeOut = AAX_FIELD_INDEX (JUCEAlgorithmContext, midiNodeOut), #endif - pluginInstance = AAX_FIELD_INDEX (JUCEAlgorithmContext, pluginInstance), - preparedFlag = AAX_FIELD_INDEX (JUCEAlgorithmContext, isPrepared), + pluginInstance = AAX_FIELD_INDEX (JUCEAlgorithmContext, pluginInstance), + preparedFlag = AAX_FIELD_INDEX (JUCEAlgorithmContext, isPrepared), - sideChainBuffers = AAX_FIELD_INDEX (JUCEAlgorithmContext, sideChainBuffers) + sideChainBuffers = AAX_FIELD_INDEX (JUCEAlgorithmContext, sideChainBuffers), + + meterTapBuffers = AAX_FIELD_INDEX (JUCEAlgorithmContext, meterTapBuffers) }; }; @@ -655,7 +659,8 @@ namespace AAXClasses const int numParameters = pluginInstance->getNumParameters(); for (int i = 0; i < numParameters; ++i) - SetParameterNormalizedValue (getAAXParamIDFromJuceIndex (i), (double) pluginInstance->getParameter(i)); + if (AAX_CParamID paramID = getAAXParamIDFromJuceIndex(i)) + SetParameterNormalizedValue (paramID, (double) pluginInstance->getParameter(i)); return AAX_SUCCESS; } @@ -893,7 +898,8 @@ namespace AAXClasses void audioProcessorParameterChanged (AudioProcessor* /*processor*/, int parameterIndex, float newValue) override { - SetParameterNormalizedValue (getAAXParamIDFromJuceIndex (parameterIndex), (double) newValue); + if (AAX_CParamID paramID = getAAXParamIDFromJuceIndex (parameterIndex)) + SetParameterNormalizedValue (paramID, (double) newValue); } void audioProcessorChanged (AudioProcessor* processor) override @@ -904,12 +910,14 @@ namespace AAXClasses void audioProcessorParameterChangeGestureBegin (AudioProcessor* /*processor*/, int parameterIndex) override { - TouchParameter (getAAXParamIDFromJuceIndex (parameterIndex)); + if (AAX_CParamID paramID = getAAXParamIDFromJuceIndex (parameterIndex)) + TouchParameter (paramID); } void audioProcessorParameterChangeGestureEnd (AudioProcessor* /*processor*/, int parameterIndex) override { - ReleaseParameter (getAAXParamIDFromJuceIndex (parameterIndex)); + if (AAX_CParamID paramID = getAAXParamIDFromJuceIndex (parameterIndex)) + ReleaseParameter (paramID); } AAX_Result NotificationReceived (AAX_CTypeID type, const void* data, uint32_t size) override @@ -932,15 +940,20 @@ namespace AAXClasses void process (const float* const* inputs, float* const* outputs, const int sideChainBufferIdx, const int bufferSize, const bool bypass, - AAX_IMIDINode* midiNodeIn, AAX_IMIDINode* midiNodesOut) + AAX_IMIDINode* midiNodeIn, AAX_IMIDINode* midiNodesOut, + float* const meterBuffers) { - const int numIns = pluginInstance->getTotalNumInputChannels(); - const int numOuts = pluginInstance->getTotalNumOutputChannels(); + const int numIns = pluginInstance->getTotalNumInputChannels(); + const int numOuts = pluginInstance->getTotalNumOutputChannels(); + const int numMeters = aaxMeters.size(); if (pluginInstance->isSuspended()) { for (int i = 0; i < numOuts; ++i) FloatVectorOperations::clear (outputs[i], bufferSize); + + if (meterBuffers != nullptr) + FloatVectorOperations::clear (meterBuffers, numMeters); } else { @@ -981,6 +994,12 @@ namespace AAXClasses process (channels, numIns, bufferSize, bypass, midiNodeIn, midiNodesOut); } + + if (meterBuffers != nullptr) + { + for (int i = 0; i < numMeters; ++i) + meterBuffers[i] = pluginInstance->getParameter (aaxMeters[i]); + } } } @@ -1253,6 +1272,8 @@ namespace AAXClasses for (int parameterIndex = 0; parameterIndex < numParameters; ++parameterIndex) { + const AudioProcessorParameter::Category category = audioProcessor.getParameterCategory (parameterIndex); + aaxParamIDs.add (usingManagedParameters ? audioProcessor.getParameterID (parameterIndex) : String (parameterIndex)); @@ -1261,6 +1282,13 @@ namespace AAXClasses paramMap.set (AAXClasses::getAAXParamHash (paramID), parameterIndex); + // is this a meter? + if (((category & 0xffff0000) >> 16) == 2) + { + aaxMeters.add (parameterIndex); + continue; + } + AAX_IParameter* parameter = new AAX_CParameter (paramID, paramName, @@ -1441,9 +1469,12 @@ namespace AAXClasses if (sideChainBufferIdx <= 0) sideChainBufferIdx = -1; + float* const meterTapBuffers = (i.meterTapBuffers != nullptr ? *i.meterTapBuffers : nullptr); + i.pluginInstance->parameters.process (i.inputChannels, i.outputChannels, sideChainBufferIdx, *(i.bufferSize), *(i.bypass) != 0, - getMidiNodeIn(i), getMidiNodeOut(i)); + getMidiNodeIn(i), getMidiNodeOut(i), + meterTapBuffers); } } @@ -1511,6 +1542,8 @@ namespace AAXClasses Array aaxParamIDs; HashMap paramMap; + Array aaxMeters; + struct ChunkMemoryBlock : public ReferenceCountedObject { juce::MemoryBlock data; @@ -1547,7 +1580,7 @@ namespace AAXClasses if (const JuceAAX_Processor* params = dynamic_cast (GetEffectParameters())) return params->getParamIndexFromID (paramID); - return -1; + return -1; } AAX_CParamID JuceAAX_GUI::getAAXParamIDFromJuceIndex (int index) const noexcept @@ -1555,7 +1588,7 @@ namespace AAXClasses if (const JuceAAX_Processor* params = dynamic_cast (GetEffectParameters())) return params->getAAXParamIDFromJuceIndex (index); - return nullptr; + return nullptr; } //============================================================================== @@ -1578,7 +1611,57 @@ namespace AAXClasses }; //============================================================================== - static void createDescriptor (AAX_IComponentDescriptor& desc, int configIndex, const AudioProcessor::BusesLayout& fullLayout, AudioProcessor& processor) + static int addAAXMeters (AudioProcessor& p, AAX_IEffectDescriptor& descriptor) + { + const int n = p.getNumParameters(); + + int meterIdx = 0; + for (int i = 0; i < n; ++i) + { + const AudioProcessorParameter::Category category = p.getParameterCategory (i); + + // is this a meter? + if (((category & 0xffff0000) >> 16) == 2) + { + if (AAX_IPropertyMap* meterProperties = descriptor.NewPropertyMap()) + { + AAX_EMeterType aaxMeterType; + + switch (category) + { + case AudioProcessorParameter::inputMeter: + aaxMeterType = AAX_eMeterType_Input; + break; + case AudioProcessorParameter::outputMeter: + aaxMeterType = AAX_eMeterType_Output; + break; + case AudioProcessorParameter::compressorLimiterGainReductionMeter: + aaxMeterType = AAX_eMeterType_CLGain; + break; + case AudioProcessorParameter::expanderGateGainReductionMeter: + aaxMeterType = AAX_eMeterType_EGGain; + break; + case AudioProcessorParameter::analysisMeter: + aaxMeterType = AAX_eMeterType_Analysis; + break; + default: + aaxMeterType = AAX_eMeterType_Other; + } + + meterProperties->AddProperty (AAX_eProperty_Meter_Type, aaxMeterType); + meterProperties->AddProperty (AAX_eProperty_Meter_Orientation, AAX_eMeterOrientation_TopRight); + descriptor.AddMeterDescription ('Metr' + static_cast (meterIdx++), + p.getParameterName (i).toRawUTF8(), meterProperties); + } + } + } + + return meterIdx; + } + + static void createDescriptor (AAX_IComponentDescriptor& desc, int configIndex, + const AudioProcessor::BusesLayout& fullLayout, AudioProcessor& processor, + const int numMeters) { AAX_EStemFormat aaxInputFormat = getFormatForAudioChannelSet (fullLayout.getMainInputChannelSet(), false); AAX_EStemFormat aaxOutputFormat = getFormatForAudioChannelSet (fullLayout.getMainOutputChannelSet(), false); @@ -1611,6 +1694,13 @@ namespace AAXClasses check (desc.AddPrivateData (JUCEAlgorithmIDs::pluginInstance, sizeof (PluginInstanceInfo))); check (desc.AddPrivateData (JUCEAlgorithmIDs::preparedFlag, sizeof (int32_t))); + HeapBlock meterIDs (static_cast (numMeters)); + + for (int i = 0; i < numMeters; ++i) + meterIDs[i] = 'Metr' + static_cast (i); + + check (desc.AddMeters (JUCEAlgorithmIDs::meterTapBuffers, meterIDs.getData(), static_cast (numMeters))); + // Create a property map AAX_IPropertyMap* const properties = desc.NewPropertyMap(); jassert (properties != nullptr); @@ -1657,7 +1747,6 @@ namespace AAXClasses const int maxAuxBuses = jmax (0, jmin (15, fullLayout.outputBuses.size() - 1)); - // add the output buses // This is incrdibly dumb: the output bus format must be well defined // for every main bus in/out format pair. This means that there cannot @@ -1690,6 +1779,8 @@ namespace AAXClasses descriptor.AddName (JucePlugin_Name); descriptor.AddCategory (JucePlugin_AAXCategory); + const int numMeters = addAAXMeters (*plugin, descriptor); + #ifdef JucePlugin_AAXPageTableFile // optional page table setting - define this macro in your project if you want // to set this value - see Avid documentation for details about its format. @@ -1705,7 +1796,7 @@ namespace AAXClasses if (AAX_IComponentDescriptor* const desc = descriptor.NewComponentDescriptor()) { - createDescriptor (*desc, 0, plugin->getBusesLayout(), *plugin); + createDescriptor (*desc, 0, plugin->getBusesLayout(), *plugin, numMeters); check (descriptor.AddComponent (desc)); } @@ -1731,7 +1822,7 @@ namespace AAXClasses if (AAX_IComponentDescriptor* const desc = descriptor.NewComponentDescriptor()) { - createDescriptor (*desc, configIndex++, fullLayout, *plugin); + createDescriptor (*desc, configIndex++, fullLayout, *plugin, numMeters); check (descriptor.AddComponent (desc)); } } diff --git a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm index 18082648b3..5953f3238e 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -800,6 +800,7 @@ public: && juceFilter != nullptr && index < juceFilter->getNumParameters()) { + outParameterInfo.unit = kAudioUnitParameterUnit_Generic; outParameterInfo.flags = (UInt32) (kAudioUnitParameterFlag_IsWritable | kAudioUnitParameterFlag_IsReadable | kAudioUnitParameterFlag_HasCFNameString @@ -818,6 +819,14 @@ public: if (juceFilter->isMetaParameter (index)) outParameterInfo.flags |= kAudioUnitParameterFlag_IsGlobalMeta; + // is this a meter? + if (((juceFilter->getParameterCategory (index) & 0xffff0000) >> 16) == 2) + { + outParameterInfo.flags &= ~kAudioUnitParameterFlag_IsWritable; + outParameterInfo.flags |= kAudioUnitParameterFlag_MeterReadOnly | kAudioUnitParameterFlag_DisplayLogarithmic; + outParameterInfo.unit = kAudioUnitParameterUnit_LinearGain; + } + MusicDeviceBase::FillInParameterName (outParameterInfo, name.toCFString(), true); outParameterInfo.minValue = 0.0f; @@ -825,7 +834,6 @@ public: outParameterInfo.defaultValue = juceFilter->getParameterDefaultValue (index); jassert (outParameterInfo.defaultValue >= outParameterInfo.minValue && outParameterInfo.defaultValue <= outParameterInfo.maxValue); - outParameterInfo.unit = kAudioUnitParameterUnit_Generic; return noErr; } diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index 884b1cc6f1..704b259a0a 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -913,6 +913,7 @@ private: const String identifier (idx); const String name = processor.getParameterName (idx); + AudioUnitParameterUnit unit = kAudioUnitParameterUnit_Generic; AudioUnitParameterOptions flags = (UInt32) (kAudioUnitParameterFlag_IsWritable | kAudioUnitParameterFlag_IsReadable | kAudioUnitParameterFlag_HasCFNameString @@ -929,6 +930,14 @@ private: if (processor.isMetaParameter (idx)) flags |= kAudioUnitParameterFlag_IsGlobalMeta; + // is this a meter? + if (((processor.getParameterCategory (index) & 0xffff0000) >> 16) == 2) + { + flags &= ~kAudioUnitParameterFlag_IsWritable; + flags |= kAudioUnitParameterFlag_MeterReadOnly | kAudioUnitParameterFlag_DisplayLogarithmic; + unit = kAudioUnitParameterUnit_LinearGain; + } + #if JUCE_FORCE_USE_LEGACY_PARAM_IDS AUParameterAddress address = static_cast (idx); #else diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index 47e4286969..6e03a72759 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -1750,7 +1750,11 @@ private: pointer_sized_int handleIsParameterAutomatable (VstOpCodeArguments args) { - return (filter != nullptr && filter->isParameterAutomatable (args.index)) ? 1 : 0; + if (filter == nullptr) + return 0; + + const bool isMeter = (((filter->getParameterCategory (args.index) & 0xffff0000) >> 16) == 2); + return (filter->isParameterAutomatable (args.index) && (! isMeter) ? 1 : 0); } pointer_sized_int handleParameterValueForText (VstOpCodeArguments args) diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index cdddcee011..2abd825fd9 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -221,7 +221,12 @@ public: info.defaultNormalizedValue = p.getParameterDefaultValue (index); jassert (info.defaultNormalizedValue >= 0 && info.defaultNormalizedValue <= 1.0f); info.unitId = Vst::kRootUnitId; - info.flags = p.isParameterAutomatable (index) ? Vst::ParameterInfo::kCanAutomate : 0; + + // is this a meter? + if (((p.getParameterCategory (index) & 0xffff0000) >> 16) == 2) + info.flags = Vst::ParameterInfo::kIsReadOnly; + else + info.flags = p.isParameterAutomatable (index) ? Vst::ParameterInfo::kCanAutomate : 0; } virtual ~Param() {} diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 502c255d58..a36dacdffe 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -648,6 +648,14 @@ bool AudioProcessor::isMetaParameter (int index) const return false; } +AudioProcessorParameter::Category AudioProcessor::getParameterCategory (int index) const +{ + if (AudioProcessorParameter* p = managedParameters[index]) + return p->getCategory(); + + return AudioProcessorParameter::generic; +} + AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const noexcept { AudioProcessorParameter* p = managedParameters[index]; @@ -1301,9 +1309,10 @@ void AudioProcessorParameter::endChangeGesture() processor->endParameterChangeGesture (parameterIndex); } -bool AudioProcessorParameter::isOrientationInverted() const { return false; } -bool AudioProcessorParameter::isAutomatable() const { return true; } -bool AudioProcessorParameter::isMetaParameter() const { return false; } +bool AudioProcessorParameter::isOrientationInverted() const { return false; } +bool AudioProcessorParameter::isAutomatable() const { return true; } +bool AudioProcessorParameter::isMetaParameter() const { return false; } +AudioProcessorParameter::Category AudioProcessorParameter::getCategory() const { return generic; } int AudioProcessorParameter::getNumSteps() const { return AudioProcessor::getDefaultNumParameterSteps(); } String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index cb1a3476e0..4c4269a543 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1099,6 +1099,14 @@ public: */ virtual bool isMetaParameter (int parameterIndex) const; + /** Should return the parameter's category. + By default, this returns the "generic" category. + + NOTE! This method will eventually be deprecated! It's recommended that you use + AudioProcessorParameter::isMetaParameter() instead. + */ + virtual AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const; + /** Sends a signal to the host to tell it that the user is about to start changing this parameter. diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index 0140faf57b..4980c135de 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -143,6 +143,28 @@ public: */ virtual bool isMetaParameter() const; + enum Category + { + generic = (0 << 16) | 0, /** If your parameter is not a meter then you should use this category */ + + inputGain = (1 << 16) | 0, /** Currently not used */ + outputGain = (1 << 16) | 1, + + /** The following categories tell the host that this parameter is a meter level value + and therefore read-only. Most hosts will display these type of parameters as + a meter in the generic view of your plug-in. Pro-Tools will also show the meter + in the mixer view. */ + inputMeter = (2 << 16) | 0, + outputMeter = (2 << 16) | 1, + compressorLimiterGainReductionMeter = (2 << 16) | 2, + expanderGateGainReductionMeter = (2 << 16) | 3, + analysisMeter = (2 << 16) | 4, + otherMeter = (2 << 16) | 5 + }; + + /** Returns the parameter's category. */ + virtual Category getCategory() const; + /** Returns the index of this parameter in its parent processor's parameter list. */ int getParameterIndex() const noexcept { return parameterIndex; } diff --git a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp index a8918a7318..3733d3f07f 100644 --- a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp @@ -83,12 +83,15 @@ private: ParamSlider (AudioProcessor& p, int paramIndex) : owner (p), index (paramIndex) { const int steps = owner.getParameterNumSteps (index); + const AudioProcessorParameter::Category category = p.getParameterCategory (index); + const bool isLevelMeter = (((category & 0xffff0000) >> 16) == 2); if (steps > 1 && steps < 0x7fffffff) setRange (0.0, 1.0, 1.0 / (steps - 1.0)); else setRange (0.0, 1.0); + setEnabled (! isLevelMeter); setSliderStyle (Slider::LinearBar); setTextBoxIsEditable (false); setScrollWheelEnabled (true); diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h index d53b816234..79080a478a 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h @@ -37,7 +37,8 @@ public: AudioParameterFloat (const String& parameterID, const String& name, NormalisableRange normalisableRange, float defaultValue, - const String& label = String()); + const String& label = String(), + Category category = AudioProcessorParameter::generic); /** Creates a AudioParameterFloat with an ID, name, and range. On creation, its value is set to the default value. diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h index 6c5392741b..da2274cb42 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h @@ -35,7 +35,8 @@ public: */ AudioProcessorParameterWithID (const String& parameterID, const String& name, - const String& label = String()); + const String& label = String(), + Category category = AudioProcessorParameter::generic); /** Destructor. */ ~AudioProcessorParameterWithID(); @@ -49,9 +50,13 @@ public: /** Provides access to the parameter's label. */ const String label; + /** Provides access to the parameter's category. */ + const Category category; + private: String getName (int) const override; String getLabel() const override; + Category getCategory() const override; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterWithID) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp index c18e4a5b58..b44ca779cd 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp @@ -27,19 +27,21 @@ AudioProcessorParameterWithID::AudioProcessorParameterWithID (const String& idToUse, const String& nameToUse, - const String& labelToUse) - : paramID (idToUse), name (nameToUse), label (labelToUse) {} + const String& labelToUse, + AudioProcessorParameter::Category categoryToUse) + : paramID (idToUse), name (nameToUse), label (labelToUse), category (categoryToUse) {} AudioProcessorParameterWithID::~AudioProcessorParameterWithID() {} -String AudioProcessorParameterWithID::getName (int maximumStringLength) const { return name.substring (0, maximumStringLength); } -String AudioProcessorParameterWithID::getLabel() const { return label; } +String AudioProcessorParameterWithID::getName (int maximumStringLength) const { return name.substring (0, maximumStringLength); } +String AudioProcessorParameterWithID::getLabel() const { return label; } +AudioProcessorParameter::Category AudioProcessorParameterWithID::getCategory() const { return category; } //============================================================================== AudioParameterFloat::AudioParameterFloat (const String& idToUse, const String& nameToUse, NormalisableRange r, float def, - const String& labelToUse) - : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse), + const String& labelToUse, Category categoryToUse) + : AudioProcessorParameterWithID (idToUse, nameToUse, labelToUse, categoryToUse), range (r), value (def), defaultValue (def) { }