AudioProcessorGraph question


#1

SOLVED: see my solution below… :mrgreen:

How can I handle a parameter that has changed in a AudioProcessorGraph node, to tell the host that something changed? Therefore, making automation work.

Its like this, we have the AudioProcessorGraph graph, which holds up to 16 loaded plugins. (VSTs on my case) If you move a parameter in any of those “child” VSTs, what happens inside the graph class? How can I handle this, so I can tell the host some automation occurred?

I posted this too in the other area, but I though I should re-write it here too. :wink:

Thanks, Wk


#2

Well, some sort of listener/broadcaster model, I guess. Though it’ll be challenging to make one that works on the audio thread, you’d need to have some sort of external class that checks it for updates and does the broadcast, maybe using a Timer.


#3

Actually, it looks like AudioProcessorListener would do the trick, as it does get called when the child VST parameter is moved on the GUI.

The only problem is, that I can’t seem to be able to create a new class that derivatives from it. :frowning:

c:\work\___current projects__\wusik juce projects\juce\extras\__wusik station x\demo\src\FilterComponent.h(92) : error C2259: 'juce::AudioProcessorListener' : cannot instantiate abstract class due to following members: 'void juce::AudioProcessorListener::audioProcessorParameterChanged(juce::AudioProcessor *,int,float)' : is abstract c:\work\___current projects__\wusik juce projects\juce\extras\__wusik station x\demo\src\../../../../juce_amalgamated.h(17096) : see declaration of 'juce::AudioProcessorListener::audioProcessorParameterChanged' 'void juce::AudioProcessorListener::audioProcessorChanged(juce::AudioProcessor *)' : is abstract c:\work\___current projects__\wusik juce projects\juce\extras\__wusik station x\demo\src\../../../../juce_amalgamated.h(17100) : see declaration of 'juce::AudioProcessorListener::audioProcessorChanged'

If I could create a class, and add the listener to each child VST, I could them process things up and it will all be good. :mrgreen:

This is what I’m trying to do:

[code]class JUCE_API AudioProcessorListenerEx : public AudioProcessorListener
{
public:
AudioProcessorListenerEx(int aindexN, void* afilter);

virtual void audioProcessorParameterChanged (AudioProcessor* processor,
											 int parameterIndex,
											 float newValue);

// Variables //
int indexN;
void* filter;

};[/code]

The indexN tells me the number of the VST in my 16 VSTs list. The filter variable is just a copy of my filter’s plugin.

Them I could just add on the filter AudioProcessorListenerEx plugsListeners[16]; but sadly, it won’t work, shows me the error above…


#4

Actually, the following compiles without problems. :oops:

[code]class JUCE_API AudioProcessorListenerEx : public AudioProcessorListener
{
public:
virtual void audioProcessorChanged (AudioProcessor* processor);

virtual void audioProcessorParameterChanged (AudioProcessor* processor,
											 int parameterIndex,
											 float newValue);

// Variables //
int indexN;
void* filter;

};[/code]


#5

YES! IT WORKS! :mrgreen: 8)

Let me post my complete solution, hang on…


#6

First, since all my VST childs are fixed, I know the number of parameters each one takes, 2000 parameters.

int FilterComponent::getNumParameters() { return 2000 * 6; }

So for each child VST, I know how to handle parameters into the graph.

void FilterComponent::setParameter (int index, float newValue) { int index2 = index - ((index/2000) * 2000); graph.WgetByIndex(index/2000)->setParameter (index2, newValue); }

Inside my graph class, I did some new calls, the WgetByIndex is one of those. It holds a list of 16 nodes, the child VSTs.


#7

Now, in my filter’s class, I added AudioProcessorListenerEx plugsListen[16];

And I handle it like this in the filter’s constructor:

for (int x=0; x<16; x++) { plugsListen[x].indexN = x; plugsListen[x].filter = (void*)this; } MainInstance->addListener(&plugsListen[0]);

And this takes care of the automation:

void AudioProcessorListenerEx::audioProcessorParameterChanged (AudioProcessor* processor, int parameterIndex, float newValue) { ((FilterComponent*)filter)->setParameterNotifyingHost(parameterIndex+(indexN*2000),newValue); }

I tested with Orion, and its working. :mrgreen: