Having some confusion with PGM

Hi @daniel

I am working with @sletz to try to streamline some of the process of going from Faust to Juce to PGM.

I am able to view the controls in the editor and I can change them. I am able to save the xml file. The xml file contents appear to make sense relative to the changes I made.

However, when I load the xml file, I just see the default layout again.

Also, it is not clear to me what the “Edit” button does. At one point when the canvas was blank it turned it all orange, but I couldn’t figure out what that means or how to make it happen again.

Any suggestions?

Here is a “grep” of all “magic” in the Faust CPP. One thing to note is that Faust puts everything into a single CPP file so it’s not straightforward, e.g. to delete the PluginEditor.cpp and .h.

};

#endif

// Using the PluginGuiMagic project (https://foleysfinest.com/developer/pluginguimagic/)

#if defined(PLUGIN_MAGIC)

class FaustPlugInAudioProcessor : public foleys::MagicProcessor, private juce::Timer
{

public:
juce::AudioProcessorValueTreeState treeState{ *this, nullptr };
FaustPlugInAudioProcessor();
 

JuceGUI fJuceGUI;

};

#ifndef PLUGIN_MAGIC
FaustPlugInAudioProcessor::FaustPlugInAudioProcessor()
: juce::AudioProcessor (getBusesProperties()), fParameterUI(this)
#else
FaustPlugInAudioProcessor::FaustPlugInAudioProcessor()
: foleys::MagicProcessor (getBusesProperties()), fParameterUI(this)
#endif
{
bool midi_sync = false;
int nvoices = 0;

mydsp* tmp_dsp = new mydsp();
MidiMeta::analyse(tmp_dsp, midi_sync, nvoices);
delete tmp_dsp;

#ifdef PLUGIN_MAGIC
auto defaultGUI = magicState.createDefaultGUITree();
magicState.setGuiValueTree(defaultGUI);
#endif

#ifdef JUCE_POLY
assert(nvoices > 0);
fSynth = std::make_unique<FaustSynthesiser>();
 
(FAUSTFLOAT**)buffer.getArrayOfWritePointers());
#endif
}

//==============================================================================
#ifndef PLUGIN_MAGIC
bool FaustPlugInAudioProcessor::hasEditor() const
{
return true;
}

juce::AudioProcessorEditor* FaustPlugInAudioProcessor::createEditor()
{
// You add the XML into BinaryData later. At the beginning just leave those
// arguments out and you get a default generated editor.
return new foleys::MagicPluginEditor(magicState, BinaryData::magic_xml, BinaryData::magic_xmlSize);
// return new FaustPlugInAudioProcessorEditor (*this);
}

//==============================================================================
void FaustPlugInAudioProcessor::getStateInformation (juce::MemoryBlock& destData)

Problem #1, eek, I left out the magicState…

image

Will continue to debug.

Ok I start with the easy ones:

The edit button toggles an edit mode. Normally the ProcessorEditor reacts normal and you can control your plugin. When you activate the edit mode, you can edit the controls inside the ProcessorEditor:

  • clicking a control will select it in the DOM tree, so you can start edit the values in the toolbox
  • You can drag controls around to reorder them. It is a bit tricky, basically it will insert before the control you are dropping to
  • You can resize the control or move them, if the display mode (sorry, it’s a CSS term) of the enclosing container View is set to Contents and not to FlexBox.
    The values are in pixels, unless you edit it to e.g. 50%. From then on it will be relative.

Regarding your PS: don’t add your own magicState. This is no longer necessary and in fact will hide the instance already present in the base class (foleys::MagicProcessor)
And btw. you are free to use the juce::AudioProcessorValueTreeState or not. PGM uses the interface of juce::AudioProcessor (i.e. getParameterTree()).

And make sure to set FOLEYS_SAVE_EDITED_GUI_IN_PLUGIN_STATE=0 in the module settings, as discussed previously. I will remove that option in the next release. It does more harm than good.

As for the faust code: is it possible to set a different base class instead of juce::AudioProcessor?
Then you would only need to remove the overrides that hinder the PGM, i.e.

  • createEditor()
  • hasEditor() // though it’s identical
  • setStateInformation:
    it’s fine to use the faust generated one, you would miss out on a few features like the persistent properties in the ValueTree that you can control from the GUI
  • getInformation (see above)

To bake the changed XML into the binaryData you have to re-save the project in projucer, so that the BinaryData.cpp is regenerated.

Please let me know if those changes also solve the issue that you cannot load the xml file.

OK thanks.

I confirm that with my own magicState removed (the “Problem #1” I put up there) that I get the view again.

Regarding edit on/off, I also see how that works now. Previously, I had enabled the edit mode and picked up a slider by the handle, and you can drag it around but it does not turn orange and nothing happens when you release it. That is to say, it just goes back to where it was.

I’ll review the rest of it. It’s still all sinking in. :grinning: :grinning:

Is there some way I can send you videos of what I am doing and what is happening?
a) Save XML works, but as far as I can tell, load XML does not.
b) I was moving things around, putting controls into a view, changing between FlexBox and Contents, etc. when suddenly a child “view” that had a few knobs in it disappeared from the panel.

It’s very hard to be able to show you what is going on without you actually seeing what I did. I don’t know exactly what I was doing when things seemed to go wrong. I can send you all of my code. Let me know if I could send you some screen capture videos via wetransfer or something like that.

