Hi JUCE devs,
I’ve seen a problem validating some 3rd party plugins.
The code hangs-up in here:
StringArray AudioProcessorParameter::getAllValueStrings() const
{
if (isDiscrete() && valueStrings.isEmpty())
{
auto maxIndex = getNumSteps() - 1;
for (int i = 0; i < getNumSteps(); ++i)
valueStrings.add (getText ((float) i / (float) maxIndex, 1024));
}
The reason? getNumSteps() is a valid off the scale!
Plug-in:
MIDI Route for iOS
componentType = 1635085685 'aumu'
componentSubType = 1836476777 'mvii'
componentManufacturer = 1447380299 'VEEK'
componentFlags = 14
componentFlagsMask = 0
...
Printing description of this->discrete:
(const bool) discrete = true
Printing description of this->numSteps:
(const int) numSteps = 2147483647
Printing description of this->minValue:
(const AudioUnitParameterValue) minValue = -2.14748365E+9
Printing description of this->maxValue:
(const AudioUnitParameterValue) maxValue = 2.14748365E+9
I’m not really sure how to handle this. Other than imposing some sort of limit on numSteps 
Pete
My ongoing “fix” is:
juce_AudioUnitPluginFormat.mm
void refreshParameterList() override
{
paramIDToParameter.clear();
AudioProcessorParameterGroup newParameterTree;
if (audioUnit != nullptr)
{
UInt32 paramListSize = 0;
auto err = AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global,
0, ¶mListSize, nullptr);
haveParameterList = (paramListSize > 0 && err == noErr);
if (! haveParameterList)
return;
if (paramListSize > 0)
{
const size_t numParams = paramListSize / sizeof (int);
std::vector<UInt32> ids (numParams, 0);
AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global,
0, ids.data(), ¶mListSize);
std::map<UInt32, AudioProcessorParameterGroup*> groupIDMap;
for (size_t i = 0; i < numParams; ++i)
{
AudioUnitParameterInfo info;
memset(&info, 0, sizeof(info)); // MPC!
UInt32 sz = sizeof (info);
if (AudioUnitGetProperty (audioUnit,
kAudioUnitProperty_ParameterInfo,
kAudioUnitScope_Global,
ids[i], &info, &sz) == noErr)
{
String paramName;
if ((info.flags & kAudioUnitParameterFlag_HasCFNameString) != 0)
{
paramName = String::fromCFString (info.cfNameString);
if ((info.flags & kAudioUnitParameterFlag_CFNameRelease) != 0)
CFRelease (info.cfNameString);
}
else
{
paramName = String (info.name, sizeof (info.name));
}
bool isDiscrete = (info.unit == kAudioUnitParameterUnit_Indexed
|| info.unit == kAudioUnitParameterUnit_Boolean);
bool isBoolean = info.unit == kAudioUnitParameterUnit_Boolean;
auto label = [info]() -> String
{
if (info.unit == kAudioUnitParameterUnit_Percent) return "%";
if (info.unit == kAudioUnitParameterUnit_Seconds) return "s";
if (info.unit == kAudioUnitParameterUnit_Hertz) return "Hz";
if (info.unit == kAudioUnitParameterUnit_Decibels) return "dB";
if (info.unit == kAudioUnitParameterUnit_Milliseconds) return "ms";
return {};
}();
// MPC - some plug-ins (e.g. MIDI Route) show *HUGE* ranges (begin)
auto numSteps = isDiscrete ? (int) (info.maxValue - info.minValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps();
if (numSteps > 1024) {
if (isDiscrete) {
numSteps = 1024;
}
}
// MPC - some plug-ins (e.g. MIDI Route) show *HUGE* ranges (end)
auto parameter = std::make_unique<AUInstanceParameter> (*this,
ids[i],
paramName,
info.minValue,
info.maxValue,
info.defaultValue,
(info.flags & kAudioUnitParameterFlag_NonRealTime) == 0,
isDiscrete,
// MPC - some plug-ins (e.g. MIDI Route) show *HUGE* ranges (end)
numSteps, // isDiscrete ? (int) (info.maxValue - info.minValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps(),
// MPC - some plug-ins (e.g. MIDI Route) show *HUGE* ranges (end)
isBoolean,
label,
(info.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0);
This came out of the following thread, FWIW… Pete
2147483647 is std::limit<int_32>::max()
so maybe the plan was to say not discrete so instead of checking for 1024 maybe just checking for this particular value make sense.
Hi @otristan I agree: that is what I ended-up thinking!
Best if the JUCE team build that in to the code base.
It seems strange that nobody else has reported this problem, however? Maybe not many people are building plug-in host apps for iOS using JUCE!
Best wishes, Pete
@ed95 not sure if I should tag this with your handle, but wanted to make sure at least one JUCE dev saw it 
Pete