Announcement: Polymorphic Plugins!


#1

I’ve just checked in a huge reorganisation of the plugin wrapper framework, which condenses all the old code down into a simpler format, where your project creates a single plugin module that functions as an AU, RTAS, VST, or any combination of these.

In the past it was a PITA to have to deal with about 5 different projects for all the combinations of platform/plugin format, and build them all whenever you change your code, so this should make it much easier to manage, and quicker to build.

It also means that your installer will shrink, because only a single binary is needed, and a smart installer could just rename and copy the same thing to all the plugin folders.

I’ve also taken the opportunity to tidy-up some of the layout and filenames to make it all a bit more sensible.

Anyway, it’s a big rewrite, so I’d really appreciate any feedback that you have from trying it out in all the bizarre hosts out there! There’s an all-new “How to use this Framework.txt” file, so have a read of that and good luck!


#2

grrrreat !! Unfortunately for me it comes a bit late in my developpement cycle so I won’t be able to use that right now (just like the cocoa port), but this is definitively a killer feature for Juce, and managing to merge the AU stuff and the RTAS stuff in one same binary is definitively a performance !


#3

Alright, now there’s two steps I definitely have to take in January: Cocoa and this thing. But if this works like you say it will definitely be a big improvement! I’ll come back with feedback/testing after the holidays…

Btw, merry christmas to everybody and especially Jules. My year would have been much worse without JUCE! Thanks!


#4

And a merry xmas to you too!


#5

Hi Jules,

Does this works only on OSX or did you succeed make it work on Windows too ?

I remember the alignement requirement for RTAS Windows and other annoying stuff.


#6

Yep, it works for windows too. RTAS is a bit annoying to set-up, but once you’ve got your project working, you probably won’t have to touch those files again, and it doesn’t make any difference to your other source files.


#7

Couple of (well 3) things on Mac (near the tip: r676):

The localised strings in the Mac project get bundled without resolving the {PRODUCT_NAME} stuff. This seems to be making the JuceDemoPlugin show up in Cubase as {PRODUCT_NAME}

I tried hacking this with various preprocessor macros but the text file just gets copied into the bundle as is, so I just deleted the localisation file/folder and that works (but obviously it then can’t be localised!)

The component still seems to be being placed too high in the window, covering Cubase’s widgets, compare:

and

… mousing in the window now works though (it wasn’t at r621).

Finally, I can’t seem to use the corner resize component in the AU in the DemoPlugin. The window just stays the same size.


#8

Thanks Martin

I’m sure that to make it pre-process the ${PRODUCT_NAME} thing just involves flipping an obscure project setting, but I’m damned if I can find which one, so I think I’ll rip out the localised file and leave it up to people who need localisation to figure that one out!

I’m a bit confused about the window position - is this an AU or VST?

And yes, resizing the AU window seems to be pretty host-dependent. I think it works in garageband but not in AUlab - which host are you talking about here?


#9

That’s a VST, in Cubase LE 4.

[quote=“jules”]
And yes, resizing the AU window seems to be pretty host-dependent. I think it works in garageband but not in AUlab - which host are you talking about here?[/quote]

OK, I just tried it in Logic and the resize component sort of “works”, but weirdly. As the component is enlarged its top edge moves down the window leaving whitespace. I managed to get it to look like this:


#10

I thought I’d got that sorted out… Ok, I’ll take another look.


#11

Also, i have two bugs:

  1. VST GUI in Juce Plugin Host
    After creating GUI it is “jumps” to the right bottom and “lose” all host’s headers. Other hosts works file.

  2. AU GUI.
    All plugins - it is not works. Standart host window is displayed. It is not implemented? (JuceAuView export is commented in wrapper).

Thanks.
(10.5.5, XCode 3)


#12

[quote=“Nkey”]Also, i have two bugs:

  1. VST GUI in Juce Plugin Host
    After creating GUI it is “jumps” to the right bottom and “lose” all host’s headers. Other hosts works file.

  2. AU GUI.
    All plugins - it is not works. Standart host window is displayed. It is not implemented? (JuceAuView export is commented in wrapper).

Thanks.
(10.5.5, XCode 3)[/quote]

Not surprised if there are still bugs in the hosting code, but I’ll take a look. As discussed elsewhere, the AU code only has support for cocoa GUIs, so only cocoa hosts will work. I’m considering adding back the old carbon version as well, as so many hosts are still stuck on carbon.


#13

It will be great to add support of Carbon.
Thanks.


#14

Great stuff Jules! I can’t wait to get the latest tip and update to using the new all in one project. I’ll do this right after a launch with all the existing projects since they seem to be a little more stable and this is production code. I have a bunch of updates as well that I’ll give to you once I’ve made sure they are all stable. I have added pre-allocated buffers so there is no calloc in the dsp thread, the dsp thread is completely lock free, and rock solid vst speaker config code to negotiate multiple ins and outs in live, cubase, studio one, wavelab, audition, and all the other hosts I have tested with.

