and the AudioProcessorParameter needs to refer to the ControllableProcessorBase instead of an AudioProcessor. There are more but solvable threads to pursue into the various classes.
One thing is GenericAudioProcessorEditor uses the LegacyParameters. I would rewrite that to use the current interface and as a side benefit to support ParameterGroups.
A few design decisions:
I already wrote a patch to template AudioProcessorValueTreeState as template<class ProcessorType> ProcessorValueTreeState<ProcessorType> and using AudioProcessorValueTreeState = ProcessorValueTreeState<AudioProcessor>;
Alternatively we can add the ControllableProcessorBase as described above
if we do that, should we move all parameter handling and ownership to the base class or use it only as an interface?
The AudioProcessorListener needs some adaption, is this still used? And if so, should we change the signature to send a ControllableProcessorBase* pointer?
It would be great to open the possibilities of JUCE towards additional pipelines.
Hope it fall âon benevolent eyesâ, let me know, if it needs changesâŠ
In order to control other Processors in a processing pipeline, a separate interface is needed, so the AudioProcessorParameters, the AudioProcessorValueTreeState and the GenericAudioProcessorEditor can be used. A use case is e.g. a VideoProcessor in a NLE.
This PR adds this base ControllableProcessorBase and moves all addParameter etc. functionality into this base.
The AudioProcessorParameter was changed to use the interface of ControllableProcessorBase instead of AudioProcessor.
The GenericAudioProcessorEditor uses the LegacyAudioParameter and the AudioProcessorListener, so it remains unchanged (but intact of course). A new GenericProcessorEditor will be added later, that will only use the new interface of AudioProcessorParameter and AudioParameterGroup as well.
If wished, the names AudioProcessorParameter and AudioProcessorValueTreeState could be changed for consistency to ProcessorParameter and ProcessorValueTreeState and an alias provided with the old names.
Disclaimer: all copyright of this PR is hereby waived to JUCE and its legal owners.
I donât think ControllableProcessorBase is the way to go here.
It certainly achieves what you want, but adding more complexity to an already overburdened class wouldnât be an overall improvement to the API. The default response to this objection is something along the lines of âBut this takes functionality out of AudioProcessor!â, which is true, but at the cost of additional layers of inheritance all over the place. Youâve managed to take the âAudioâ out of âAudioProcessorâ, but for consistency weâd need to do the same for AudioProcessorParameter, AudioProcessorParameterGroup, AudioProcessorListener, AudioProcessorEditor and maybe a few others that Iâve missed. Using inheritance like youâve done is the only way I can see to do this without breaking everyoneâs code (AudioProcessor is probably the root of most JUCE apps), but the complexity overhead is just too great. Renaming and aliasing doesnât provide an easy answer here - an example would be that AudioProcessorParameter can have a category of compressorLimiterGainReductionMeter which isnât generic enough for a ProcessorParameter class.
The other approach to this is thinking about how to make the AudioProcessorValueTreeState and the various ::*Attachment classes more generic. If these sat on top of a more general wrapper around a ValueTree and a ParameterGroup then you could perhaps dispense with the AudioProcessor class entirely and use your own structure created using composition. Youâre still likely to run into naming problems, with âAudioâ sprinkled everywhere` but it would, perhaps, be a much less invasive set of changes.
Thank you for your feedback. I am aware, that not many people will need any processor other than AudioProcessor, thatâs why I was hesitant to do the refactoring in the first place. But one day, people want to control other processors as well, and I think my video engine is not very far fetched, regardless who does itâŠ
My first approach was indeed to template the AudioProcessorValueTreeState. Iâll attach the patch here. patch_template_APVTS.txt (35.9 KB)
Otherwise I will have to create my own parameter classes just to achieve the very same thing, which would be very sadâŠ
BTW. I donât mind doing the extra work of removing the Audio from the Parameter classes and adding using-aliasesâŠ
Itâs not as simple as using aliases; the classes I mentioned above have built-in audio-ness that make them unsuitable for generic use, like a category of compressorLimiterGainReductionMeter.
I agree that it would be lovely to have all the parameter controls separate from anything audio related, but I canât see a way of doing this without making a huge mess.
And what does that mean for JUCE? Will the AudioProcessor and things be deprecated by Soul? I didnât think soâŠ
Ok, I see, if I can come up with a polymorphic adapter to wrap around the different processors, and create my own four parameter classes⊠will be another good days work sigh
I worked around this now by writing a polymorphic adapter class and re-implementing my own ProcessorParameter and ProcessorParameterValueTreeState (but with a shorter name)âŠ
Do you want to keep the PR for future reference or shall I delete it?
Whilst itâs certainly a decent chunk of boilerplate, if we did decide to go that route then we would take the same approach and could get ourselves to the same endpoint without too much trouble. Without a significant shift in direction the PR will just sit there forever.
The JUCE team certainly appreciates your efforts, but this one is not going to make it into the API.