Build insert plugin and synth from the same sources

I have a customer request to build an audio insert plugin with midi input as a virtual instrument with sidechain input. Technically it’s the same thing and some hosts treat both the same way. Others do not and it can be cumbersome to route midi to insert effects.

In order to do such a build I’d have to change many settings in the .jucer project including configuration flags, binary names and plugin codes.

Has anyone faced the same challenge and come up with a way to make this repeatable? I already tried to do it with extra build configs that have a preprocessor flag set, but getting all the right values in the AppConfig is tricky and opaque and there are a few files that need to be regenerated anyway (like info.plist etc). So I think there is no way around a separate .jucer project for a synth version.

I’m worried about future changes and would like to avoid having to maintain two .jucer projects for this. I imagine something should be possible using shell scripts to automatically generate the synth project, but do wonder if anyone found an elegant working solution - or maybe I’m overlooking a simple way to get this done.

1 Like

This reminds me of Aumu and aumi single project.

I don’t know any way of making this work in Projucer.

However, if you’re fine with using a CMake-based solution (such as JUCE 6 CMake support or FRUT), I would be more than happy to help you.

Thank you for the reply! I was searching the forum, but didn’t find the thread you linked which is indeed about the exact same problem. I’m not ready (yet) to switch to CMake, but might do that once Juce 6 is out.
I think I can do something similar with a shell script that will just parse and patch my jucer file. Maybe even a diff file could handle the necessary changes.

I believe the solution in the other thread is still missing a few things. In order to load both variants in the same host, they probably need different plugin codes, binary names and AU prefixes as well.

Thanks again, I’ll now work on rolling my own solution based on this information.

1 Like

For future reference. Here is what I ended up doing:

  1. I removed all the keys from the .jucer file that can be autogenerated based on the project name. After that changing the name automatically changes many dependent params and leads to needing less patching.
  2. I wrote a Python script using xml.etree.ElementTree which loads the .jucer file and patches the xml attributes in the JUCERPROJECT root node and stores the xml as a new .jucer file. I ended up creating a routine that checks the original value first so I get an error in case future Projucer versions use different ids and/or values.
import xml.etree.ElementTree as ET

def replaceProp(node, propID, expected, newValue):
	if node.get(propID) != expected:
		print('ERROR! unexpected property: ' + propID + ' node: ' + node.tag + ' expected: ' + expected + ' encountered: ' + node.get(propID))
	node.set(propID, newValue)

tree = ET.parse('{ORIGINAL}.jucer')

root = tree.getroot()
replaceProp(root, 'name', '{ORIGNAME}', '{NEWNAME}')
replaceProp(root, 'pluginIsSynth', '0', '1') 
replaceProp(root, 'pluginCharacteristicsValue', 'pluginWantsMidiIn', 'pluginIsSynth,pluginWantsMidiIn')
replaceProp(root, 'pluginCode',...

(.... etc)

tree.write('{PATCHED}.jucer')

I would just move all your code, other than the type specific code into a JUCE module, so you won’t have to keep running a script.

(CMake would indeed make that process even simpler)

I think that solution would still require me to keep two .jucer files up to date. Most build configuration would need to be done twice after the split because some data would need to be duplicated. Now I can just rerun my python converter and don’t even need to have the second jucer file stored in my git repo.

Yes, you’d have 2 JUCER files, but if the source files are in the JUCE module, you won’t have to touch those often, unless the build settings changed - the module header/source would keep track if you added source files.

To really share settings between projects using CMake+JUCE 6 would be very easy.