The method used to classify AudioUnit, VST3 and AAX plug-in parameters as either continuous or discrete has changed.
Possible Issues
Plug-ins: DAW projects with automation data written by an AudioUnit, VST3 or AAX plug-in built with JUCE version 5.1.1 or earlier may load incorrectly when opened by an AudioUnit, VST3 or AAX plug-in built with JUCE version 5.2.0 and later.
Hosts: The AudioPluginInstance::getParameterNumSteps method now returns correct values for AU and VST3 plug-ins.
Workaround
Plug-ins: Enable JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE in the juce_audio_plugin_client module config page in the Projucer.
Hosts: Use AudioPluginInstance::getDefaultNumParameterSteps as the number of steps for all parameters.
Rationale
The old system for presenting plug-in parameters to a host as either continuous or discrete is inconsistent between plug-in types and lacks sufficient flexibility. This change harmonises the behaviour and allows individual parameters to be marked as continuous or discrete.
Thanks so much Tom! This is looking great in most hosts so far.
One issue: REAPER doesnāt seem to correctly show discrete parameters with JUCE-made Audio Unit plugins ā they still appear continuous and the string names arenāt shown. Weāve confirmed with our old non-JUCE, AU plugins that REAPER does correctly show discrete parameters. As far as I can tell, all the flags youāve set are more or less the same as what we were doing in our AU wrapper, so Iām not sure why it doesnāt work or whatās different.
Tom, there are still 2 calls to AudioProcessor::getParameters() lines 921 and 939 that wonāt work when we donāt use the AudioProcessorParameter classes.
Letās say I create a new plug-in from scratch with the Projucer on macOS. In the PluginProcessor constructor, I add a new parameter that I have declared as an AudioParameterChoice in the header, and I provide three string values for the choices. I compile it in VST + AU formats.
Now in Reaper, if I open the AU version, Iāll seeā¦ the Hello World on the UI Thatās fine. If I click on the āUIā button on the top right of the window associated with the plug-in, Iāll see a list of all the parameters available. Thatās where the problem isā¦
Since we have now the isDiscrete option enabled for AudioParameterChoice, instead of a slider, weāll see now in Reaper a ComboBox (with Reaper UI) displaying the available options. And Iāll see the three options I provided in the constructor of my PluginProcessor. If I click on the first, everything is fine. If I click on the second, itās fine as well. But if I click on the third, for a reason I donāt get the plug-in itself works as the third was properly selected, but in Reaper itās still the second that is displayed as the one I have clicked on.
This bug has a lot of implications, as I see the same behaviour in other DAWs, and strange things happening in Logic Pro X.
By the way, in the AudioProcessor classes, should we set the return value of āgetNumStepsā for AudioParameterChoice and AudioParameterInt to other values than AudioProcessorParameterWithID::getNumSteps() a.k.a. AudioProcessor::getDefaultNumParameterSteps() since they are discrete now ?
getNumSteps has already been changed from the default for AudioPrameterChoice (which is discrete), and Iāve now done the same for AudioPrameterInt (which is not discrete). For AudioPrameterInt this will let the user continuously select values in the automation lane, but Pro Tools, and perhaps other DAWs, can still indicate the steps in other places.
Iām a little confused. So, to properly set the isDiscrete flag in createAndAddParameter(), I also have to override isDiscrete() and getNumSteps() and therefore, subclass AudioProcessorParameter ? But then I canāt use AudioProcessorValueTreeState.createAndAddParameter() ?
Iām definitely confused. Whatās the proper way to create/use discrete parameters with AudioProcessorValueTreeState?
It always seemed odd to me that the AudioParameterFloat/Int/Bool/Choice classes did not have counterparts when using AudioProcessorValueTreeState.
No, you donāt. The AudioProcessorValueTreeState::Parameter is a generic parameter, that has the same bas class like the AudioParameterFloat etc, which is AudioProcessorParameterWithID, hence you can use the same interface.
getNumSteps() is already implemented, it deduces the information from the NormalisableRange.
I think it is an alternative to the AudioParameterFloat/Int/Bool classes. But the AudioProcessorValueTreeState version has already a better interface providing the AudioProcessorValueTreeState::Listener and the different attachment classes, so IMHO there is no need for the subclasses any longer.
This is very cool. Iāve always wondered why some other pluginsā parameters show up in MainStageās parameter list with sliders, on/off buttons and comboBoxes when mine were all only sliders. I just added the isDiscrete flag to my parameters that are really ints & bools and violaā¦MainStage shows them correctly.
And nowā¦let me see if this breaks already created automationā¦
Sorry to revive this topic, but I could use some clarification about this JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE flag: is this only relevant for plugins that use the new AudioProcessorParameter(WithID) + related classes, or also if your plugin is still using the AudioProcessor.setParameter calls?
Context: I have a plugin built with an old Juce version (a few commits before Juce 2.1.2), for which I recently released a new updated using Juce 5.3.2. The plugin is still using the AudioProcessor.set/getParameter calls, no AudioProcessorParameter classes.
(I had seen the other flag JUCE_FORCE_USE_LEGACY_PARAM_IDS, which is apparently only relevant when using the newer parameter classes, but was wondering about this automation flag as well)
In your case I suspect it would be safest to enable this option. However, this one is easy to test: record some automation for a parameter using an old version of JUCE, then recompile and attempt to read the automation back. It will be really obvious if things are not working correctly. AUs in Logic X would the be easiest way to find out.
OK, Iāll do some testing if itās not clear what the effect should be.
Edit: I never declared any parameters explicitly as discrete/continuous, and am not doing that now either, so itās not clear to me how things could change (unless there is something clever in the code that tries to find out if my parameters are continuous or discrete, but canāt see how that would work as I donāt have AudioProcessorParameter stuff in my code). Oh well, I guess Iāll have to go test each and every parameter then, right?
Have a search for JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE in the source code to see whatās changed.
If youāve never indicated that your parameters are discrete then the relevant changes are confined to the AU and AAX backends. Without the macro set AU parameters will be marked as HighResolution which allows the parameter to take more fine grained values in the automation lane, and AAX parameters will not have their ādiscretenessā set by whether they have more that 1000 steps or not.
OK, I did some testing today, and Iām logging my experience with this flag here for the sake of clarity (I hope) in case anyone else finds it useful. Note that the following is all for the case where you are NOT using the AudioProcessorParameter(WithID) etcā¦ classes, and still using the set/getParameterValue calls (possibly with your own parameter handling system).
In Logic Pro X, I created automation ramps for several of my parameters with the old version of the AU plugin installed (from way before this flag even existed), with values ramping from 0.0 to 1.0. This moved the parameters in the plugin from their minimum values to their maximum values. I saved this project.
I then installed the recently released version of my plugin (using Juce 5.3.2, and since I missed this change, with the JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE flag NOT enabled). When I open the project, the automation in Logic Pro X shows ramps from 0.0 to only around 0.79 (NOT 1.0), and my pluginās parameters donāt move up to their maximum values any longer. This means that automation data is now incorrectly being read by this version of the plugin!
I then rebuilt the plugin after setting JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE=1 in the project settings and installed that version. When I now open the project, automation ramps in Logic Pro X are again from 0.0 to 1.0, and my pluginās parameters again move from their minimum to their maximum values.
So, this means that:
apparently this macro needs to be enabled to avoid automation data corruption if you are NOT using the AudioProcesorParameter(WithID) classes
users of the recent update of my plugin are screwed: if they created automation data while that version was installed, as soon as they install the new version with this flag enabled (or the old version from way before this macro existed), their automation data will lead to higher values than they intended
I also noticed that just opening and saving a project with that recent version of my plugin installed does not modify the automation data (although the automation data values look lower in Logic Pro X), and these projects again show correct automation data values when the new fixed version with that flag enabled is installed, and the plugin parameter values are being automated correctly again.
Not sure how to break this news to the people who created automation data with that recent version of my plugin nowā¦