Regarding the Faust->cpp->juce translation questions, I’m going to leave that to Stephane as I don’t really have an opinion on it. What I did this morning in that regard (conditional #ifdefs based on flags to the faust2juce script) seems to work as intended.

That is the normal behaviour if the Control is inside a FlexBox managed View. Only if there are multiple items in the View you can change the order :wink:
To place the Control manually select the parent View in the tree, unfold the “Container” section and switch FlexBox to Contents.

BTW. you can resize the sections in the toolbox, there are movable splitters between the tree, properties and components palette.

It helps to set it to “View…Detached” so that you can stretch it out. Otherwise it stays the same size as the plugin UI, which I can live with.

OK I think I am narrowing down the issue. I will start with some recommendations about the information presented here.

The #1 How to get started document from September 2020 is obsolete so it should be unpinned.

It should have an entry at the top indicating that it is out of date and a link to the correct doc (which should be pinned). I haven’t got as far as #2 or #3 pinned doc so I don’t know if those need an update also.

I am pretty sure the problem gets down to this section.

FaustPlugInAudioProcessor::FaustPlugInAudioProcessor()
: foleys::MagicProcessor (getBusesProperties()), fParameterUI(this)	
#endif
{
    bool midi_sync = false;
    int nvoices = 0;
    
    mydsp* tmp_dsp = new mydsp();
    MidiMeta::analyse(tmp_dsp, midi_sync, nvoices);
    delete tmp_dsp;
	
#ifdef PLUGIN_MAGIC
    auto defaultGUI = magicState.createDefaultGUITree();
    magicState.setGuiValueTree(defaultGUI);
#endif

I’m just loading the defaultGUI.

If I try to use this approach:

magicState.setGuiValueTree (BinaryData::magic_xml, BinaryData::magic_xmlSize);

I get something wrong with BinaryData.

image

If I try to build, this happens:

I’ll look at how this is handled in the example which I got running.

This declaration is found in my project and the SignalGenerator project.

namespace BinaryData {
using namespace BinaryDataFallbacks;
}

When I look for declarations of this in SignalGenerator, I get:

When I try to find the declaration in my own project, I get:

(nothing)

This is in the SignalGenerator solution:

image

This is in mine (same):

image

The “module page”… hmmm… where is that…

I don’t see FOLEYS_ENABLE_BINARY_DATA in either jucer file.

Signal Generator

Mine

I changed this to match, but still didn’t get that namespace.

image

So I disabled it again in line with previous comments.

@daniel any suggestions?

The BinaryData is a CPP source file that is created by the Projucer, but only if you added files as binary resources.
To do this drag the magic.xml and any image file you want to use in the Projucer and save the project.
Now you should have the BinaryData.h and BinaryData.cpp (and maybe BinaryData1.cpp and so on).

I’ll add the workflow for CMake later, I need to look it up myself.

To make the image files accessible you need that module switch. It is not necessary to switch that on to use the BinaryData::magic_xml in your source code.

Hope that helps

Hmmm. Well I haven’t done any of that yet. But I can’t figure out why it is not possible for me to load the XML. Or more to the point, it looks like I am loading the XML (I don’t get an error) but it just goes back to the default layout of a bunch of sliders side by side. I am really in the dark. The sample project can save/load just fine and this was one of the differences.

Can you please try the develop banch for me?

  • I removed the conflicting FOLEYS_SAVE_EDITED_GUI_IN_PLUGIN_STATE, which was always overwriting the GUI with the last version from the saved state in the DAW project. That flow wasn’t really thought through.

  • The FOLEYS_ENABLE_BINARY_DATA was brought back. Due to a misunderstanding I thought it wasn’t necessary, but silently all images were no longer showing.

  • I also started to add more documentation about how to use the editor, see here:

I plan to do a release of the develop branch pretty soon, so this version will become the standard.
But there is one functionality I want to add first, which is a callback where you can define your own default GUI algorithm.

Sure, just to be clear, I should delete the existing folder then take the ZIP (or Git checkout) in place?

That’s not necessary. git can switch to any version in time. One way is to use sourcetree or in a terminal you can use the following:

$> cd modules/foleys_gui_magic
$> git checkout develop
$> git pull origin develop

The first line changes to the module folder.
The second line switches the followed branch to develop.
The third line fetches all new commits from the develop branch.

You can also download the specific version from the github page. In that case make sure that github doesn’t rename the folder. It needs to be named foleys_gui_magic, otherwise Projucer will not recognise it as module. IIRC github likes to call it foleys_gui_magic.develop, so you have to rename it to work.

EDIT: I should add you need the git CLI installed to use it on the commandline. THey are not standard on windows, on Mac OS and Linux they are usually already there.

OK Well I’m on Windows so I just downloaded the ZIP, renamed the existing folder, unzipped the new one, renamed the folder, added the module again to jucer. It’s version 1.3.3 now.

It doesn’t help with Load XML and also it appears I can’t drag controls around in edit mode, which I used to be able to do.

That’s weird. Can you have a look at the VERSION.md to check if that is the latest version? It should say 1.3.3
Did you download this one?
https://github.com/ffAudio/foleys_gui_magic/archive/refs/heads/develop.zip

Here’s the link I used, and readme.md does not contain the version #.

https://github.com/ffAudio/foleys_gui_magic/archive/refs/heads/develop.zip

Oops, Version.md contains

1.3.3

  • Allow caption to be configured from CSS style class
  • Added Filmstrip option for knobs
  • Removed FOLEYS_SAVE_EDITED_GUI_IN_PLUGIN_STATE

Sorry, I don’t have an idea at the moment. I will have another look when I come back to my machine.

OK, I rebuilt everything and behavior is the same.

I can move things around in the GUI tree, just not in the plugin UI itself.

I reloaded 1.3.2, still can’t load XML but I can drag and drop controls in the plugin UI.