Modular plugin... getting started

Hi,

I want to write a modular plugin for audio/midi processing by internal interconnected processing units (modules).

I read few topics on forum about modular approach...

So in case of newly created plugin project, I need to replace MyDefaultAudioProcessor to inherit from AudioProcessorGraph instead?

And to have my processing units (modules) to inherit from AudioProcessor which I will then add as nodes to MyDefaultAudioProcessor?

 

Thanks a lot! smiley

1 Like

I would rather use an AudioProcessorGraph as member (use a ScopedPointer obviously) which is manually processed in the base MyDefaultAudioProcessor's processBlock method.

And to have my processing units (modules) to inherit from AudioProcessor which I will then add as nodes to MyDefaultAudioProcessor?

Yes, that should work.

I would rather use an AudioProcessorGraph as member (use a ScopedPointer obviously) which is manually processed in the base MyDefaultAudioProcessor's processBlock method.

Can you explaine why would you use AudioProcessorGraph (which is inhereted from AudioProcessor as well) as member of AudioProcessor derived MyDefaultAudioProcessor class?

Yes, that should work.

So basically writing processing modules is the same as writing a plugin? So for each module I should have ModuleProcessor.h/cpp (for actual processing) and ModuleEditor.h/cpp (for GUI)? 

I can't exactly remember, but I tried to use an AudioProcessorGraph as base class and ended up with the suggested solution (I think I didn't got the Audio-I/O nodes working).

But in general I think this is a case of composition vs inheritance (but someone with a more profound C++ knowledge can expand this).

So basically writing processing modules is the same as writing a plugin?

Yes, but I wouldn't create a PluginEditor for each component, but think of a system to access all parameters from one Editor (the main MyDefaultAudioProcessorEditor). Otherwise you will end up with a LOT of pop up windows...

I can't exactly remember, but I tried to use an AudioProcessorGraph as base class and ended up with the suggested solution (I think I didn't got the Audio-I/O nodes working).

Can't see any problem using AudioProcessorGraph as a base class of a plugin. Seems to work fine.

a system to access all parameters from one Editor (the main MyDefaultAudioProcessorEditor). 

I can hardly imagen what that system should be... Can you explain this?

Otherwise you will end up with a LOT of pop up windows...

Same as in Juce Host Demo? (pop-up window for every AudioProcessorEditor)

It's not bad actually, but maybe a kind of master-detail GUI layout would be preferable. Where a graph panel will display all involved AudioProcessors and a detail panel that will show currenly selected AudioProcessorEditor.

But I have no clue how to arrange it in JUCE. sad

1 Like

Can't see any problem using AudioProcessorGraph as a base class of a plugin. Seems to work fine.

Ok, nice to hear, maybe I will try it again another time.

But I have no clue how to arrange it in JUCE. 

This should be no problem. make sure that the AudioProcessor doesn't rely on the Editor (it shouldn't anyway) and delete and create the editor of the selected AudioProcessor().

You can start with something like this:

ScopedPointer<AudioProcessorEditor> selectedEditor;
ScopedPointer<Component> selectedEditorComponent; // this is the component which holds the selected editor

void processorSelected(Processor *p)
{
    selectedEditorComponent->addAndMakeVisible(detailEditor = p->createEditor());
}

This code is a mess regarding object ownership (in the destructor of the base class hell might break loose), but you should see what I mean.

 

Thanks, chrisboy2000!

I'll try your aproach.

I'm currently examing JUCE Plugin Host Demo. It's plugins hosting is a bit overwhelmed comparing to my task... trying to figure out which parts of it can be useful in my situation.

Not an easy task for a newbie like me. indecision

Here is a screens of GUI layout I want to achive in my plugin:

The plugin is separated into 2 panels, Global Panel (which is always visible) and an Upper Panel which has 2 views, depending on a switch button (Routing/Modules).

View 1 - Routing Matrix (Probably needs AudioProcessorGraph class to implement. What else?)

View 2 - Modules Details (Probably needs some sort of scrollable list Component to hold modules Components. Else?)

 

What JUCE classes I need to use to achive this organization?

It will help me a lot!!! 

Routing Matrix (Probably needs AudioProcessorGraph class to implement. What else?)

There is no ready-made class for this in the API. You have to hack the plugin host demo. Its source files GraphEditorPanel.cpp / .h should contain everything you need, so I suggest you start there. 

scrollable list Component to hold modules 

These are classes that handle this kind of functionality, so pick the one you like most:

Listbox

Viewport

ConcertinaPanel

However, I would not display multiple modules at once, but only the selected (and toss the concept of two panels), but I think here it comes down to taste.

There is no ready-made class for this in the API. You have to hack the plugin host demo. Its source files GraphEditorPanel.cpp / .h should contain everything you need, so I suggest you start there. 

Ok! yes

These are classes that handle this kind of functionality, so pick the one you like most:

Listbox

Viewport

ConcertinaPanel

Thanks! I'll look at them more closly.

However, I would not display multiple modules at once, but only the selected (and toss the concept of two panels), but I think here it comes down to taste.

That was my first idea as well, but then decided to switch to have 2 views.

Now I'm thinking that tabbedComponent will be better than a switch view button...

Need help.

I have GraphPanel and FilterGraph. FilterGraph contains the processors that will do some midi stuff. As plugin template suppose, I have a PluginProcessor with PluginEditor as well. Now the host will call PluginProcessors' processBlock() but the actual processing is done in FilterGraph's processors. How do I connect them?