I would like to know how do you deal with parameters that have a list of choices. Currently, I’m treating those like any other parameter, but if I end up to add more options in an update, the entire 0-1 mapping is inevitably changed.
Example: having a list of 10 choices named “TYPE”, we get that each entry starts from 0 and increments by 0.11 (1.0 / N-1). If I add 2 more choices, we’ll have a list of 12 elements and now these values will be translated with an increment of 0.091.
In this case, I check if the preset version matches the current plugin version and adapt the mapping, but it’s cumbersome and not the very best way to do that. I could add a sort of UID to each list entry and store that instead of the 0-1 value and manage the mapping later, but that won’t work if a user automated that parameter change, since parameter automations are stored as 0-1 values.
A couple of workarounds that jumps in my mind would be either store the last UID as a session var or preallocate N values for the list, even if I’m not using all of them (set the parameter to have 255 values, use 10). Both of them are definitely ugly.
This problem has to do with automation in general. Imagine that you change the range of some DSP filter in a product update, then any automation from an old session will break, it will sound different. My suggestion is to simply not change the ranges or choices. I like that @valhalladsp clearly mentions on his website that once a product is released, it will not change and (nearly) no features will be added. Support - Valhalla DSP
I think if I really have to change the range then maybe I would make it a new parameter (change the ID) so that old automation data is ignored.
To just convert the state, you can write conversion functions, make sure to add the version number of the product in the state so you can easily detect from what version to convert.
Thanks, but @valhalladsp also have similar situations, since he added new algorithms to existing products. I’d find very bad, nowdays, to keep new features away from a product just become we can’t handle that. Changing the parameter ID is a no-go for users, especially if they won’t be able to recall old projects and lost automations. This would be very bad for a brand reputation.
I already have range converters in my existing products but, as said, I find this approach quite ugly. I believe that a better way to handle that exists, but I’m struggling to find one that will be manageable in the long term.
The only clean way to add more choices, is to add more parameters to your product, or use non-automatable data (which is only saved in your state; not as a “parameter”), but you will loose backwards compatibility anyway.
I guess I’ll try the pre-allocated steps way. I tried in the past to make these parameters as not automatable, ending up in several support tickets asking why they weren’t able to automate them -_-
I’ve allocated more “slots” in parts of my plugins, by mapping the 0-1 range of a parameter to 12 or 24 slots, and then shipping with only a few of those filled. This allows me to add more modes over time. If I didn’t pre-reserve these slots when the plugin was launched, I can’t change this.
Another good idea, is to have several reserved parameters at the end of your parameter list. I did this with ValhallaDelay, which allowed me to add a new parameter to a later release without breaking any existing DAW projects.
My guess is that most DAWs are OK nowadays with adding a parameter to the end of a parameter list, but I haven’t verified this. In this case, you could add a second parameter that works with an existing parameter, to extend the range. Think of it as adding more “banks” or whatever. Your existing parameter might cover 10 choices, and the new parameter then adds 10 banks, with the first bank reserved for the existing 10 choices, and 90 more slots can open up this way.
Sorry to reopen this thread, but I’m hitting this right now and while I like the idea of preallocating more steps than I will currently use for a “choice” type parameter, how then do you deal with the control ranges? If my preallocated parameter range is {0.0, 24.0, 1.0}, but I’m only currently using 10 or so, then I have to have a special case for anything that uses that range. Any elegant way to deal with this?
I made my own parameter class from the base class, AudioProcessorParameter, and in there I just decided that the value I serialize with is not the normalized, but the denormalized one. that way I can change the range of a parameter after already having released the plugin and the presets people made still do the same thing, unless the values themselves now represent something different ofc. idk if apvts does the same thing tho. apparently not, or else there wouldn’t be so much confusion about this all the time. another good aspect about my selfmade parameter class is that it doesn’t even make a difference between bool, float or choice. it’s all float. that is mainly for modulation reasons btw, but i think i nice byproduct of that is that every part of the code, that does something with my parameters, uses the same methods, so it’s easy to keep track of what’s going on and whenever you load the denormalized value it represents exactly what you need in your dsp code anyway
If you use AudioProcessorValueTreeState, then it will automatically store the parameter values as non-normalised values in the ValueTree. The APVTS will store the index for a choice parameter in the ValueTree, e.g “0, 1, 2, 3”.
The challenge here is not serialisation, but automation. Parameters work under the hood with a range from 0 to 1, regardless of what the range is you convert it to. So a choice parameter with 3 choices is mapped to 0, 0.5, 1 and one with 4 choices is mapped to 0, 0.33, 0.66. So, for choice parameters, it makes sense to reserve a few extra choices to make the plug-in automation future compatible, as @valhalladsp suggested.
i understand this. but i also think it’s a bit of a made-up problem. i mean imagine you’re a pro mixing / mastering engineer. would you update your plugins mid-session? i think i’d first finish the current project and only then proceed with plugin updates to keep it safe. so automation not mapping to the same value as before due to it being normalized is a bit of an ignorable scenario, even though it’s real
If developers would prioritize backward compatibility, it could potentially encourage users to become more comfortable with frequent updates. Ultimately, as a developer, your goal is to have your users consistently use the latest version of your product.
Furthermore, certain DAW projects can have long lifespans in various contexts, like when they are used for live performances with DAWs such as Ableton, Mainstage, or Digital Performer. It’s important to avoid sudden project failures after several years of use in these situations.
ok, i wasn’t thinking about dj-orientated projects. but even then if i was planning to perform music i’d keep the number of active plugins to a minimum to reduce potential to failure. no one should just expect an extremely old project file to still work the same as when it was made