Andrew Simper


#15

Excellent stuff, ta very much!


#16

It also means that your installer will shrink, because only a single binary is needed, and a smart installer could just rename and copy the same thing to all the plugin folders.

Has anyone managed to do this on OSX? 

I'm looking into various ways to create a standard installer or a drag&drop dmg that would take advantage of the polymorphic space saving. To me it seems to be impossible with a standard package format as in order to be able to select what format(s) to install, sub-packages are needed and those always contain a copy of the data to install.  

I also tried creating a DMG that would allow dragging and dropping and contain renamed links to the same file. However symbolic links won't work and hard links are impossible for directories.

Making the user install the file(s) himself and renaming a .component to a .vst definitely seems to be the wrong way to go.

Creating a custom installer application seems overkill and is hard because of the needed admin rights. It'll also be troublesome because of gatekeeper. 


So overall I'm looking for other options and am hoping someone on this forum has figured something out :). Otherwise I'll endup with unnecessarily large downloads containing three times the same bundle - almost the opposite of the goal of the whole thing. AAX with the signing already leads to an extra copy, but vst/vst3/au should somehow be doable with just one source file.


#17

Has anyone managed to do this on OSX? 

You don't have to. If your installer uses compression.

I have a component, a vst and a vst3 file. Exactly the same file, 6.7MB. And a different signed aaxplugin, 6.8MB.
The installer contains all of them and has a size of 8.2MB.

I use http://s.sudre.free.fr/Software/Packages/about.html to create the installer. Can't recommend it enough, takes the pain out of the creation of pkgs.


#18

I am using Packages already ;). I think you are mistaken by how the compression works. It does not take advantage of multiple files with the same contents, it's using zip compression on each individual file.

If you were right, then your end result should be smaller than 6.7 MB. What you are getting are three copies of the same file compressed in each sub-package. As the products are well compressable you get the 8.2 MB. I have four formats to support and my build is a whopping 16 MB for each. If I compress a single bundle I get 4.7 mb. So ideally my installer would be around 5 mb.

In the meantime I am cooking up a different solution as it appears to work so far. I add a compressed bundle to the resources of the mpkg and now use script-only subpackages to unpack the file and move it to the right folder. I'm still working on the scripts, but I can share once I think it's working completely. 

The only problem I see so far is that the sub-packages all report 0 Bytes as the instal size, but I think I have seen that in other software many times before.


#19

it's using zip compression on each individual file.

I wasn't aware of that. Did a quick test run and yes you are right. Quite stupid indeed...

I add a compressed bundle to the resources of the mpkg...

Side note: In order to pass Apples Gatekeeper you need to sign your installer. A non flat mpkg package can't be signed. To change to a flat pkg, switch from Bundle to Flat in Packages project type.


#20

I completed the first version of my script. I run this as post-install on sub-packages without payload. I build the plugin in xcode and then sign it using the aax signing tools which luckily don't prevent the other formats from working. Then I use command-line zip to create a plug.zip with plugname.aaxplugin inside it. This plug.zip gets added to the main package resources. I use the same script on all subpackages and use the package name to determine where the plugin needs to be copied to. Then I rename in place with the correct file extension.

I will try with a flat package, but I guess it won't work. For me that hopefully stays irrelevant because I really don't like to pay for a mac developer membership just to get signing credentials when there is no way to distribute my product on the Mac App Store.

I tried and it indeed does not work because the Resources folder is of course not readable in a flat pkg. Maybe I could tweak the script so it unpacks the .pkg and then copies stuff out - then the extra zipping probably wouldn't be necessary.

Oh well it starts to feel like a hack solution now :/.

#!/bin/sh
filename="plugname"
originalext="aaxplugin"
case "$PACKAGE_PATH" in
    *AudioUnit.pkg)
        targetpath="/Library/Audio/Plug-Ins/Components"
        ext="component"
        ;;
    *VST.pkg)
        targetpath="/Library/Audio/Plug-Ins/VST"
        ext="vst"
        ;;
    *VST3.pkg)
        targetpath="/Library/Audio/Plug-Ins/VST3"
        ext="vst3"
        ;;
    *AAX.pkg)
        targetpath="/Library/Application Support/Avid/Audio/Plug-Ins"
        ext="aaxplugin"
        ;;
    *)
        exit 77
        ;;
esac
cd `dirname "$PACKAGE_PATH"`/../Resources
cp -rf plug.zip "$targetpath"/plug.zip
cd "$targetpath"
unzip plug.zip

mv "$filename"."$originalext" "$filename"."$ext"
rm -rf plug.zip
exit 0
​