From daf876172792a9ce43bce29c1ab0560964b381b2 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 9 Mar 2021 12:47:31 +0000 Subject: [PATCH] AU Host: Ensure discrete parameters are scaled correctly Previously, the AU hosting code always computed the number of steps in the parameter range as though the minimum parameter value was 0. Now, we take the parameter's reported minimum into account when computing the number of steps. We also use the parameter's range, rather than its step number, when normalising/denormalising the parameter value. --- BREAKING-CHANGES.txt | 29 +++++++++++++++++++ .../juce_AudioUnitPluginFormat.mm | 8 +---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index 0d0586b399..496b9189fc 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -4,6 +4,35 @@ JUCE breaking changes Develop ======= +Change +------ +The implementations of `getValue` and `setValue` in `AUInstanceParameter` now +properly take the ranges of discrete parameters into account. + +Possible Issues +--------------- + +This issue affects JUCE Audio Unit hosts. Automation data previously saved for +a discrete parameter with a non-zero minimum value may not set the parameter to +the same values as previous JUCE versions. Note that previously, `getValue` on +a hosted discrete parameter may have returned out-of-range values, and +`setValue` may have only mapped to a portion of the parameter range. As a +result, automation recorded for affected parameters was likely already behaving +unexpectedly. + +Workaround +---------- +There is no workaround. + +Rationale +--------- +The old behaviour was incorrect, and was causing issues in plugin validators +and other hosts. Hosts expect `getValue` to return a normalised parameter +value. If this function returns an out-of-range value (including Inf and NaN) +this is likely to break assumptions made by the host, leading to crashes, +corrupted project data, or other defects. + + Change ------ AudioProcessorListener::audioProcessorChanged gained a new parameter describing diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 9aa4a338e9..2ebce0d407 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -495,17 +495,11 @@ public: float normaliseParamValue (float scaledValue) const noexcept { - if (discrete) - return scaledValue / (getNumSteps() - 1); - return (scaledValue - minValue) / range; } float scaleParamValue (float normalisedValue) const noexcept { - if (discrete) - return normalisedValue * (getNumSteps() - 1); - return minValue + (range * normalisedValue); } @@ -1467,7 +1461,7 @@ public: info.defaultValue, (info.flags & kAudioUnitParameterFlag_NonRealTime) == 0, isDiscrete, - isDiscrete ? (int) (info.maxValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps(), + isDiscrete ? (int) (info.maxValue - info.minValue + 1.0f) : AudioProcessor::getDefaultNumParameterSteps(), isBoolean, label, (info.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0);