| @@ -1351,7 +1351,6 @@ public: | |||
| void refreshParameterList() override | |||
| { | |||
| managedParameters.clear (false); | |||
| paramIDToIndex.clear(); | |||
| AudioProcessorParameterGroup newParameterTree; | |||
| @@ -1440,7 +1439,6 @@ public: | |||
| isBoolean, | |||
| label, | |||
| (info.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0); | |||
| addParameterInternal (parameter); | |||
| if (info.flags & kAudioUnitParameterFlag_HasClump) | |||
| { | |||
| @@ -1487,7 +1485,7 @@ public: | |||
| } | |||
| } | |||
| getParameterTree() = std::move (newParameterTree); | |||
| setParameterTree (std::move (newParameterTree)); | |||
| UInt32 propertySize = 0; | |||
| Boolean writable = false; | |||
| @@ -180,17 +180,16 @@ public: | |||
| inputs.clear(); | |||
| outputs.clear(); | |||
| managedParameters.clear (false); | |||
| AudioProcessorParameterGroup parameterGroups; | |||
| AudioProcessorParameterGroup newTree; | |||
| for (unsigned int i = 0; i < plugin->PortCount; ++i) | |||
| { | |||
| const auto portDesc = plugin->PortDescriptors[i]; | |||
| if ((portDesc & LADSPA_PORT_CONTROL) != 0) | |||
| parameterGroups.addChild (std::make_unique<LADSPAParameter> (*this, (int) i, | |||
| String (plugin->PortNames[i]).trim(), | |||
| (portDesc & LADSPA_PORT_INPUT) != 0)); | |||
| newTree.addChild (std::make_unique<LADSPAParameter> (*this, (int) i, | |||
| String (plugin->PortNames[i]).trim(), | |||
| (portDesc & LADSPA_PORT_INPUT) != 0)); | |||
| if ((portDesc & LADSPA_PORT_AUDIO) != 0) | |||
| { | |||
| @@ -199,7 +198,7 @@ public: | |||
| } | |||
| } | |||
| getParameterTree() = std::move (parameterGroups); | |||
| setParameterTree (std::move (newTree)); | |||
| for (auto* param : getParameters()) | |||
| if (auto* ladspaParam = dynamic_cast<LADSPAParameter*> (param)) | |||
| @@ -2560,7 +2560,6 @@ private: | |||
| auto* param = new VST3Parameter (*this, | |||
| paramInfo.id, | |||
| (paramInfo.flags & Vst::ParameterInfo::kCanAutomate) != 0); | |||
| addParameterInternal (param); | |||
| if ((paramInfo.flags & Vst::ParameterInfo::kIsBypass) != 0) | |||
| bypassParam = param; | |||
| @@ -2594,7 +2593,7 @@ private: | |||
| group->addChild (std::unique_ptr<AudioProcessorParameter> (param)); | |||
| } | |||
| getParameterTree() = std::move (newParameterTree); | |||
| setParameterTree (std::move (newParameterTree)); | |||
| } | |||
| void synchroniseStates() | |||
| @@ -1006,6 +1006,16 @@ struct VSTPluginInstance : public AudioPluginInstance, | |||
| if (auto* xml = vstModule->vstXml.get()) | |||
| xmlInfo.reset (VSTXMLInfo::createFor (*xml)); | |||
| refreshParameterList(); | |||
| vstSupportsBypass = (pluginCanDo ("bypass") > 0); | |||
| setRateAndBufferSizeDetails (sampleRateToUse, blockSizeToUse); | |||
| } | |||
| void refreshParameterList() override | |||
| { | |||
| AudioProcessorParameterGroup newParameterTree; | |||
| for (int i = 0; i < vstEffect->numParams; ++i) | |||
| { | |||
| String paramName; | |||
| @@ -1070,21 +1080,12 @@ struct VSTPluginInstance : public AudioPluginInstance, | |||
| } | |||
| } | |||
| addParameter (new VSTParameter (*this, | |||
| paramName, | |||
| shortParamNames, | |||
| defaultValue, | |||
| label, | |||
| isAutomatable, | |||
| isDiscrete, | |||
| numSteps, | |||
| isBoolSwitch, | |||
| parameterValueStrings, | |||
| valueType)); | |||
| newParameterTree.addChild (std::make_unique<VSTParameter> (*this, paramName, shortParamNames, defaultValue, | |||
| label, isAutomatable, isDiscrete, numSteps, | |||
| isBoolSwitch, parameterValueStrings, valueType)); | |||
| } | |||
| vstSupportsBypass = (pluginCanDo ("bypass") > 0); | |||
| setRateAndBufferSizeDetails (sampleRateToUse, blockSizeToUse); | |||
| setParameterTree (std::move (newParameterTree)); | |||
| } | |||
| ~VSTPluginInstance() override | |||
| @@ -34,6 +34,8 @@ PluginDescription AudioPluginInstance::getPluginDescription() const | |||
| return desc; | |||
| } | |||
| void* AudioPluginInstance::getPlatformSpecificData() { return nullptr; } | |||
| String AudioPluginInstance::getParameterID (int parameterIndex) | |||
| { | |||
| assertOnceOnDeprecatedMethodUse(); | |||
| @@ -63,7 +63,7 @@ public: | |||
| //============================================================================== | |||
| /** Fills-in the appropriate parts of this plugin description object. */ | |||
| virtual void fillInPluginDescription (PluginDescription& description) const = 0; | |||
| virtual void fillInPluginDescription (PluginDescription&) const = 0; | |||
| /** Returns a PluginDescription for this plugin. | |||
| This is just a convenience method to avoid calling fillInPluginDescription. | |||
| @@ -74,12 +74,7 @@ public: | |||
| E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be | |||
| cast to an AudioUnit handle. | |||
| */ | |||
| virtual void* getPlatformSpecificData() { return nullptr; } | |||
| /** For some formats (currently AudioUnit), this forces a reload of the list of | |||
| available parameters. | |||
| */ | |||
| virtual void refreshParameterList() {} | |||
| virtual void* getPlatformSpecificData(); | |||
| // Rather than using these methods you should call the corresponding methods | |||
| // on the AudioProcessorParameter objects returned from getParameters(). | |||
| @@ -60,11 +60,6 @@ AudioProcessor::~AudioProcessor() | |||
| // or more parameters without having made a corresponding call to endParameterChangeGesture... | |||
| jassert (changingParams.countNumberOfSetBits() == 0); | |||
| #endif | |||
| // The parameters are owned by an AudioProcessorParameterGroup, but we need | |||
| // to keep the managedParameters array populated to maintain backwards | |||
| // compatibility. | |||
| managedParameters.clearQuick (false); | |||
| } | |||
| //============================================================================== | |||
| @@ -371,10 +366,6 @@ void AudioProcessor::setRateAndBufferSizeDetails (double newSampleRate, int newB | |||
| { | |||
| currentSampleRate = newSampleRate; | |||
| blockSize = newBlockSize; | |||
| #ifdef JUCE_DEBUG | |||
| checkForDupedParamIDs(); | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| @@ -405,12 +396,12 @@ int AudioProcessor::getOffsetInBusBufferForAbsoluteChannelIndex (bool isInput, i | |||
| } | |||
| //============================================================================== | |||
| void AudioProcessor::setNonRealtime (const bool newNonRealtime) noexcept | |||
| void AudioProcessor::setNonRealtime (bool newNonRealtime) noexcept | |||
| { | |||
| nonRealtime = newNonRealtime; | |||
| } | |||
| void AudioProcessor::setLatencySamples (const int newLatency) | |||
| void AudioProcessor::setLatencySamples (int newLatency) | |||
| { | |||
| if (latencySamples != newLatency) | |||
| { | |||
| @@ -419,148 +410,6 @@ void AudioProcessor::setLatencySamples (const int newLatency) | |||
| } | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_GCC | |||
| #pragma GCC diagnostic push | |||
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic push | |||
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |||
| #elif JUCE_MSVC | |||
| #pragma warning (push, 0) | |||
| #pragma warning (disable: 4996) | |||
| #endif | |||
| void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newValue) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->setValueNotifyingHost (newValue); | |||
| } | |||
| else if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| setParameter (parameterIndex, newValue); | |||
| sendParamChangeMessageToListeners (parameterIndex, newValue); | |||
| } | |||
| } | |||
| void AudioProcessor::sendParamChangeMessageToListeners (int parameterIndex, float newValue) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->sendValueChangedMessageToListeners (newValue); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChanged (this, parameterIndex, newValue); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| void AudioProcessor::beginParameterChangeGesture (int parameterIndex) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->beginChangeGesture(); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| // This means you've called beginParameterChangeGesture twice in succession without a matching | |||
| // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. | |||
| jassert (! changingParams[parameterIndex]); | |||
| changingParams.setBit (parameterIndex); | |||
| #endif | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| void AudioProcessor::endParameterChangeGesture (int parameterIndex) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->endChangeGesture(); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| // This means you've called endParameterChangeGesture without having previously called | |||
| // beginParameterChangeGesture. That might be fine in most hosts, but better to keep the | |||
| // calls matched correctly. | |||
| jassert (changingParams[parameterIndex]); | |||
| changingParams.clearBit (parameterIndex); | |||
| #endif | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| String AudioProcessor::getParameterName (int index, int maximumStringLength) | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getName (maximumStringLength); | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterName (index).substring (0, maximumStringLength) | |||
| : String(); | |||
| } | |||
| const String AudioProcessor::getParameterText (int index) | |||
| { | |||
| #if JUCE_DEBUG | |||
| // if you hit this, then you're probably using the old parameter control methods, | |||
| // but have forgotten to implement either of the getParameterText() methods. | |||
| jassert (! textRecursionCheck); | |||
| ScopedValueSetter<bool> sv (textRecursionCheck, true, false); | |||
| #endif | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterText (index, 1024) | |||
| : String(); | |||
| } | |||
| String AudioProcessor::getParameterText (int index, int maximumStringLength) | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getText (p->getValue(), maximumStringLength); | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterText (index).substring (0, maximumStringLength) | |||
| : String(); | |||
| } | |||
| #if JUCE_GCC | |||
| #pragma GCC diagnostic pop | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic pop | |||
| #elif JUCE_MSVC | |||
| #pragma warning (pop) | |||
| #endif | |||
| //============================================================================== | |||
| AudioProcessorListener* AudioProcessor::getListenerLocked (int index) const noexcept | |||
| { | |||
| @@ -575,179 +424,72 @@ void AudioProcessor::updateHostDisplay() | |||
| l->audioProcessorChanged (this); | |||
| } | |||
| const OwnedArray<AudioProcessorParameter>& AudioProcessor::getParameters() const noexcept | |||
| { | |||
| return managedParameters; | |||
| } | |||
| int AudioProcessor::getNumParameters() | |||
| { | |||
| return managedParameters.size(); | |||
| } | |||
| float AudioProcessor::getParameter (int index) | |||
| const Array<AudioProcessorParameter*>& AudioProcessor::getParameters() const | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| return p->getValue(); | |||
| return 0; | |||
| } | |||
| void AudioProcessor::setParameter (int index, float newValue) | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| p->setValue (newValue); | |||
| } | |||
| float AudioProcessor::getParameterDefaultValue (int index) | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getDefaultValue(); | |||
| return 0; | |||
| } | |||
| const String AudioProcessor::getParameterName (int index) | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| return p->getName (512); | |||
| return {}; | |||
| } | |||
| String AudioProcessor::getParameterID (int index) | |||
| { | |||
| // Don't use getParamChecked here, as this must also work for legacy plug-ins | |||
| if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (managedParameters[index])) | |||
| return p->paramID; | |||
| return String (index); | |||
| } | |||
| int AudioProcessor::getParameterNumSteps (int index) | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getNumSteps(); | |||
| return AudioProcessor::getDefaultNumParameterSteps(); | |||
| } | |||
| int AudioProcessor::getDefaultNumParameterSteps() noexcept | |||
| { | |||
| return 0x7fffffff; | |||
| } | |||
| bool AudioProcessor::isParameterDiscrete (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->isDiscrete(); | |||
| return false; | |||
| } | |||
| String AudioProcessor::getParameterLabel (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getLabel(); | |||
| return {}; | |||
| } | |||
| bool AudioProcessor::isParameterAutomatable (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->isAutomatable(); | |||
| return true; | |||
| } | |||
| bool AudioProcessor::isParameterOrientationInverted (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->isOrientationInverted(); | |||
| return false; | |||
| } | |||
| bool AudioProcessor::isMetaParameter (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->isMetaParameter(); | |||
| if (flatParamListNeedsRebuilding) | |||
| { | |||
| flatParamListNeedsRebuilding = false; | |||
| flatParameterList = parameterTree.getParameters (true); | |||
| return false; | |||
| } | |||
| #ifdef JUCE_DEBUG | |||
| StringArray usedIDs; | |||
| usedIDs.ensureStorageAllocated (flatParameterList.size()); | |||
| #endif | |||
| AudioProcessorParameter::Category AudioProcessor::getParameterCategory (int index) const | |||
| { | |||
| if (auto* p = managedParameters[index]) | |||
| return p->getCategory(); | |||
| int index = 0; | |||
| return AudioProcessorParameter::genericParameter; | |||
| } | |||
| for (auto& p : flatParameterList) | |||
| { | |||
| p->processor = const_cast<AudioProcessor*> (this); | |||
| p->parameterIndex = index++; | |||
| AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const noexcept | |||
| { | |||
| AudioProcessorParameter* p = managedParameters[index]; | |||
| #ifdef JUCE_DEBUG | |||
| if (auto* withID = dynamic_cast<AudioProcessorParameterWithID*> (p)) | |||
| usedIDs.add (withID->paramID); | |||
| #endif | |||
| } | |||
| // 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; | |||
| } | |||
| #ifdef JUCE_DEBUG | |||
| usedIDs.sort (false); | |||
| void AudioProcessor::addParameterInternal (AudioProcessorParameter* param) | |||
| { | |||
| param->processor = this; | |||
| param->parameterIndex = managedParameters.size(); | |||
| managedParameters.add (param); | |||
| // This assertion checks whether you attempted to add two or more parameters with the same ID | |||
| for (int i = 1; i < usedIDs.size(); ++i) | |||
| jassert (usedIDs[i - 1] != usedIDs[i]); | |||
| #endif | |||
| } | |||
| #ifdef JUCE_DEBUG | |||
| shouldCheckParamsForDupeIDs = true; | |||
| #endif | |||
| return flatParameterList; | |||
| } | |||
| void AudioProcessor::addParameter (AudioProcessorParameter* param) | |||
| { | |||
| addParameterInternal (param); | |||
| parameterTree.addChild (std::unique_ptr<AudioProcessorParameter> (param)); | |||
| flatParamListNeedsRebuilding = true; | |||
| } | |||
| void AudioProcessor::addParameterGroup (std::unique_ptr<AudioProcessorParameterGroup> group) | |||
| { | |||
| for (auto* param : group->getParameters (true)) | |||
| addParameterInternal (param); | |||
| parameterTree.addChild (std::move (group)); | |||
| flatParamListNeedsRebuilding = true; | |||
| } | |||
| AudioProcessorParameterGroup& AudioProcessor::getParameterTree() | |||
| const AudioProcessorParameterGroup& AudioProcessor::getParameterTree() const | |||
| { | |||
| return parameterTree; | |||
| } | |||
| #ifdef JUCE_DEBUG | |||
| void AudioProcessor::checkForDupedParamIDs() | |||
| void AudioProcessor::setParameterTree (AudioProcessorParameterGroup&& newTree) | |||
| { | |||
| if (shouldCheckParamsForDupeIDs) | |||
| { | |||
| shouldCheckParamsForDupeIDs = false; | |||
| StringArray ids; | |||
| for (auto p : managedParameters) | |||
| if (auto* withID = dynamic_cast<AudioProcessorParameterWithID*> (p)) | |||
| ids.add (withID->paramID); | |||
| parameterTree = std::move (newTree); | |||
| flatParamListNeedsRebuilding = true; | |||
| } | |||
| ids.sort (false); | |||
| void AudioProcessor::refreshParameterList() {} | |||
| for (int i = 1; i < ids.size(); ++i) | |||
| { | |||
| // This is triggered if you have two or more parameters with the same ID! | |||
| jassert (ids[i - 1] != ids[i]); | |||
| } | |||
| } | |||
| int AudioProcessor::getDefaultNumParameterSteps() noexcept | |||
| { | |||
| return 0x7fffffff; | |||
| } | |||
| #endif | |||
| void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) | |||
| { | |||
| @@ -1422,6 +1164,259 @@ const char* AudioProcessor::getWrapperTypeDescription (AudioProcessor::WrapperTy | |||
| } | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_GCC | |||
| #pragma GCC diagnostic push | |||
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic push | |||
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |||
| #elif JUCE_MSVC | |||
| #pragma warning (push, 0) | |||
| #pragma warning (disable: 4996) | |||
| #endif | |||
| void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newValue) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->setValueNotifyingHost (newValue); | |||
| } | |||
| else if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| setParameter (parameterIndex, newValue); | |||
| sendParamChangeMessageToListeners (parameterIndex, newValue); | |||
| } | |||
| } | |||
| void AudioProcessor::sendParamChangeMessageToListeners (int parameterIndex, float newValue) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->sendValueChangedMessageToListeners (newValue); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChanged (this, parameterIndex, newValue); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| void AudioProcessor::beginParameterChangeGesture (int parameterIndex) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->beginChangeGesture(); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| // This means you've called beginParameterChangeGesture twice in succession without a matching | |||
| // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. | |||
| jassert (! changingParams[parameterIndex]); | |||
| changingParams.setBit (parameterIndex); | |||
| #endif | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| void AudioProcessor::endParameterChangeGesture (int parameterIndex) | |||
| { | |||
| if (auto* param = getParameters()[parameterIndex]) | |||
| { | |||
| param->endChangeGesture(); | |||
| } | |||
| else | |||
| { | |||
| if (isPositiveAndBelow (parameterIndex, getNumParameters())) | |||
| { | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| // This means you've called endParameterChangeGesture without having previously called | |||
| // beginParameterChangeGesture. That might be fine in most hosts, but better to keep the | |||
| // calls matched correctly. | |||
| jassert (changingParams[parameterIndex]); | |||
| changingParams.clearBit (parameterIndex); | |||
| #endif | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| if (auto* l = getListenerLocked (i)) | |||
| l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // called with an out-of-range parameter index! | |||
| } | |||
| } | |||
| } | |||
| String AudioProcessor::getParameterName (int index, int maximumStringLength) | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getName (maximumStringLength); | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterName (index).substring (0, maximumStringLength) | |||
| : String(); | |||
| } | |||
| const String AudioProcessor::getParameterText (int index) | |||
| { | |||
| #if JUCE_DEBUG | |||
| // if you hit this, then you're probably using the old parameter control methods, | |||
| // but have forgotten to implement either of the getParameterText() methods. | |||
| jassert (! textRecursionCheck); | |||
| ScopedValueSetter<bool> sv (textRecursionCheck, true, false); | |||
| #endif | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterText (index, 1024) | |||
| : String(); | |||
| } | |||
| String AudioProcessor::getParameterText (int index, int maximumStringLength) | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getText (p->getValue(), maximumStringLength); | |||
| return isPositiveAndBelow (index, getNumParameters()) ? getParameterText (index).substring (0, maximumStringLength) | |||
| : String(); | |||
| } | |||
| int AudioProcessor::getNumParameters() | |||
| { | |||
| return getParameters().size(); | |||
| } | |||
| float AudioProcessor::getParameter (int index) | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| return p->getValue(); | |||
| return 0; | |||
| } | |||
| void AudioProcessor::setParameter (int index, float newValue) | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| p->setValue (newValue); | |||
| } | |||
| float AudioProcessor::getParameterDefaultValue (int index) | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getDefaultValue(); | |||
| return 0; | |||
| } | |||
| const String AudioProcessor::getParameterName (int index) | |||
| { | |||
| if (auto* p = getParamChecked (index)) | |||
| return p->getName (512); | |||
| return {}; | |||
| } | |||
| String AudioProcessor::getParameterID (int index) | |||
| { | |||
| // Don't use getParamChecked here, as this must also work for legacy plug-ins | |||
| if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (getParameters()[index])) | |||
| return p->paramID; | |||
| return String (index); | |||
| } | |||
| int AudioProcessor::getParameterNumSteps (int index) | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getNumSteps(); | |||
| return AudioProcessor::getDefaultNumParameterSteps(); | |||
| } | |||
| bool AudioProcessor::isParameterDiscrete (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->isDiscrete(); | |||
| return false; | |||
| } | |||
| String AudioProcessor::getParameterLabel (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getLabel(); | |||
| return {}; | |||
| } | |||
| bool AudioProcessor::isParameterAutomatable (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->isAutomatable(); | |||
| return true; | |||
| } | |||
| bool AudioProcessor::isParameterOrientationInverted (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->isOrientationInverted(); | |||
| return false; | |||
| } | |||
| bool AudioProcessor::isMetaParameter (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->isMetaParameter(); | |||
| return false; | |||
| } | |||
| AudioProcessorParameter::Category AudioProcessor::getParameterCategory (int index) const | |||
| { | |||
| if (auto* p = getParameters()[index]) | |||
| return p->getCategory(); | |||
| return AudioProcessorParameter::genericParameter; | |||
| } | |||
| AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const | |||
| { | |||
| auto p = getParameters()[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; | |||
| } | |||
| #if JUCE_GCC | |||
| #pragma GCC diagnostic pop | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic pop | |||
| #elif JUCE_MSVC | |||
| #pragma warning (pop) | |||
| #endif | |||
| //============================================================================== | |||
| void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} | |||
| void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} | |||
| @@ -975,95 +975,6 @@ public: | |||
| AudioProcessorEditor* createEditorIfNeeded(); | |||
| //============================================================================== | |||
| /** This must return the correct value immediately after the object has been | |||
| created, and mustn't change the number of parameters later. | |||
| NOTE! This method is deprecated! It's recommended that you use the | |||
| AudioProcessorParameter class instead to manage your parameters. | |||
| */ | |||
| JUCE_DEPRECATED (virtual int getNumParameters()); | |||
| /** Returns the name of a particular parameter. | |||
| NOTE! This method is deprecated! It's recommended that you use the | |||
| AudioProcessorParameter class instead to manage your parameters. | |||
| */ | |||
| JUCE_DEPRECATED (virtual const String getParameterName (int parameterIndex)); | |||
| /** Returns the ID of a particular parameter. | |||
| The ID is used to communicate the value or mapping of a particular parameter with | |||
| the host. By default this method will simply return a string representation of | |||
| index. | |||
| NOTE! This method is deprecated! It's recommended that you use the | |||
| AudioProcessorParameterWithID class instead to manage your parameters. | |||
| */ | |||
| JUCE_DEPRECATED (virtual String getParameterID (int index)); | |||
| /** Called by the host to find out the value of one of the processor's parameters. | |||
| The host 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. | |||
| NOTE! This method is deprecated! It's recommended that you use the | |||
| AudioProcessorParameter class instead to manage your parameters. | |||
| */ | |||
| JUCE_DEPRECATED (virtual float getParameter (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 | |||
| will look better in constrained spaces (e.g. the displays on hardware controller | |||
| devices or mixing desks) then you should implement this method. | |||
| If you don't override it, the default implementation will call getParameterName(int), | |||
| and truncate the result. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getName() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual String getParameterName (int parameterIndex, int maximumStringLength)); | |||
| /** Returns the value of a parameter as a text string. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getText() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual const String getParameterText (int parameterIndex)); | |||
| /** Returns the value of a parameter as a text string with a preferred maximum length. | |||
| If you want to provide customised short versions of your parameter values that | |||
| will look better in constrained spaces (e.g. the displays on hardware controller | |||
| devices or mixing desks) then you should implement this method. | |||
| If you don't override it, the default implementation will call getParameterText(int), | |||
| and truncate the result. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getText() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual String getParameterText (int parameterIndex, int maximumStringLength)); | |||
| /** Returns the number of discrete steps that this parameter can represent. | |||
| The default return value if you don't implement this method is | |||
| AudioProcessor::getDefaultNumParameterSteps(). | |||
| If your parameter is boolean, then you may want to make this return 2. | |||
| If you want the host to display stepped automation values, rather than a | |||
| continuous interpolation between successive values, you should ensure that | |||
| isParameterDiscrete returns true. | |||
| The value that is returned may or may not be used, depending on the host. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getNumSteps() instead. | |||
| @see isParameterDiscrete | |||
| */ | |||
| JUCE_DEPRECATED (virtual int getParameterNumSteps (int parameterIndex)); | |||
| /** Returns the default number of steps for a parameter. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| @@ -1073,130 +984,6 @@ public: | |||
| */ | |||
| static int getDefaultNumParameterSteps() noexcept; | |||
| /** Returns true if the parameter should take discrete, rather than continuous | |||
| values. | |||
| If the parameter is boolean, this should return true (with getParameterNumSteps | |||
| returning 2). | |||
| The value that is returned may or may not be used, depending on the host. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::isDiscrete() instead. | |||
| @see getParameterNumSteps | |||
| */ | |||
| JUCE_DEPRECATED (virtual bool isParameterDiscrete (int parameterIndex) const); | |||
| /** Returns the default value for the parameter. | |||
| By default, this just returns 0. | |||
| The value that is returned may or may not be used, depending on the host. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getDefaultValue() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual float getParameterDefaultValue (int parameterIndex)); | |||
| /** Some plugin types may be able to return a label string for a | |||
| parameter's units. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getLabel() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual String getParameterLabel (int index) const); | |||
| /** This can be overridden to tell the host that particular parameters operate in the | |||
| reverse direction. (Not all plugin formats or hosts will actually use this information). | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::isOrientationInverted() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual bool isParameterOrientationInverted (int index) const); | |||
| /** The host will call this method to change the value of one of the processor's parameters. | |||
| The host may call this at any time, including during the audio processing | |||
| callback, so the processor 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 | |||
| setParameterNotifyingHost() 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. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::setValue() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual void setParameter (int parameterIndex, float newValue)); | |||
| /** Your processor 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. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::setValueNotifyingHost() instead. | |||
| */ | |||
| void setParameterNotifyingHost (int parameterIndex, float newValue); | |||
| /** Returns true if the host can automate this parameter. | |||
| By default, this returns true for all parameters. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::isAutomatable() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual bool isParameterAutomatable (int parameterIndex) 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. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::isMetaParameter() instead. | |||
| */ | |||
| JUCE_DEPRECATED (virtual bool isMetaParameter (int parameterIndex) const); | |||
| /** Should return the parameter's category. | |||
| By default, this returns the "generic" category. | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::getCategory() instead. | |||
| */ | |||
| JUCE_DEPRECATED (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. | |||
| This allows the host to know when a parameter is actively being held by the user, and | |||
| it may use this information to help it record automation. | |||
| If you call this, it must be matched by a later call to endParameterChangeGesture(). | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::beginChangeGesture() instead. | |||
| */ | |||
| JUCE_DEPRECATED (void beginParameterChangeGesture (int parameterIndex)); | |||
| /** Tells the host that the user has finished changing this parameter. | |||
| This allows the host to know when a parameter is actively being held by the user, and | |||
| it may use this information to help it record automation. | |||
| A call to this method must follow a call to beginParameterChangeGesture(). | |||
| NOTE! This method is deprecated! It's recommended that you use | |||
| AudioProcessorParameter::endChangeGesture() instead. | |||
| */ | |||
| JUCE_DEPRECATED (void endParameterChangeGesture (int parameterIndex)); | |||
| /** The processor can call this when something (apart from a parameter value) has changed. | |||
| It sends a hint to the host that something like the program, number of parameters, | |||
| @@ -1222,10 +1009,21 @@ public: | |||
| void addParameterGroup (std::unique_ptr<AudioProcessorParameterGroup>); | |||
| /** Returns the group of parameters managed by this AudioProcessor. */ | |||
| AudioProcessorParameterGroup& getParameterTree(); | |||
| const AudioProcessorParameterGroup& getParameterTree() const; | |||
| /** Returns the current list of parameters. */ | |||
| const OwnedArray<AudioProcessorParameter>& getParameters() const noexcept; | |||
| /** Returns the group of parameters managed by this AudioProcessor. */ | |||
| void setParameterTree (AudioProcessorParameterGroup&& newTree); | |||
| /** A processor should implement this method so that the host can ask it to | |||
| rebuild its parameter tree. | |||
| If a plugin never changes its parameters, it's enough to create its | |||
| parameters in its constructor and do nothing in this method, but some | |||
| may want to | |||
| */ | |||
| virtual void refreshParameterList(); | |||
| /** Returns a flat list of the parameters in the current tree. */ | |||
| const Array<AudioProcessorParameter*>& getParameters() const; | |||
| //============================================================================== | |||
| /** Returns the number of preset programs the processor supports. | |||
| @@ -1432,38 +1230,6 @@ public: | |||
| */ | |||
| virtual void updateTrackProperties (const TrackProperties& properties); | |||
| //============================================================================== | |||
| #ifndef DOXYGEN | |||
| /** Deprecated: use getTotalNumInputChannels instead. */ | |||
| JUCE_DEPRECATED_WITH_BODY (int getNumInputChannels() const noexcept, { return getTotalNumInputChannels(); }) | |||
| JUCE_DEPRECATED_WITH_BODY (int getNumOutputChannels() const noexcept, { return getTotalNumOutputChannels(); }) | |||
| /** Returns a string containing a whitespace-separated list of speaker types | |||
| These functions are deprecated: use the methods provided in the AudioChannelSet | |||
| class. | |||
| */ | |||
| JUCE_DEPRECATED_WITH_BODY (const String getInputSpeakerArrangement() const noexcept, { return cachedInputSpeakerArrString; }) | |||
| JUCE_DEPRECATED_WITH_BODY (const String getOutputSpeakerArrangement() const noexcept, { return cachedOutputSpeakerArrString; }) | |||
| /** Returns the name of one of the processor's input channels. | |||
| These functions are deprecated: your audio processor can inform the host | |||
| on channel layouts and names via the methods in the AudioChannelSet class. | |||
| @see getBus, Bus::getCurrentLayout, AudioChannelSet | |||
| */ | |||
| JUCE_DEPRECATED (virtual const String getInputChannelName (int channelIndex) const); | |||
| JUCE_DEPRECATED (virtual const String getOutputChannelName (int channelIndex) const); | |||
| /** Returns true if the specified channel is part of a stereo pair with its neighbour. | |||
| These functions are deprecated: your audio processor should specify the audio | |||
| channel pairing information by modifying the busLayout member variable in | |||
| the constructor. */ | |||
| JUCE_DEPRECATED (virtual bool isInputChannelStereoPair (int index) const); | |||
| JUCE_DEPRECATED (virtual bool isOutputChannelStereoPair (int index) const); | |||
| #endif | |||
| //============================================================================== | |||
| /** Helper function that just converts an xml element into a binary blob. | |||
| @@ -1601,10 +1367,44 @@ protected: | |||
| /** @internal */ | |||
| void sendParamChangeMessageToListeners (int parameterIndex, float newValue); | |||
| private: | |||
| //============================================================================== | |||
| void addParameterInternal (AudioProcessorParameter*); | |||
| #ifndef DOXYGEN | |||
| public: | |||
| // These methods are all deprecated in favour of using AudioProcessorParameter | |||
| // and AudioProcessorParameterGroup | |||
| JUCE_DEPRECATED (virtual int getNumParameters()); | |||
| JUCE_DEPRECATED (virtual const String getParameterName (int parameterIndex)); | |||
| JUCE_DEPRECATED (virtual String getParameterID (int index)); | |||
| JUCE_DEPRECATED (virtual float getParameter (int parameterIndex)); | |||
| JUCE_DEPRECATED (virtual String getParameterName (int parameterIndex, int maximumStringLength)); | |||
| JUCE_DEPRECATED (virtual const String getParameterText (int parameterIndex)); | |||
| JUCE_DEPRECATED (virtual String getParameterText (int parameterIndex, int maximumStringLength)); | |||
| JUCE_DEPRECATED (virtual int getParameterNumSteps (int parameterIndex)); | |||
| JUCE_DEPRECATED (virtual bool isParameterDiscrete (int parameterIndex) const); | |||
| JUCE_DEPRECATED (virtual float getParameterDefaultValue (int parameterIndex)); | |||
| JUCE_DEPRECATED (virtual String getParameterLabel (int index) const); | |||
| JUCE_DEPRECATED (virtual bool isParameterOrientationInverted (int index) const); | |||
| JUCE_DEPRECATED (virtual void setParameter (int parameterIndex, float newValue)); | |||
| JUCE_DEPRECATED (virtual bool isParameterAutomatable (int parameterIndex) const); | |||
| JUCE_DEPRECATED (virtual bool isMetaParameter (int parameterIndex) const); | |||
| JUCE_DEPRECATED (virtual AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const); | |||
| JUCE_DEPRECATED (void beginParameterChangeGesture (int parameterIndex)); | |||
| JUCE_DEPRECATED (void endParameterChangeGesture (int parameterIndex)); | |||
| JUCE_DEPRECATED (void setParameterNotifyingHost (int parameterIndex, float newValue)); | |||
| // These functions are deprecated: your audio processor can inform the host | |||
| // on its bus and channel layouts and names using the AudioChannelSet and various bus classes. | |||
| JUCE_DEPRECATED_WITH_BODY (int getNumInputChannels() const noexcept, { return getTotalNumInputChannels(); }) | |||
| JUCE_DEPRECATED_WITH_BODY (int getNumOutputChannels() const noexcept, { return getTotalNumOutputChannels(); }) | |||
| JUCE_DEPRECATED_WITH_BODY (const String getInputSpeakerArrangement() const noexcept, { return cachedInputSpeakerArrString; }) | |||
| JUCE_DEPRECATED_WITH_BODY (const String getOutputSpeakerArrangement() const noexcept, { return cachedOutputSpeakerArrString; }) | |||
| JUCE_DEPRECATED (virtual const String getInputChannelName (int channelIndex) const); | |||
| JUCE_DEPRECATED (virtual const String getOutputChannelName (int channelIndex) const); | |||
| JUCE_DEPRECATED (virtual bool isInputChannelStereoPair (int index) const); | |||
| JUCE_DEPRECATED (virtual bool isOutputChannelStereoPair (int index) const); | |||
| #endif | |||
| private: | |||
| //============================================================================== | |||
| struct InOutChannelPair | |||
| { | |||
| @@ -1666,19 +1466,18 @@ private: | |||
| String cachedInputSpeakerArrString, cachedOutputSpeakerArrString; | |||
| int cachedTotalIns = 0, cachedTotalOuts = 0; | |||
| OwnedArray<AudioProcessorParameter> managedParameters; | |||
| AudioProcessorParameter* getParamChecked (int) const noexcept; | |||
| AudioProcessorParameterGroup parameterTree; | |||
| mutable Array<AudioProcessorParameter*> flatParameterList; | |||
| mutable bool flatParamListNeedsRebuilding = true; | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| BigInteger changingParams; | |||
| #endif | |||
| AudioProcessorParameter* getParamChecked (int) const; | |||
| #if JUCE_DEBUG | |||
| #if ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING | |||
| BigInteger changingParams; | |||
| #endif | |||
| bool textRecursionCheck = false; | |||
| bool shouldCheckParamsForDupeIDs = false; | |||
| void checkForDupedParamIDs(); | |||
| #endif | |||
| AudioProcessorListener* getListenerLocked (int) const noexcept; | |||
| @@ -1690,11 +1489,6 @@ private: | |||
| void processBypassed (AudioBuffer<floatType>&, MidiBuffer&); | |||
| friend class AudioProcessorParameter; | |||
| friend class JuceVST3EditController; | |||
| friend class JuceVST3Component; | |||
| friend class VST3PluginInstance; | |||
| friend class AudioUnitPluginInstance; | |||
| friend class LADSPAPluginInstance; | |||
| // This method is no longer used - you can delete it from your AudioProcessor classes. | |||
| @@ -268,10 +268,10 @@ public: | |||
| } | |||
| g1->addChild (std::make_unique<AudioProcessorParameterGroup> ("g6", "g6", " | ", | |||
| std::make_unique<AudioParameterFloat> ("p11", "p11", NormalisableRange<float> (0.0f, 2.0f), 0.5f), | |||
| std::make_unique<AudioParameterFloat> ("p13", "p13", NormalisableRange<float> (0.0f, 2.0f), 0.5f), | |||
| std::make_unique<AudioProcessorParameterGroup> ("g7", "g7", " | ", | |||
| std::make_unique<AudioParameterFloat> ("p12", "p12", NormalisableRange<float> (0.0f, 2.0f), 0.5f)), | |||
| std::make_unique<AudioParameterFloat> ("p13", "p13", NormalisableRange<float> (0.0f, 2.0f), 0.5f))); | |||
| std::make_unique<AudioParameterFloat> ("p14", "p14", NormalisableRange<float> (0.0f, 2.0f), 0.5f)), | |||
| std::make_unique<AudioParameterFloat> ("p15", "p15", NormalisableRange<float> (0.0f, 2.0f), 0.5f))); | |||
| TestAudioProcessor processor; | |||