cabbage icon indicating copy to clipboard operation
cabbage copied to clipboard

[Request] Add LV2 as export options

Open T0NIT0RMX opened this issue 6 years ago • 42 comments
trafficstars

Hi @rorywalsh ,

I'm currently developping a synthesizer using Cabbage framework and I would love to release it (for free, and open source)

So here are my 2 request to implement 2 new new plugins format :

  • VST3 (JUCE seems ready for that) : Would allow compatibility with DAW like FL Studio
  • LV2 (@FalkTX has a fork of JUCE with a LV2 wrapper, I think he can give you some help here) : Would allow compatibility with LMMS soon !

Thanks in advance,

T0NIT0RMX avatar Feb 02 '19 18:02 T0NIT0RMX

Hi,

Though I'm not developer. Cabbage uses vanilla JUCE, so VST3 could be possible (except Linux for now), LV2 - sadly not, until JUCE megre LV2 supports in own sourcetree.

KottV avatar May 12 '19 05:05 KottV

VST3 support is now available. LV2 is not so straightforward. I'll leave this open until such time as LV2 sorry can be added. falltx published an LV2 add-on for JUCE. I just haven't had time to test it with the latest source. It was known to work well in earlier versions of Cabbage.

rorywalsh avatar May 12 '19 09:05 rorywalsh

For information, no idea if it helps, there seems to be an actively maintained project "LV2 Related JUCE Modules" (Mentioned on https://github.com/WeAreROLI/JUCE/issues/123)

JohannesLorenz avatar Jan 02 '20 21:01 JohannesLorenz

Thanks for this. I think being able to export to LV2 is more important that Cabbage being able to host LV2 plugins. Btw, VST3 exporting was implemented some time ago. Maybe I should change the issue name, or close it and open one about specifically about LV2s..

On Thu, 2 Jan 2020 at 21:35, Johannes Lorenz [email protected] wrote:

For information, no idea if it helps, there seems to be an actively maintained project "LV2 Related JUCE Modules" https://github.com/lvtk/jlv2 (Mentioned on WeAreROLI/JUCE#123 https://github.com/WeAreROLI/JUCE/issues/123)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rorywalsh/cabbage/issues/39?email_source=notifications&email_token=AAUQWGOLLO42Q3IUWFDOTQLQ3ZM3BA5CNFSM4GT6242KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH7PZBQ#issuecomment-570358918, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAUQWGOYPNSOV77NHE6YAE3Q3ZM3BANCNFSM4GT6242A .

rorywalsh avatar Jan 02 '20 21:01 rorywalsh

It possible to make LV2 plugins in recent JUCE https://linuxmusicians.com/viewtopic.php?f=44&t=20584#p112948

Next important question that Cabbage have to generate all LV2 *.ttl stuff

PS I think it needs the collaboration of developers for providing "stay-up-to-day" LV2 fork of JUCE for example, there is my fork (not published yet) and https://github.com/DISTRHO/juce/tree/distrho-update

KottV avatar Jan 03 '20 05:01 KottV

@rorywalsh you are alright, we can change the name and close this issue for vst3 and open a special LV2 one ! It would be really cool to have lv2 export option in Cabbage! That would make it possible for Linux user to use ToneZ !

T0NIT0RMX avatar Jan 03 '20 06:01 T0NIT0RMX

@rorywalsh Hi! Rory, are you still intended to add LV2 export feature? As far as I can build LV2 plugins from recent JUCE code and have CabbagePluginSynth.lv2 (and it loads). But I haven't knowledge how Cabbage generate .so files.

KottV avatar Jan 17 '20 00:01 KottV

I wrote a long reply to this a few days ago, but somehow it didn't appear. That's not the first time this has happened to me! Anyhow, I was asking how you added support for LV2 to the current JUCE source? Can you provide me with a patch, I'm using JUCE 5.4.5. Once I have the wrapper stuff in place I can probably use falktx's code from Cabbage v1 to add an LV2 export option for Cabbage.

Btw, it looks like ROLI will not be adding support for LV2 any time soon.

rorywalsh avatar Jan 21 '20 22:01 rorywalsh

This is JUCE 5.4.5 with updated and working LV2 code https://github.com/lv2-porting-project/JUCE/tree/lv2 so it has to substitude original JUCE when building For now the Projucer knows nothing about LV2, so we need to add some lines after resaving project:

  1. To enable LV2 add this lines to JuceLibraryCode/AppConfig.h it contains LV2 URI of plugin. It's unclear for me how it should work with exporting in Cabbage:
// [BEGIN_USER_CODE_SECTION]

// (You can add your own code in this section, and the Projucer will not overwrite it)
#define JucePlugin_Build_LV2 1
#define JucePlugin_LV2URI "https://cabbageaudio.com/CabbagePluginSynth"


// [END_USER_CODE_SECTION]
  1. Prepare additional Makefile for LV2 format, it contains plugin dir/file name "JUCE_TARGET := CabbagePluginSynth" . I usually name it LV2.mak and put it near the .jucer file :
# -*- makefile -*-
JUCE_TARGET := CabbagePluginSynth
JUCE_TARGET_LV2 := $(JUCE_TARGET).so
JUCE_OUTDIR_LV2 := $(JUCE_OUTDIR)/$(JUCE_TARGET).lv2
JUCE_CFLAGS_LV2 := $(JUCE_CFLAGS_VST)
JUCE_CPPFLAGS_LV2 := $(JUCE_CPPFLAGS_VST)
JUCE_LDFLAGS_LV2 := $(JUCE_LDFLAGS_VST)

all : LV2
LV2 : $(JUCE_OUTDIR_LV2)/$(JUCE_TARGET_LV2)

OBJECTS_LV2 := \
  $(JUCE_OBJDIR)/include_juce_audio_plugin_client_LV2_.o

$(JUCE_OBJDIR)/include_juce_audio_plugin_client_LV2_.o: ../../JuceLibraryCode/include_juce_audio_plugin_client_LV2.cpp
        -$(V_AT)mkdir -p $(JUCE_OBJDIR)
        @echo "Compiling include_juce_audio_plugin_client_LV2.cpp"
        $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_LV2) $(JUCE_CFLAGS_LV2) -o "$@" -c "$<"

