AudioProcessorValueTreeState Parameter Access Best Practices

I’m working on a plugin with gui controls that are more complex than typical sliders/buttons/etc. In particular, I want to add 2-axis sliders, and sliders that might control a variety of parameters at once. I want to make sure I handle parameters correctly. Here are a few points I haven’t been able to clarify via google/documentation/source code; I would love to get help on any :slight_smile:

  1. I’ve seen a variety of methods for accessing parameters from the Audio thread. In Tutorial: Saving and loading your plug-in state we save the std::atomic* returned by getRawParameterValue(paramId) and dereference the value when needed. Is that the current best practice?

  2. Is it safe to register an AudioProcessorValueTreeState::Listener on the audio thread? Or do I need to use a conditional if(*paramPointer != previousParam) {...} to safely respond to parameter changes?

  3. Can I safely access parameters (for example by dereferencing the getRawParameterValue() pointer, as in q.1) from the GUI thread? This way I could rely on the APVTS as my app’s “single source of truth” instead of creating a separate, identical gui state that is updated upon parameterChanged()

  4. To allow the custom gui elements to interface with the APVTS it seems like I’m going to need to re-implement the functionality found in AttachedControlBase (juce_AudioProcessorValueTreeState.cpp). Is that the best approach? Or am I missing an easier way?