How to #2 add an analyzer

You can add visualisations to PluginGuiMagic. All analysis and rendering is already implemented, you only need to declare, which signal in your dsp you want to visualise.

To add for instance an analyser, you add a foleys::MagicPlotSource pointer to the processor:

foleys::MagicPlotSource*  outputAnalyser = nullptr;

In the processor constructor you create and advertise the analyser to the GUI:

outputAnalyser  = magicState.createAndAddObject<foleys::MagicAnalyser>("output");
magicState.addBackgroundProcessing (outputAnalyser);

(Only some visualisations need the background processing, but if it is not needed, this is silently ignored.)

Now you only need to push the signal to the analyser in your dsp code, most likely processBlock():

// assuming you have an AudioBuffer<float> buffer
outputAnalyser->pushSamples (buffer);

Now you are ready to add the plot to the GUI:
Simply drag a Plot into a View and select the name you gave the analyser in the creation call as source:

Hint: to overlay several Plot curves select “content” as display method in the parent View. You find that property in the “Container” section.

Now you should be able to see the analyser curve once you run the plugin.

So how would you add a meter? Currently, all controls come into PGM from Faust as sliders, even bargraphs. I can add a meter but I can’t select anything to assign to it, which makes me think that I need to add this stuff in the code, which is fine, but the classes don’t match up between level meter and analyzer, so I’m having trouble figuring out the combination that works properly for a meter.

In my processor class:

    foleys::MagicLevelSource* LFOLevel = nullptr;

In the constructor:

    LFOLevel = magicState.createAndAddObject<foleys::MagicLevelSource>("LFOLevel");
    magicState.addBackgroundProcessing(LFOLevel);

Then I get:

Thanks,

DL

OK I took out this line and it compiled anyway. I think you mentioned that somewhere.

//    magicState.addBackgroundProcessing(LFOLevel);

Sure, the MagicPlotSource is meant for graphs like the analyzer etc.
The LevelMeter has it’s own counterpart which is the LevelMeterSource.
It is quite similar to the PlotSource, you push the buffer you want to measure into the LevelMeterSource. The LevelMeter has a selection box where all LevelMeterSources are listed.

There is an example in the EqualizerExample, the setup is here this single line:

And in prepareToPlay, so it knows the number of channels:

About the error above: The LevelMeterSource doesn’t have a background process.
In fact the createAndAddObject would take care of it, if it was a MagicPlotSource.

1 Like

In my processor:

    foleys::MagicLevelSource* LFOLevel = nullptr;

In the constructor:

    LFOLevel = magicState.createAndAddObject<foleys::MagicLevelSource>("LFOLevel");

This is in my prepareToPlay():

    magicState.prepareToPlay(sampleRate, samplesPerBlock);
    LFOLevel->setupSource(1, sampleRate, 500, 200);

And this is what it looks like:

image

There’s a white box with a green line on the bottom. I don’t see anything happening. It strikes me that there’s no connection to a specific signal… I’m not just using the block outputs.

Yeah, sorry… missing this part.

1 Like

Glad you found it.

BTW. the simple bar is not particularly beautiful, a LookAndFeel interface to create different level meters is on the road map.

I got it to work but it is only listening to the block output. How do I hook it to an internal signal in my program? In Faust I can put a bar graph readout in any signal line. If I leave it as created in PGM by default (a slider) then the slider moves as my LFO does its thing. So I just want to replace the slider with a meter.

image

Another thing about the Faust code generator is that it creates processBlock() with <double> also:

but if you add the line in the second one you’ll get a compilation error.

Thank you for the heads up. I will add a function that accepts an juce::AudioBuffer<double>&.

As for the question about displaying a different signal, that is difficult. How would it know what to measure?
Normally you have the different commands and loops in the processBlock() so you can measure anywhere, but in this case you can only measure before and after the processBlock().
Is there an API to get information out from the faust dsp?

Here’s how it’s apparently done in Faust generated C++.

	FAUSTFLOAT fHbargraph1;

In buildUserInterface():

		ui_interface->declare(&fHbargraph1, "01", "");
		ui_interface->addHorizontalBargraph("LFO", &fHbargraph1, 0.0f, 1.0f);

Then, the variable is just part of the dsp “compute” function.

...
			fHbargraph1 = FAUSTFLOAT(fRec18[0]);
			float fTemp22 = ((fRec17[0] * fHbargraph1) + 1.0f);
...

Looks like some special case code generation?

	#define FAUST_LIST_PASSIVES(p) \
		p(HORIZONTALBARGRAPH, LFO, "[00]/LFO", fHbargraph1, 0.0, 0.0f, 1.0f, 0.0) \
		p(HORIZONTALBARGRAPH, Level, "[00]Low/Level", fHbargraph0, 0.0, -80.0f, 1.0f, 0.0) \
		p(HORIZONTALBARGRAPH, Level, "[01]Hi/Level", fHbargraph2, 0.0, -80.0f, 1.0f, 0.0) \

Anyway, it looks like things are arranged such that the UI has full visibility of the DSP’s internal details. For the level meter at least, we just need a single value, not a block of data.

I just need something that behaves like a slider but looks like a level meter.