$(JUCE_OUTDIR_LV2)/$(JUCE_TARGET_LV2) : check-pkg-config $(OBJECTS_LV2) $(RESOURCES) $(JUCE_OUTDIR)/$(JUCE_TARGET_SHARED_CODE)
        @echo Linking "$(JUCE_TARGET) - LV2"
        -$(V_AT)mkdir -p $(JUCE_BINDIR)
        -$(V_AT)mkdir -p $(JUCE_LIBDIR)
        -$(V_AT)mkdir -p $(JUCE_OUTDIR_LV2)
        $(V_AT)$(CXX) -o $(JUCE_OUTDIR_LV2)/$(JUCE_TARGET_LV2) $(OBJECTS_LV2) $(JUCE_OUTDIR)/$(JUCE_TARGET_SHARED_CODE) $(JUCE_LDFLAGS) $(JUCE_LDFLAGS_LV2) $(RESOURCES) $(TARGET_ARCH)
        ../../generate-lv2-ttl.py $(JUCE_OUTDIR_LV2)/$(JUCE_TARGET_LV2)

-include $(OBJECTS_LV2:%.o=%.d)

check-pkg-config:
        @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; }
        @pkg-config --print-errors alsa freetype2 libcurl x11 xext xinerama

  1. include above in original Makefile, I usually put it near of the .jucer file:

echo "include ../../LV2.mak" >> Builds/LinuxMakefile/Makefile

  1. Get ttl generator and put near of the LV2.mak https://github.com/lv2-porting-project/lv2-ttl-generator/blob/master/generate-lv2-ttl.py

  2. Go to Builds/LinuxMakefile/Makefile and run make. For now it crashes with CONFIG=Release, so I build with Debug then strip binary.

KottV avatar Jan 22 '20 00:01 KottV

Btw, it looks like ROLI will not be adding support for LV2 any time soon.

True. LV2 can be just option in Cabbage for now.

KottV avatar Jan 22 '20 00:01 KottV

Thanks for the info. I'll try to get something going. I will probably need your help at some point!

rorywalsh avatar Jan 22 '20 07:01 rorywalsh

I'll do my best.

KottV avatar Jan 22 '20 08:01 KottV

Am I right in assuming that I should credit falktx's for these files? I want to include it in the readme. I'll obviously mention your good self too. I just don't want to appear to be taking credit for the work of others! If you can think of any others I'll be happy to put their name down too!

rorywalsh avatar Jan 22 '20 10:01 rorywalsh

I'm getting an error:

Linking CabbagePluginSynth - LV2 ../../LV2Code/generate-lv2-ttl.py build/CabbagePluginSynth.lv2/CabbagePluginSynth.so make: ../../LV2Code/generate-lv2-ttl.py: Command not found

Any ideas? I've double checked the path to the .py file and it's correct.

[edit] My bad, the path was actually incorrect!

rorywalsh avatar Jan 22 '20 14:01 rorywalsh

Thanks to your steps @KottV I have an LV2 plugin building now, although it doesn't make my sound. But at least it's a start!

rorywalsh avatar Jan 22 '20 16:01 rorywalsh

Am I right in assuming that I should credit falktx's for these files? If you can think of any others I'll be happy to put their name down too!

Most of work is made by falktx https://github.com/DISTRHO/juce/branches with contributions by https://github.com/jpcima Patching concept is from Debian JUCE repo https://salsa.debian.org/multimedia-team/juce IOhannes m zmölnig And some good guy (I think he is from Pianoteq :) https://linuxmusicians.com/viewtopic.php?f=44&p=113721#p112936

