# How to #2 add an analyzer

**URL:** https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14
**Category:** PluginGuiMagic
**Created:** [20 September 2020 22:08 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14 "2020-09-20T22:08:21Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [20 September 2020 22:08 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/1 "2020-09-20T22:08:21Z")

</div>

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:

```auto
foleys::MagicPlotSource* outputAnalyser = nullptr;

```

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

```auto
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():

```auto
// 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:

 ![Select-source](https://forum2.foleysfinest.com/uploads/default/original/1X/c0c843c68a5c816e46c139c51a2f135ea656700e.png)

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.

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [20 September 2020 22:12 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/2 "2020-09-20T22:12:51Z")

</div>



---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 16:16 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/3 "2021-06-30T16:16:41Z")

</div>

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:

```auto
    foleys::MagicLevelSource* LFOLevel = nullptr;

```

In the constructor:

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

```

Then I get:  
 ![image](https://forum2.foleysfinest.com/uploads/default/original/1X/4fbe6d430e7efb0822182edf74faa2ea1655e446.png)

Thanks,

DL

---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 16:27 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/4 "2021-06-30T16:27:16Z")

</div>

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

```auto
// magicState.addBackgroundProcessing(LFOLevel);

```

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [30 June 2021 16:28 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/5 "2021-06-30T16:28:15Z")

</div>

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:

> <https://github.com/ffAudio/PluginGuiMagic/blob/main/examples/EqualizerExample/Source/PluginProcessor.cpp#L168>

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

> <https://github.com/ffAudio/PluginGuiMagic/blob/main/examples/EqualizerExample/Source/PluginProcessor.cpp#L198>

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.

---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 16:52 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/6 "2021-06-30T16:52:07Z")

</div>

In my processor:

```auto
    foleys::MagicLevelSource* LFOLevel = nullptr;

```

In the constructor:

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

```

This is in my prepareToPlay():

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

```

And this is what it looks like:

 ![image](https://forum2.foleysfinest.com/uploads/default/original/1X/ab53959b93bd005f558cb18e156c031aa83d180d.png)

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.

 ![image](https://forum2.foleysfinest.com/uploads/default/original/1X/6b2db755019af4748b929b3fef84d8b3e4f63fdc.png)

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [30 June 2021 17:13 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/7 "2021-06-30T17:13:46Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 18:11 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/8 "2021-06-30T18:11:26Z")

</div>

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](https://forum2.foleysfinest.com/uploads/default/original/1X/8d1691a896691fe1845e92e0f1e71294d4326acd.png)

---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 18:39 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/9 "2021-06-30T18:39:39Z")

</div>

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

 ![image](https://forum2.foleysfinest.com/uploads/default/original/1X/e9b4174c54364701fa4eacebf26c5ddf8e819013.png)

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

---

<div class="post-metadata">

### Author: ![daniel](https://forum.foleysfinest.com/user_avatar/forum.foleysfinest.com/daniel/32/5_2.png) [@daniel](https://forum.foleysfinest.com/u/daniel)
#### Post date: [30 June 2021 19:58 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/10 "2021-06-30T19:58:05Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![Digital\_Larry](https://forum.foleysfinest.com/letter_avatar_proxy/v4/letter/d/bb73d2/32.png) [@Digital\_Larry](https://forum.foleysfinest.com/u/Digital_Larry)
#### Post date: [30 June 2021 20:11 UTC](https://forum.foleysfinest.com/t/how-to-2-add-an-analyzer/14/11 "2021-06-30T20:11:36Z")

</div>

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

```auto
	FAUSTFLOAT fHbargraph1;

```

In buildUserInterface():

```auto
		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.

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

```

Looks like some special case code generation?

```auto
	#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.
