`juce7` technical preview branch

Hi!

I tried Surge with LV2 on mac. I got a plugin which scanned in reaper but didn’t show ports (which @reuk tells me is expected) and didn’t show a UI (which he said wasn’t).

Just dropping instructions here for folks if they want to try it. Basically you need to build against juce7 and then cmake is all set up to detect that it’s juce7 and voila eject an LV2 target. A sample session would be

git clone https://github.com/surge-synthesizer/surge
cd surge
git submodule update --init --recursive
cd libs/JUCE
git remote add upstream https://github.com/juce-framework/JUCE
git fetch upstream
git checkout upstream/juce7
cd ../..
cmake -Bignore/blv2 -DCMAKE_BUILD_TYPE=Debug -DSURGE_COPY_AFTER_BUILD=TRUE
cmake --build ignore/blv2 --target surge-xt_LV2

For that to work I need to merge Support JUCE7 LV2 Builds (if you pull JUCE7) by baconpaul · Pull Request #6083 · surge-synthesizer/surge · GitHub which I will do once ci passes in about 20 minutes.

I haven’t had a chance to try in the plugin host or carla yet but will.

1 Like

RangedAudioParameter has the same constructor signatures as AudioProcessorParameterWithID. AudioProcessorParameterWithID takes a ParameterID as its first constructor argument. ParameterID can optionally be constructed with a custom versionHint.

1 Like

Ok this is merged so these instructions should work module typos and stuff. Will try a bit more later this am!

Ahh OK I’ve figured out why it doesn’t work. this is something we also fixed in the old community LV2 fork.

When I run the audio plugin host I get

JUCE v6.1.6
error: /Users/paul/Library/Audio/Plug-Ins/LV2/Surge XT.lv2/manifest.ttl:10:22: invalid IRI character (escape %20)
lilv_world_load_file(): error: Error loading file `file:///Users/paul/Library/Audio/Plug-Ins/LV2/Surge%20XT.lv2/manifest.ttl'
lilv_world_load_bundle(): error: Error reading file:///Users/paul/Library/Audio/Plug-Ins/LV2/Surge%20XT.lv2/manifest.ttl
error: /Users/paul/Library/Audio/Plug-Ins/LV2/Surge XT.lv2/manifest.ttl:10:22: invalid IRI character (escape %20)
lilv_world_load_file(): error: Error loading file `file:///Users/paul/Library/Audio/Plug-Ins/LV2/Surge%20XT.lv2/manifest.ttl'
lilv_world_load_bundle(): error: Error reading file:///Users/paul/Library/Audio/Plug-Ins/LV2/Surge%20XT.lv2/manifest.ttl

That’s because my plugin name (“Surge XT”) contains a space which becomes the name of the dll but the ttl parser doesn’t work. Here’s the manifest section

<https://surge-synthesizer.github.io/lv2/surge-xt>
	a lv2:Plugin ;
	lv2:binary <libSurge XT.so> ;
	rdfs:seeAlso <dsp.ttl> 

So in the community LV2 fork Kott and I had added

  LV2_SHARED_LIBRARY_NAME SurgeXT

as an argument to juce_add_plugin and then used that as the dll name rather than the one with the space. You could also protect the name in your cmake/projucer also.

When I hand modify the LV2 to rename the library to libSurgeXT.so and modify the manifest files to remove the space, it shows up in the AudioPluginHost no problem. (And spews assertions from that param id thing)

Thanks for reporting. I think there are two problems here:

  • The first problem is that JUCE is writing a malformed manifest.ttl when the LV2’s library name contains a space. We can fix this by percent-encoding the library filename when we write the ttl. When I make this change, the LV2 loads in Carla and the AudioPluginHost, but not in REAPER 6.56…
  • The second problem is that REAPER doesn’t seem to understand percent-encoded library names. When the manifest contains a dylib name that itself contains raw spaces, REAPER fails to parse the manifest. When the manifest contains a percent-encoded dylib name, REAPER successfully parses the manifest, but then fails to load the plugin. My guess is that REAPER is not un-escaping the dylib name before trying to load it. I’ve reported the issue here.

Until the issue is resolved in REAPER, you may be able to work around the issue by using the PRODUCT_NAME and PLUGIN_NAME arguments to juce_add_plugin - the PRODUCT_NAME should not contain spaces for REAPER compatibility, but the user-facing PLUGIN_NAME can still contain spaces. Admittedly, this isn’t a perfect solution as it will apply to other plugin formats.

I can look at adding a proper workaround if we don’t hear anything back from the REAPER developers, or if there are a substantial number of users unwilling to update once the issue is fixed in REAPER. However, I’d rather avoid adding more complexity to JUCE’s build system if possible!

2 Likes

Yeah when we fixed it with our lv2 library name I remember some other tool (like lv2lint or jalv or some such) was giving us problems with the space too so we took the heavy hammer route of adding a dll name argument. I presume the same would happen if you have emoji or other mis encoded utf8 as your plugin name too?

Possibly, yeah. I’ll give the “Audio Plugin Example” a go in jalv and lv2lint too.

Yeah we didn’t try it escaped so that may also fix those tools. Thanks as always for a prompt look!

Hi,

Looks like that host part doesn’t report PluginPath properly to the plugin.
If I open GUI for GitHub - sjaehn/BOops: Sound glitch effect sequencer LV2 plugin (or any other plugin with resources bundled as separate files) it tries to open resource file with file:// prefix:

openat(AT_FDCWD, "file:///usr/lib64/lv2/BOops.lv2/inc/page12.png", O_RDONLY) = -1 ENOENT (No such file or directory)