KottV avatar Jan 23 '20 00:01 KottV

Thanks for this information. I'm just trying to set up a proper dev environment to debug this issue. It's taking me a little more time than I'd like. I'll let you know when I get somewhere with it.

rorywalsh avatar Jan 23 '20 17:01 rorywalsh

Hi @KottV I accidentally deleted all that work I had done with this :rage: So I had to do it all again. No big deal. Anyhow, Carla loads the resulting LV2 file without any problems. As too does Ardour 6. But for some reason Ardour 5.n will not load them. I'm going to try some things now to see if I can figure out what's going on.

rorywalsh avatar Jan 30 '20 16:01 rorywalsh

If I build with CONFIG=Release then Ardour 5.12 sees the plugin. This is good. I'll take a look at adding LV2 export next.

rorywalsh avatar Jan 30 '20 16:01 rorywalsh

Hi! This is exciting in all means.

KottV avatar Jan 30 '20 22:01 KottV

Might it be possible to mark ports as being CV for generated LV2 plugins, like DPF can?

mxmilkiib avatar Feb 10 '20 22:02 mxmilkiib

That might be possible. Sorry I haven't had more time to spend on this. I will return to it on Wednesday ;)

rorywalsh avatar Feb 11 '20 09:02 rorywalsh

I did some more work on this today. If anyone wants to test it out, checkout the lv2 branch and build using the buildCabbage script. Then launch Cabbage from the newly created install folder. Open an effect, and try exporting as an lv2. You will then need to copy that .lv2 to your lv2 folder. I haven't tried synths yet. I'll let you know.

rorywalsh avatar Feb 14 '20 16:02 rorywalsh

It builds. But doesn't work for me. It shows empty GUI like there no csd file. And something wrong with Effect's files naming. I'm gonna to dig it deeply.

Another thing is calling addLV2Support.sh when run buildCabbage again. I think it should be executed just once separately or maybe using flag/checking in script.

KottV avatar Feb 15 '20 05:02 KottV

The lv2 that get's built is merely a dummy. Can you check the lv2 bundle that gets created when you export from Cabbage? It should definitely contain a .csd file? The ttl files should be renamed too.

Another thing is calling addLV2Support.sh when run buildCabbage again. I think it should be executed just once separately or maybe using flag/checking in script.

It's done this way because the Projucer overwrites all the JUCE modules when it generates a project. So when we generate the synth project it overwrites all previous modules, same when we generate the makefiles for the effect. I guess most people would separate each project into its own unique project tree, but I've always kept them in the same tree, which I always found to be cleaner, albeit with certain caveats.

If you think you can find a neat way around this issue please give it a go. I'm always open the PRs. Thanks again for taking a look. We're getting closer I think.

rorywalsh avatar Feb 15 '20 08:02 rorywalsh

Hi @KottV Can you confirm that the bundle you export from Cabbage has the associated .csd file, and that the ttl files have all been updated?

rorywalsh avatar Feb 20 '20 09:02 rorywalsh

Hi! Yes, now there is bundle:

~/.lv2/BandFilter.lv2> tree
.
├── BandFilter.csd
├── BandFilter.so
├── BandFilter.ttl
├── CabbagePlugin.lv2
│   ├── CabbagePlugin.so
│   ├── CabbagePlugin.ttl
│   ├── manifest.ttl
│   └── presets.ttl
├── manifest.ttl
└── presets.ttl

and now it loads in jalv.gtk2 (it's really awesome) though URI is still https://cabbageaudio.com for every exported bundle

KottV avatar Feb 20 '20 11:02 KottV

I can help with the last one. When I was packaging cabbage files as plugins, I used this:

#define JucePlugin_LV2URI String("urn:cabbage:")+File::getSpecialLocation(File::currentExecutableFile).getFileNameWithoutExtension().replace("cabbage-","")

These might also be useful:

// skips preset generation, as they are not usually a thing for csound
#define JucePlugin_WantsLV2Presets 0
// if we dont need custom chunk data, consider also:
#define JucePlugin_WantsLV2State 0
// finally, if fixed block-size buffers are required, use this: (note that it will prevent it from being used in ardour, but also prevents crashes..)
#define JucePlugin_WantsLV2FixedBlockSize 1

falkTX avatar Feb 20 '20 11:02 falkTX

Great thanks guys. I'll tidy things up and add support for synths too in the next few days. And thanks @falkTX If it wasn't for your initial work, we'd all still be scratching our heads.

rorywalsh avatar Feb 20 '20 15:02 rorywalsh

Camomile has it's own modifications of JUCE LV2 for generating binaries https://github.com/pierreguillot/Camomile/tree/dev/imp-compilation The project is some kind similar (pure-data instead of csound). Let's take a look if it can be borrowed for Cabbage :)

KottV avatar Jul 14 '20 04:07 KottV