Chowdhury-DSP / chowdsp_utils

JUCE module with utilities for ChowDSP
Other
234 stars 24 forks source link

Extending ParamListeners to update ValueTree #554

Open davispolito opened 12 hours ago

davispolito commented 12 hours ago

Hi!

I have been working on developing this plugin which utilizes your plugin state and paramholder when creating audio processors that then get added into an audioprocessorgraph. I am only interested in using the paramholder/pluginstate concept for things that would be added into the audioporcessorgraph but want to use ValueTree elsewhere for concepts such as connections and other general state ideas. I would like to be able to mix the two easily so that serializing to xml can be as simple as serializing the overall valuetree. Since your connection btwn processor and UI appears more thread safe and has the nice ability to declare where messages are broadcast.

I had originally thought that I would do this by modifying your serializing functions to serialize xml similar to the way the valuetree does with params as properties, but there isn't a seemless way to get the valuetree::toXML function to know that it should add the processor serializing to this.

My new idea is to just write to the ValueTree whenever a parameter changes. I can't quite tell where the best place to add this would be. I could simply add a ParameterListener that triggers on the MessageThread but that I'm lazy/forgetful and that has overhead of remembering to add that whenever I add a new parameter. I think if I override the ValueChanged() callback for the ParameterTypes to write to a ValueTreeProperty this could accomplish that? I plan to eventually be able to modulate params with LFOs etc. so wouldn't want that to update the valuetree value whenever its modulated... I think that's safe to do with the modparameter mixin concept since that doesn't update the value of the audioparam and would trigger the value changed.. value changed would really only trigger when the Attachment calls the Callback which does the setValue call...

Does this seem like a good/safe idea? Figured you might have considered this idea before

sidenote: This wouldn't handle deserializing back to the paramholders though. This could probably be solved with some sort of ValueTree listener although I wouldn't want it to trigger whenever I am doing general writing so It'd probably have to listen to the load function rather than the valuetree itself... This wouldn't handle deserializing back to the paramholders though. This could probably be solved with some sort of ValueTree listener although I wouldn't want it to trigger whenever I am doing general writing so It'd probably have to listen to the load function rather than the valuetree itself...

davispolito commented 11 hours ago

or perhaps just doing the addParameterListener in the ParamterAttachment class. I guess I'll run into undo manager complications with any of these ideas as well

jatinchowdhury18 commented 10 hours ago

Hmmm, this is a good question. In general, I'm not sure how compatible my system is with juce::ValueTreeState. That said, if chowdsp::PluginState is only being used for the "internal" processors, which are then managed by a more "global" value tree, then I would try to de-couple the two as much as possible.

What I would recommend is to serialize the state of a chowdsp::PluginState object to JSON, then convert that JSON to a string, and add it to the ValueTree. You might need to store some additional information as well (for example which processor type did this JSON come from), so that the state(s) can be de-serialized correctly. The additional information could either be added on the JSON side, or the Value Tree side (your choice).

Then the only question would be figuring out when to re-save the state for each internal processor. If you want to do this on every parameter change, then that could be triggered from a "regular" parameter listener in the chowdsp::PluginState. That said, I imagine it might be simpler to only save the processor state when you need to do a more "global" save operation.

Anyway, I hope this idea is helpful, please let me know if I've mis-understood any parts of your use-case. I would also suggest trying out some alternatives to the Value Tree for storing the audio graph state as well... Value Tree might be the best choice, but it's possible that there could be something simpler that works well for your use-case.