Vember surge synth opensourced, builds and runs on Linux

Yessss! It works! Thanks!
Now we are really really close …

zynthian_engine_surge

and of course …

Thanks to @C0d3man & @lguyome45 for paving the way for integrating this new engine on zynthian … and of course, thanks to the fabulous falkTX and the fantastic Surge team!!

8 Likes

Next step find a way to convert fxp to ttl :wink:

The minimum and maximum value in FXP file is defined in the code of the plugin : https://github.com/surge-synthesizer/surge/blob/dd49b2582d07156838f5cf8e142a54c352d3e104/src/common/Parameter.cpp#L308 set variables with the mini/maxi which is assigned to parameters in https://github.com/surge-synthesizer/surge/blob/main/src/common/SurgePatch.cpp

When the minimum and maximum value in TTL file is between [0.0; 1.0]

There is a python script in surge directory that take a fxp in input to list the parameter : https://github.com/surge-synthesizer/surge/blob/main/scripts/patch-tool/patch-tool.py

Then it’s almost done. Simply take a look to this:

We have already a OBXd’s FXB to LV2 preset converter:

so it shouldn’t be too difficult to write one for Surge’s FXBs. Perhaps @mheidt want to collaborate … :wink:

Regards,

2 Likes

There is more than 600 parameters and need to find what is the scale needed for all of this parameter, maybe not so difficult

Perhaps hacking the function:

param_ptr.push_back(...)

for writing the info we need (parameter name, min, max, default, etc) in the format we want … :thinking:

Once we have a list of parameters with:

  • name
  • type
  • scale info: min, max

in a format we can load easily from python: JSON or YAML would be OK), we can easily parse the FXPs, that are binary files with the parameters values stored as embbeded XML. The last step is almost trivial.

Thanks!

I adore… people call 'trivial" those things that I totally don’t understand…
They are angels, for sure… maybe even gods…

1 Like

I take time, find a file in the source with all parameters name https://github.com/surge-synthesizer/surge/blob/main/test-data/param-ids-1.6.5.txt , add the type.
Next step, calculate all scale
surge parameters.ods (19.4 KB)

3 Likes

Hmmm, in Surge_dsp.ttl all values have a range from 0.0 to 1.0. This means a converter has to scale all values of the several types to a range of 0.0…1.0?

I don’t like LV2 plugins which try to normalize all parameters. But if we have no other chance…

Regards, Holger

P.S.: This is why I started to write a complete own LV2 engine around Dexed: I thought that it is not very usable for humans to have all parameters in a normalized range. This bad handling comes from the JUCE plugin wrapper… I don’t like it…

I totally agree with you, @C0d3man. I can’t understand the reason to implement the LV2 wrapper in such a way. LV2 perfectly supports a wide range of control port types …

Regards!

2 Likes

I get a bus error when I try to compile the surge plugin using the recipe script. Do you have 2+ Gig pi’s?

I am using 4GB RPis…

You need to take the recipe C0d3man put :

#!/bin/bash
# https://github.com/hexdump0815/surge-arm-build
# https://github.com/nemequ/simde
cd $ZYNTHIAN_PLUGINS_SRC_DIR
sudo apt-get install --no-install-recommends --yes build-essential libcairo2-dev libxkbcommon-x11-dev libxkbcommon-dev libxcb-cursor-dev libxcb-keysyms1-dev libxcb-util0-dev
git clone https://github.com/hexdump0815/surge-arm-build.git
cd surge-arm-build
git checkout 5add960506adc2af3a647698edb8fca3f6ef07f0 # just to be sure to use the right version!
git clone https://github.com/surge-synthesizer/surge.git
cd surge
git checkout release_1.6.6
git submodule update --init --recursive
patch --forward -p0 <../surge-armv7l.patch
find * -type f -exec ../simde-ify.sh {} \;
git clone https://github.com/nemequ/simde.git
sed -i 's/flags { "StaticRuntime" }/flags { staticruntime "On" }/g' premake5.lua
premake5 --cc=gcc --os=linux gmake2
sed -i '/^ifndef verbose/,+4d' surge-lv2.make
sed -i 's, -m64,,g;s,-msse2,-march=armv7-a -mfpu=vfpv3-d16 -mno-unaligned-access,g;s,FORCE_INCLUDE +=,FORCE_INCLUDE += -Isimde/simde,g' surge-*.make
sed -i 's,config=debug_x64,config=release_x64,' surge-*.make
CXXFLAGS="" CFLAGS="" make -f surge-lv2.make
rsync -r --delete target/lv2/Release/Surge.lv2 "${ZYNTHIAN_PLUGINS_DIR}/lv2"
cd ..
1 Like

