Just making a little kick drum VST, and have set it all up with the lovely new AudioProcessorValueTreeState class, and have connected my UI with AudioProcessorValueTreeState::SliderAttachment classes.
…And that all works nice and well. State of the sliders is saved in the host, and recalled fine when reloading.
But i’m getting stuck with this:
I want to update the ValueTreeState and also the pitch slider, whenever a midi note is entered.
Here’s what my processBlock looks like:
MidiMessage msg;
int ignore;
for (MidiBuffer::Iterator it (midiMessages); it.getNextEvent (msg, ignore);)
{
if (msg.isNoteOn())
{
mainValueTree->state.setProperty ("Kick_pitch", msg.getNoteNumber() / 127.0f, nullptr);
kickSynth.trigger();
}
}
the kickSynth.trigger() function is working fine, so it seems highly unlikely i have an error in midi handling… but i was really hoping that calling setProperty on the tree would just “work” in this case, and unfortunately it doesn’t.
as i said, i have set up my sliderAttachments correctly, as the getStateInformation and setStateInformation functions in my processor are working fine.
so why isn’t the setProperty function updating my slidersAttachments?
Unfortunately the Attachments work only for parameters. They are not designed for arbitrary properties, afaik.
In this case I think you need to add a ValueTree::Listener on the public accessible state of the AudioProcessorValueTreeState.
There you get the callback from the property change and call Slider::setValue() by hand.
HTH
state of the sliders seems to save fine, and yes, they do update when i change the value tree. awesome.
only thing i have to sort out now, is that my synth was an AudioProcessorValueTreeState::Listener, so i guess i’ll have to change that and make it listen directly to the value tree too, yeah?
would there be any problem to include this code directly into the AudioProcessorValueTreeState::SliderAttachment class?
as far as i can see, if they don’t give each other issues, and they both use basically the same arguments , then this would be a pretty cool and handy addition
Just added the attachment class to github as module
And added two more attachment classes, one for ComboBox (working) and one for a RadioButtonGroup (in progress). If someone has a clever idea how to design the lookup between the radio buttons and the ValueTree, let me know.
Now I can cleanup my code as well a bit…
I think it should be kept separate. Every AudioProcessorValueTreeState is a ValueTree, but not vice versa. So why would one restrict the users from using the attachment on “normal” ValueTrees?
@jules: if you want to add that stuff, please go ahead. But you probably will rewrite most of it anyways
Never do any ValueTree (or other similar high-level work) in your audio thread!!
Also, why are you even trying to process the midi messages directly - our Synthesiser class would probably do this for you, as well as handling numerous nasty edge-cases that you won’t yet have banged your head against (but you will do!)…
@jules when you say don’t do any ValueTree work would it is safe to be reading a value from the state in the process block ?
Am I right in thinking it would just be bad practice to set a Value, particularly when a listener is attached to that value and the asynch update tiggering (or whatever is used internally) would be potentially blocking behaviour ?
No, don’t read a Value or ValueTree in your audio functions. It could involve allocation, and the message thread could be changing it while you’re reading it.
So if you’ve got your plugin Document/Preset/State in a ValueTree and need to read some value(s) from it in the audio thread, what should you do @jules ? Is that what CachedValue<> is for?
Does this also apply for the AudioProcessorValueTreeState getRawParameterValue function?
float* AudioProcessorValueTreeState::getRawParameterValue ( StringRef parameterID ) const noexcept
Returns a pointer to a floating point representation of a particular parameter which a
realtime process can read to find out its current value.
Is it safe to retrieve these values in the processBlock function as is done in the new AudioProcessorValueTreeState tutorial?
Getting raw parameter values should be safe as it doesn’t actually read from the internal ValueTree object.
When you pass in the paramID the AudioProcessorValueTreeState class/object gets the parameter from it’s owning processor via the usual OwnedArray of audio parameters which the AudioProcessorValueTreeState ::createAndAddParameter() method adds to under the hood.
So yeah calling *parameters.getRawParameterValue ("gain") * phase; on the callback thread should be safe.