Semantic Audio Plug-Ins

Hello everybody,

As part of a research project we have created a few audio plug-ins to gather information about descriptors people use when producing music. Now we just need to get as many people using them as we can so we can get a load of juicy data to analyse.

We would be very grateful to anyone who feels like giving the plug-ins a go. There is more detail and downloadable binaries on our website:

www.semanticaudio.co.uk

 

The project is all open source and can be found on GitHub:

https://github.com/semanticaudio/SAFE

 

Thanks in advace.

Have a nice day now!

Sean

Nice, thanks for the plugins.

I love when I get new linux-compatible stuff. :D

 

If you don't mind, I shared your post on the linuxmusicians forum: http://linuxmusicians.com/viewtopic.php?f=24&t=12631

 

PS: I was happy to see the LV2 wrapper included!

 

Thanks.

It's good to see the Linux build are working for you. I had all kinds of strange problems trying to run them in Ardour so I thought they may have been broken. Hence not having any binaries avaliable.

I just tested the reverb (lv2) in ardour3, seems to work fine. Saving & loading state too.

 

You're free to use my linux binaries if you want. They are inside deb files but it's easy to extract:

https://launchpad.net/~kxstudio-debian/+archive/plugins/+sourcepub/4248511/+listing-archive-extra

(These builds use Ubuntu10.04 with gcc4.8, tested to be working on old systems like Debian 6)

The problems in Ardour happened when when I loaded multiple different plug-ins. You have to do some fairly specific stuff to get things to break but it seemed fairly reproducable.

 

1. Load multiple SAFE plug-ins (they need to be of different types, for some reason it's perfectly happy when it is multiple intances of the same plug-in).

2. Open the plug-in's editors.

3. Unload the plugins in the same order you loaded them (or any order providing that the fisrt one you loaded is not the last one you unload)

4. SEGFAULT :-( (Every so often things get a little more verbose and you get a "X Window Server Error BadCursor ...")

 

I managed to trace this back to the presence of TextEditors in the plugin interface. If you make two "blank" plug-ins which do nothing but have a TextEditor in the interface the same behaviour happens. Not sure if the problem lies in Ardour, JUCE or somewhere else in the system.

 

Any Ideas?

 

Thanks for doing the debian packages, it is much appriciated.

I can see the error when closing ardour3:

The program 'ardour-3.5.380' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadCursor (invalid Cursor parameter)'.

Loading it in my carla host I was able to get a backtrace

EDIT: nevermind the trace

 

it seems to be some memory corruption here.

the crash is different sometimes..

I've been trying to get to the bottom of this, but it's proving rather tricky.

 

The VST builds seem to work fine when hosted in Qtractor. Only in Ardour do they crash when being unloaded as described above. That leads me to believe that the problem lies in Ardour (although perhaps that is wishful thinking). Can anybody suggest any other native Linux VST hosts I can test them in?

 

The LV2 builds seem to be much less stable. Every so often they will crash on loading. Here is a backtrace:


#0  __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
#1  0x96463c85 in juce::CriticalSection::enter (this=0x0)
    at ../../../JuceModules/juce_core/native/juce_posix_SharedCode.h:42
#2  0x963fd547 in juce::GenericScopedLock<juce::CriticalSection>::GenericScopedLock (this=0xbfffc710, lock=...)
    at ../../../JuceModules/juce_audio_basics/../juce_core/threads/juce_ScopedLock.h:72
#3  0x964cd254 in juce::InternalMessageQueue::postMessage (this=0x0, 
    msg=0x8f02820)
    at ../../../JuceModules/juce_events/native/juce_linux_Messaging.cpp:68
#4  0x964caa40 in juce::MessageManager::postMessageToSystemQueue (
    message=0x8f02820)
    at ../../../JuceModules/juce_events/native/juce_linux_Messaging.cpp:361
#5  0x964c6aa1 in juce::MessageManager::MessageBase::post (this=0x8f02820)
    at ../../../JuceModules/juce_events/messages/juce_MessageManager.cpp:73
#6  0x964c70e7 in juce::MessageManagerLock::attemptLock (this=0xbfffc7f8, 
    threadToCheck=0x0, job=0x0)
    at ../../../JuceModules/juce_events/messages/juce_MessageManager.cpp:278
#7  0x964c6f68 in juce::MessageManagerLock::MessageManagerLock (
    this=0xbfffc7f8, threadToCheck=0x0)
    at ../../../JuceModules/juce_events/messages/juce_MessageManager.cpp:242
#8  0x96709edb in juceLV2_Instantiate (sampleRate=44100, features=0x9084180)
    at ../../../JuceModules/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp:17

Perhaps I am not including something I need to to use the LV2 wrapper. I'm not really sure, I'm a bit out of my depth when messages and threads enter the fray.

the lv2 code is based on the vst one.

on linux it uses the same extra message thread to drive events.

 

EDIT: experimental patch for lv2 init issues:

https://github.com/DISTRHO/DISTRHO/commit/632fdd37c2d8e125e22360d16e5833fdbdabe636.patch

I just gave this patch a go.

It gets rid of the SEGFAULT but it now just causes the host to hang sometimes when loading a plug-in.

 

