The AudioProcessorListener is only notified, when a parameter is changed via AudioProcessorParameter::setValueNotifyingHost(). But if the host performes the automatization it calls setValue rather than setValueNotifyingHost (which makes perfect sense). But the listener doesn't get this changes notified.
Wouldn't it make sense to move the notification to setValue so that the listener gets every change?
That's because each wrapper (which is the gate between the Host and the AudioProcessor) is an AudioProcessorListener, therefore when an object that is an AudioProcessorListener calls setValue() it doesn't exactly want a callback to tell it the value has been set. Think of "setValueNotifyingHost" as actually being "setValueNotifyingListener".
I think to be honest you probablt shouldn't be using theAudioProcessorListener unless you are creating a new wrapper.
Yes, that's what I found out by looking at the sources. But it spoils the idea of the Listener class. And in my architectures I use the subject observer pattern a lot.
If Jules or respectively the juce team want to improve the usability of the listener there are two solutions:
- the sender of setValue adds it's "this" adress and is excluded from notifications
- the former value is known, so only send notifications if the value really has changed (it's already implemented like that)
The latter version can lead to problems, if the value is internally stored in an other format and if rounding errors occur...
Another idea would be an AudioProcessorParameterListener class, but this would make the functionality kind of redundant.
You might want to try the new AudioProcessorParameter helper classes, which let you attach lambdas for callbacks. Or AudioProcessorValueTreeState, which lets you manipulate the state via ValueTree callbacks and Values.
Thanks for the pointer to lambdas, I already read about it in the recent thread from Mike et al. But this is only an internal detail as I understand it. To create this callback I will have to override the AudioParameter* classes. Somebody told me recently to prefer aggregation over inheritance ;-) Especially because I will have to change it in all derrived classes. Not much DRI.
Or is there some api function where I can register a lambda, that I have overseen in AudioProcessorParameter?
The ValueStateTree is a nice thing though, I will play a little around with it to get accustomed. Seems like the AudioProcessorParameter class had a short life then ;-)
No - the AudioProcessorParameter class will be around for a long time.
The guidance on inheritance is not that it's a bad thing in all cases, but you should only use it only when you need to. The parameter class is deliberately designed for inheritance, and that's how other things like the utility classes and the ValueTree class actually work.
I think it's also fair to say that by using a correct approach with lambda callbacks you should be able to limit the number of derived parameter classes you are creating in the first place(fair enough you may need a few)? Your derived class can take in a std::function object in it's constructor and then use this generically for callbacks. Should be able to still adhere to the DRY principal with a bit of thought.
Personally I think the new parameter classes are actually pretty neat and flexible, they just need a little more thought/planning from a user's perspective to use as a base class.
I posted a quick but by no means perfect example in this thread.
...so do you plan to add an AudioProcessorParameterListener? It could IMHO happily coexist with the AudioProcessorListener notifying the host i.e. the wrapper and the AudioProcessorParameterListener notifying whatever I need like GUI widgets etc.?
I would love it...
No, I don't think it's something that's needed.
If for some reason you really, really do need a listener because you've got some strange use-case, then the whole point of the parameters being done with a class means that you can write your own sub-class that does have listeners, and use that.
Personally I think the new parameter classes are actually pretty neat and flexible, they just need a little more thought/planning from a user's to use as a base class.
So do I. My only problem is that the notifivation will take place in the setValue and would perfectly fit in the AudioProcessorParameter class, which is already base class to the very usefull AudioParameter[Float|Choice|Int|Bool] classes.
It's not much work, evaluation time is also linear. I don't see any obstacles, but I might not have the full overview.
With this approach you can even create a Slider+AudioProcessorParameterListener class representing the correct value with a default implementation, so no additional code needed except instanciation and addListener... wouldn't that be nice?
Ok, I understand.
One can't have everything. And the ValueTreeState has also some advantages, AudioProcessor::getStateInformation in one line of code is a nice feature...
Just reading http://www.juce.com/doc/classAudioProcessorValueTreeState_1_1SliderAttachment - that does what I need. Nice approach...
Do we still have these callbacks accessible somewhere? I can’t see them in the doc.