Okay - so I’ve been thinking about thread-safety of APVTS in the bath. How does this sound for a strategy … critique welcome…
setStateInformation()
Check to see if we are on the message thread. If so import the data, otherwise push the received data into a queue, trigger an event to handle it on the message thread and wait for that work to complete before returning.
getStateInformation()
Maintain a copy of the ValueTree (updated via a ValueTree::Listener or ValueTreeSynchronizer?), protected with a lock, that’s then possible to convert the copy to XML and return as a blob without threading issues and without having to wrap the main ValueTree in some kind of lock.
Parameter listeners
The current listeners seem to be called on any old thread. I.e. whatever thread the host decides to call setValue from. Instead these could be called asynchronously on the message thread by hooking into a ValueTree::Listener.
Non-parameter information
This is about how to get information, attached to the APVTS::state ValueTree from the to the audio thread safely. E.g. settings that you don’t want to expose as parameters but which control aspects of processing. I need to have a think about this still, but some kind of interface that looks like the interface for getting parameters but returns something like a thread safe CachedValue.
Little things…
The AudioProcessorValueTreeState uses juce::Atomic which includes a full memory fence can this just use std::atomic::store with std::memory_order_release, which should mean that the parameter is definitely written before the flag is set.
Also, the tutorial obtains the float pointers to the parameter values in processBlock. These I’m guessing would be better as member variables, as otherwise there’s quite a bit of looking stuff up with string comparisons (CharacterFunction::compare is hardly a pretty place to be).
Here’s a quick profile of our simple plugin with a few parameters following the pattern in the tutorial:
It would only get worse with lots of parameters with similar names…
Thoughts?
PS. I’ve not thought about this original problem: “If the parameter uses an interval, the quantized (stepped) values are stored internally. I think this is problematic, from a hosts perspective, it sets a certain float value, and gets a quantized value back.”