Removing the MessageManagerLock from juceLV2_Instantiate seems to fix the problem. Although that may be a dangerous move. Is it actaully serving a purpose in there? Usually you will hit an assertation if you don't have one where you need it. I haven't hit said assertation.

all UI calls in the LV2 and VST linux builds have to be in scope wth a MessageManagerLock.

this is because linux doesn't have a native event handler/callback, so we need a separate thread polling X11 for new events.

 

I think the problem might be in this line:

https://github.com/DISTRHO/DISTRHO/blob/master/libs/juce/source/modules/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp#L561

The UI should only be really considered initialised after MessageManager is created and set for the new thread.

Try put the "initialised = true;" line after "MessageManager::getInstance()->setCurrentThreadAsMessageThread();"

I'll do the same myself and report back

Thats seems to have fixed it :)

Thanks a lot!

Sorry to drag this up again, but there still seem to be some issues in the LV2 wrapper.

I keep getting a segfault when unloading multiple different plug-ins. I have a feedling it is to do with how and when shutdownJuce_GUI is called. Here is a backtrace:


#0  0x9706b74a in juce::ContainerDeletePolicy<juce::Font::SharedFontInternal>::destroy (object=0xb2088240)
    at ../../../JuceModules/juce_graphics/../juce_core/memory/juce_ContainerDeletePolicy.h:48
#1  0x970657cb in juce::ReferenceCountedObjectPtr<juce::Font::SharedFontInternal>::decIfNotNull (o=0xb2088240)
    at ../../../JuceModules/juce_graphics/../juce_core/memory/juce_ReferenceCountedObject.h:366
#2  0x9705c403 in juce::ReferenceCountedObjectPtr<juce::Font::SharedFontInternal>::~ReferenceCountedObjectPtr (this=0xb1eacab8, __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/../juce_core/memory/juce_ReferenceCountedObject.h:327
#3  0x9703fd83 in juce::Font::~Font (this=0xb1eacab8, 
    __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/fonts/juce_Font.cpp:292
#4  0x9706d0df in juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>::~CachedGlyphEdgeTable (this=0xb1eacab0, 
    __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/native/juce_RenderingHelpers.h:277
#5  0x9706d15b in juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>::~CachedGlyphEdgeTable (this=0xb1eacab0, 
    __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/native/juce_RenderingHelpers.h:277
#6  0x9706d18a in juce::ContainerDeletePolicy<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState> >::destroy (
    object=0xb1eacab0)
    at ../../../JuceModules/juce_graphics/../juce_core/memory/juce_ContainerDeletePolicy.h:48
#7  0x97067ad8 in juce::ReferenceCountedArray<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::DummyCriticalSection>::releaseObject (o=0xb1eacab0)
    at ../../../JuceModules/juce_graphics/../juce_core/containers/juce_ReferenceCountedArray.h:892
#8  0x97060192 in juce::ReferenceCountedArray<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::DummyCriticalSection>::clear (this=0xb1e470e4)
    at ../../../JuceModules/juce_graphics/../juce_core/containers/juce_ReferenceCountedArray.h:136
#9  0x97067978 in juce::ReferenceCountedArray<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::DummyCriticalSection>::~ReferenceCountedArray (this=0xb1e470e4, 
    __in_chrg=<optimised out>)
---Type <return> to continue, or q <return> to quit---
    at ../../../JuceModules/juce_graphics/../juce_core/containers/juce_ReferenceCountedArray.h:122
#10 0x970718ee in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::~GlyphCache (this=0xb1e470e0, 
    __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/native/juce_RenderingHelpers.h:152
#11 0x97071995 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::~GlyphCache (this=0xb1e470e0, 
    __in_chrg=<optimised out>)
    at ../../../JuceModules/juce_graphics/native/juce_RenderingHelpers.h:152
#12 0x96fca5dd in juce::DeletedAtShutdown::deleteAll ()
    at ../../../JuceModules/juce_events/messages/juce_DeletedAtShutdown.cpp:63
#13 0x96fcb4fa in juce::shutdownJuce_GUI ()
    at ../../../JuceModules/juce_events/messages/juce_MessageManager.cpp:332
#14 0x9720e21a in juceLV2_Cleanup (handle=0x10065a00)
    at ../../../JuceModules/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp:1804

It only seems to happen with the LV2 builds, VST works fine. 

Any Ideas?

the shutdownJuce_GUI probably shouldn't be there, as it calls DeleteAtShutdown.

a host can still have a plugin DLL in memory after deleting all instances and afterwards try to load a new one.

I don't think this would work right with the current code. (but it seems to be fine for VST and AU)

 

try commening out the shutdownJuce_GUI line for now.

I'll investigate this a bit more.

Getting rid of that line just causes all sorts of memory leaks.

Maybe a SharedResourcePointer would be the right tool for managing the juce startup/shutdown lifetime?

I based my LV2 code on the VST wrapper, so if you update the VST code with a SharedResourcePointer I'll do the same for LV2.

 

btw, I'm planning to release my plugin host for OSX very soon (which supports LV2).

hopefully this will allow you to test LV2 on OSX and finally have the wrapper in juce, officially.

TBH I'm a bit reluctant to change the VST wrapper, as it's one of those bits of code where small changes can break things in subtle ways that are hard to predict!