| @@ -90,6 +90,8 @@ static Array<void*> activePlugins, activeUIs; | |||||
| static const AudioUnitPropertyID juceFilterObjectPropertyID = 0x1a45ffe9; | static const AudioUnitPropertyID juceFilterObjectPropertyID = 0x1a45ffe9; | ||||
| template <> struct ContainerDeletePolicy<const __CFString> { static void destroy (const __CFString* o) { if (o != nullptr) CFRelease (o); } }; | |||||
| // make sure the audio processor is initialized before the AUBase class | // make sure the audio processor is initialized before the AUBase class | ||||
| struct AudioProcessorHolder | struct AudioProcessorHolder | ||||
| { | { | ||||
| @@ -880,6 +882,34 @@ public: | |||||
| return kAudioUnitErr_InvalidParameter; | return kAudioUnitErr_InvalidParameter; | ||||
| } | } | ||||
| ComponentResult GetParameterValueStrings (AudioUnitScope inScope, | |||||
| AudioUnitParameterID inParameterID, | |||||
| CFArrayRef *outStrings) override | |||||
| { | |||||
| if (outStrings == nullptr) | |||||
| return noErr; | |||||
| const int index = getJuceIndexForAUParameterID (inParameterID); | |||||
| if (inScope == kAudioUnitScope_Global | |||||
| && juceFilter != nullptr | |||||
| && isPositiveAndBelow (index, juceFilter->getNumParameters()) | |||||
| && juceFilter->isParameterDiscrete (index)) | |||||
| { | |||||
| if (auto* valueStrings = parameterValueStringArrays[index]) | |||||
| { | |||||
| *outStrings = CFArrayCreate (NULL, | |||||
| (const void **) valueStrings->getRawDataPointer(), | |||||
| valueStrings->size(), | |||||
| NULL); | |||||
| return noErr; | |||||
| } | |||||
| } | |||||
| return kAudioUnitErr_InvalidParameter; | |||||
| } | |||||
| ComponentResult GetParameter (AudioUnitParameterID inID, | ComponentResult GetParameter (AudioUnitParameterID inID, | ||||
| AudioUnitScope inScope, | AudioUnitScope inScope, | ||||
| AudioUnitElement inElement, | AudioUnitElement inElement, | ||||
| @@ -1613,6 +1643,9 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| AudioUnitHelpers::ChannelRemapper mapper; | AudioUnitHelpers::ChannelRemapper mapper; | ||||
| //============================================================================== | |||||
| OwnedArray<OwnedArray<const __CFString>> parameterValueStringArrays; | |||||
| //============================================================================== | //============================================================================== | ||||
| void pullInputAudio (AudioUnitRenderActionFlags& flags, const AudioTimeStamp& timestamp, const UInt32 nFrames) noexcept | void pullInputAudio (AudioUnitRenderActionFlags& flags, const AudioTimeStamp& timestamp, const UInt32 nFrames) noexcept | ||||
| { | { | ||||
| @@ -1747,9 +1780,7 @@ private: | |||||
| if (usingManagedParameter) | if (usingManagedParameter) | ||||
| { | { | ||||
| const int n = juceFilter->getNumParameters(); | |||||
| for (int i = 0; i < n; ++i) | |||||
| for (int i = 0; i < numParams; ++i) | |||||
| { | { | ||||
| const AudioUnitParameterID auParamID = generateAUParameterIDForIndex (i); | const AudioUnitParameterID auParamID = generateAUParameterIDForIndex (i); | ||||
| @@ -1776,6 +1807,32 @@ private: | |||||
| if (param->isDiscrete()) | if (param->isDiscrete()) | ||||
| jassert (param->getNumSteps() != juceFilter->getDefaultNumParameterSteps()); | jassert (param->getNumSteps() != juceFilter->getDefaultNumParameterSteps()); | ||||
| #endif | #endif | ||||
| parameterValueStringArrays.ensureStorageAllocated (numParams); | |||||
| for (int index = 0; index < numParams; ++index) | |||||
| { | |||||
| OwnedArray<const __CFString>* stringValues = nullptr; | |||||
| #if ! JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE | |||||
| if (juceFilter->isParameterDiscrete (index)) | |||||
| { | |||||
| if (auto* param = juceFilter->getParameters()[index]) | |||||
| { | |||||
| const auto numSteps = juceFilter->getParameterNumSteps (index); | |||||
| stringValues = new OwnedArray<const __CFString>(); | |||||
| stringValues->ensureStorageAllocated (numSteps); | |||||
| const auto maxValue = getMaximumParameterValue (index); | |||||
| for (int i = 0; i < numSteps; ++i) | |||||
| stringValues->add (CFStringCreateCopy (nullptr, (param->getText ((float) i / maxValue, 0)).toCFString())); ; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| parameterValueStringArrays.add (stringValues); | |||||
| } | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||