With escaping, the plugin/UI load fine in lv2lint and jalv. There are a couple of other lv2lint complaints:

  • The ‘turtle_recall’ extension (used to write out the manifest files) is not a ‘real’ extension. Perhaps we should just avoid declaring this extension in the manifest, given that only the JUCE build system really cares about it.
  • Non-resizable plugins have ui:resize extensionData which is not declared in the manifest. We should probably always declare extensionData for both ui:resize and ui:noUserResize, but then only mark one of these as an optional feature.

Thanks for reporting, I was incorrectly passing the UI bundle URI, rather than the filepath, to the UI’s instantiate function. Adding a call to lilv_file_uri_parse seems to resolve the issue, and the background image of B.Oops.lv2 displays correctly.

We’ll push these changes shortly.

1 Like

Excellent!

So now the other thing I’m trying to figure out: has anyone anywhere in the world successfully signed a macOS LV2 plugin? They are not bundles so codesign -s on the LV2 doesn’t work; but you can of course sign each file (which may be what I do). Any thoughts on this welcomed.

well i’m not sure if anyone anywhere else in the world has signed and packaged a standalone lv2 in a mac installer, but i got it working. hit me up here if you end up wanting to know what i did, Short version is: Rather than code sign the bundle, then package, then distribution certificate the pkg, I code signed the .so inside the directory, then package then distrubtion cert the pkg.

And then i get it all notarized and installing.

1 Like

Thanks for reporting, I was incorrectly passing the UI bundle URI, rather than the filepath, to the UI’s instantiate function. Adding a call to lilv_file_uri_parse seems to resolve the issue, and the background image of B.Oops.lv2 displays correctly.

Thanks! B.Oops works fine (and other B*). But there is still a little issue with XT-plugins (from Harrison Harrison Audio)

File not found : /home/kv/.lv2/XT-EQ.lv2res/images/img_201.bmp
as you can see, it misses the slash at the end of bundle path, I “fixed” it by simple:

auto fixedBundlePath = bundlePath.getFullPathName() + "/";
        return Instance { descriptor->get()->instantiate (descriptor->get(),
                                                          pluginUri.toString (false).toRawUTF8(),
                                                          fixedBundlePath.toRawUTF8(),

perhaps there should be a check for such incomplete paths.

1 Like

Oh, though bundle path was easy to fix, the XT-* plugin itself doesn’t redraw the GUI, it changes the values, but the widgets are still, after re-open they are changed.

Which XT build are you testing? Are you using the ‘community’ LV2 implementation, or the JUCE 7 one?

When I build XT with JUCE 7 by updating the submodule and rebuilding, load it in the AudioPluginHost, then open the host parameter display, moving any of the ‘macro’ parameter sliders in the host causes the macro sliders in the editor to update as expected, and vice versa.

I also tried the LV2 from the latest build here: Release Nightly · surge-synthesizer/releases-xt · GitHub

I guess this one is using the community LV2 wrapper as it’s using ungrouped control-port parameters instead of grouped patch parameters. Parameter updates also seem to work for this version of the plugin: moving the host’s Global Volume parameter causes the editor’s volume slider to update; and moving the slider in the editor causes the host’s parameter slider to update.

Please can you specify exactly which plugin build you’re testing, and how you’re testing it? Thanks!

I think kott was talking about a totally different plugin not surge xt Mixbus Plugins - Music Recording Software for Audio Post Production - Harrison Audio Consoles

Our nightlies are still on 616 so our binary is still the community one in surge land. I didn’t want to ask something like “is there a juce7 date yet” because I don’t know what the xt 1.1 date is yet but if those dates align maybe we can move to j7 for xt11

I’ve made this change to surge and will merge it tonight; if you are on JUCE7 the version hint gets set and you can actually run it as a debug build without losing your mind! If you are on juce6 it falls back to the string ctor.

I do wonder if you want to maybe

1: suppress that warning in the VST3/Standalone/etc or
2: Fire it a little less frequently. Like, maybe, once? :slight_smile:

Without a version hint you basically can’t run debug in reaper for instance without it spewing asserts.

Yeah, it’s not Surge XT, it’s a HarissonConsole plugins :slight_smile:
I see you’ve fixed the path (LV2 Host: Add missing path separator to UI bundle path · juce-framework/JUCE@c0d02fc · GitHub). Thanks again!

You can get these plugins for GUI testing in demo mode with Mixbus demo.

1 Like

With JUCE 7 about to be released, would it be a good moment for switching to semantic versioning, or is that still out of the question?

EDIT: perhaps this technical preview branch could be used to see if it’s feasible and useful, before making a definitive choice?

5 Likes

Heya @reuk

we’ve been spending a bit of time looking at the monique LV2. GitHub - surge-synthesizer/monique-monosynth: Monique monosynth

Monique was using a super-ancient (like JUCE 3) deprecated bus api but we fixed it up yesterday which made the CLAP work in BWS. If we pull the synth to juce 7 and try on linux in reaper, ardour, and carla, reaper works but

the semi helpful output so far: Ardour: JUCE Assertion failure in juce_LV2_Client.cpp:1347 (// The host doesn't provide the 'bounded block length' feature)

Carla: [carla] Plugin UI wants a feature that is not supported (ignored): http://lv2plug.in/ns/ext/options#interface [carla] Will use LV2 X11 UI for 'Monique'

To do the build just clone monique from that GitHub repo, submodule update, then cd libs/juce and pull juce 7. Should just spit out an LV2.

Nothing urgent, but it could be another useful test case for you!

2 Likes