If it helps, the 0,1 choice happens in https://github.com/surge-synthesizer/surge/blob/main/src/lv2/SurgeLv2Export.cpp when the export-to-ttl uses getParameter01 which is the normalized value inside the synth. Could also use the other APIs which have both scaled and unscaled ranges on Parameter. The XML in the fxp uses the non-normalized value but the scaling is the obvious (val - val_min)/(val_max-val_min) where val_max and val_min are set by the parameter type which is specified in the SurgePatch param layout.

I am not knowledgeable enough about LV2 to know why the LV2 authors made that choice.

We have surge 1.7.0 around the corner and we’re working on getting most of the ARM stuff merged into main. Surge 1.7.0 also moves from premake to cmake. https://github.com/surge-synthesizer/surge/issues/2345. You can see the full changelog of new features here: https://surge-synthesizer.github.io/changelog/ and we plan the 1.7.0 release on Aug 1.

Finally with Surge 1.7.0 the official binary release will only include VST3 and AU, but folks who build from source can also build LV2 and VST2 (if they have the VST2 SDK). See our website for why (I can only put 3 links in a post since I’m new).

Especially note the request for help with making a reliable LV2. We are recommending that, if at all possible, folks prefer the VST3 on Linux although I don’t know if the toolset here supports it.

Best

5 Likes

@baconpaul has come from over here: https://github.com/surge-synthesizer/surge/issues/2345 by the way. Thanks for popping by!

2 Likes

Hey just thinking about this TTL issue overnight, and checking out zynthian for the first time (which looks like a super cool project, btw! Neat stuff). One thing which makes Surge unreliable as an LV2 is that the state of the synth (which is streamed into the XML) is way larger than the state of the parameters. So there’s 600 params or so, but there’s also close to unbounded modulation. Those modulation paths and amounts are not host exposed.

The short version of this is: if you take a surge, load it at init, and apply just the DAW parameters which are floats, you won’t get the right sound. You really need to load that XML blob.

(There’s another thing too which is that surge modifies its port values itself through things like oscillator type changes, which cause most of the LV2 problems).

But I think your intent here was: Take the FXP, make a list of param values in some other format, and assign those as presets from zynthian. Cool idea, but you will want to make sure that that preset contains the xml blob also. You can see in the surge LV2 where we basically do that here: https://github.com/surge-synthesizer/surge/blob/fd16ef0d5749938f50561de7d22da758c38ab979/src/lv2/SurgeLv2Wrapper.cpp#L351

Finally with @Baggypants and some others I’m working on getting all the ARM stuff into our main branch ready for 1.7.0 so you should just be able to build from and track main at that point.

6 Likes

Thanks for the note! The lv2 exports I created with jalv.gtk include a base64 encoded state blob a the end which I’ve just checked is encoded xml. Looks a lot like the fxp format.

2 Likes

Yes that’s right. If you export by “saving a track” you will get it (that’s what the code above does). Just if you export by writing some code to dump a TTL from params you will miss stuff.

The question is, how can we load the XML blob in the LV2 engine?
On LV2, a preset is a list of control port values, so it should be a special “control port” with a custom data type for the XML blob, or something like that …

Anyway, i’ve tested the 4 presets generated by @Baggypants and the sound is nice, although i’ve not compared with the original, loaded from the UI.

Regards!

1 Like

:face_with_monocle:

3 Likes

Jalv takes care of that. The lv2 presets I created with jalv have the xml and state saved in the base64 encoded part of the ttl file.

1 Like