JUCE + Tracktion Engine on ELK Audio OS

here is the code I’m using: https://www.dropbox.com/s/du100sgwa3kihp5/engine_in_plugin_example_to_share.zip?dl=1
The Makefile will work using the cross compilation toolchain. I also included the JUCE headless and the VST2 sdk that I’m using but I guess you don’t really need that.

You’ll fins the projucer file and linux makefile in tracktion_engine/examples/projects/EngineInPluginDemo
I removed other engine examples to simplify filelist.

I’m currently compiling this in a VM to see if it works. I’ll let you know…

UPDATE: I could compile in the VM. When running with sushi -d I get the same output, with all the *** ERROR: Rogue call to triggerAndWaitForCallback() errors. At the end it says Segmentation fault (core dumped).

If I run it with -j (jack) it fails trying to initialize frontend, maybe some jack thing I have to configure. In any case I’ll focus on the -d option for now as it is curious that the error is the same as in ELK. I’ll try running other VST hosts and see…

1 Like

Interesting, thanks. I’ll take a look during the weekend but it’s good that it fails already in a simple-to-analyze case as the dummy frontend.

Be catious in distributing the VST2 SDK! It is not allowed by Steinberg…
Not a huge issue while this forum is still with restricted access but better to remove it for next week when this area will be public.

yeah I know about sdk, I was planing to remove the file from dropbox once forum goes live. funny think is that the sdk is still downloadable from steinberg website without making any tricks.

would be interesting to run in a native linux machine with audio known to be properly set.

I took a look at your examples.

With your sources I was able to get the plugin initialized somehow but couldn’t hear any output. Using the oroginal, unmodified EngineInPluginDemo.h from Tracktion Engine’s repo, I get a segfault during init:

Thread 1 "sushi" received signal SIGSEGV, Segmentation fault.
0x00007fffef840420 in tracktion_engine::InputDevice::isEnabled() const () from /home/stez/plugins/EngineInPluginDemo.so                                                                                         
(gdb) bt
#0  0x00007fffef840420 in tracktion_engine::InputDevice::isEnabled() const () from /home/stez/plugins/EngineInPluginDemo.so                                                                                     
#1  0x00007fffef85d078 in tracktion_engine::EditPlaybackContext::rebuildDeviceList() () from /home/stez/plugins/EngineInPluginDemo.so                                                                           
#2  0x00007fffef85dbb0 in tracktion_engine::EditPlaybackContext::EditPlaybackContext(tracktion_engine::TransportControl&) () from /home/stez/plugins/EngineInPluginDemo.so                                      
#3  0x00007fffef85dd38 in tracktion_engine::TransportControl::ensureContextAllocated(bool) () from /home/stez/plugins/EngineInPluginDemo.so                                                                     
#4  0x00007fffef793e1b in tracktion_engine::Edit::TreeWatcher::valueTreePropertyChanged(juce::ValueTree&, juce::Identifier const&) () from /home/stez/plugins/EngineInPluginDemo.so                             
#5  0x00007fffef4839f0 in juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*) () from /home/stez/plugins/EngineInPluginDemo.so                        
#6  0x00007fffef48655d in juce::ValueTree::SharedObject::setProperty(juce::Identifier const&, juce::var const&, juce::UndoManager*, juce::ValueTree::Listener*) () from /home/stez/plugins/EngineInPluginDemo.so
#7  0x00007fffef47fd90 in juce::ValueTree::setPropertyExcludingListener(juce::ValueTree::Listener*, juce::Identifier const&, juce::var const&, juce::UndoManager*) ()                                           
   from /home/stez/plugins/EngineInPluginDemo.so
#8  0x00007fffef63ff0e in EngineInPluginDemo::EngineInPluginDemo() () from /home/stez/plugins/EngineInPluginDemo.so                                                                                             
#9  0x00007fffef63f1cb in createPluginFilter() () from /home/stez/plugins/EngineInPluginDemo.so
#10 0x00007fffef3d8beb in createPluginFilterOfType(juce::AudioProcessor::WrapperType) () from /home/stez/plugins/EngineInPluginDemo.so                                                                          
#11 0x00007fffef3a1afc in VSTPluginMain () from /home/stez/plugins/EngineInPluginDemo.so
#12 0x00005555555f2d6f in sushi::vst2::Vst2xWrapper::init(float) ()

seems like the Tracktion engine is trying to access a device not properly initialized.

From the output logs I get, audio buffer size & sample rate seem to be fetch correctly from the host but there’s not MIDI In / Out devices.

I also tried the same binary with another host (Carla on Linux) and it failed to load there, as well. Which at least means that the problem doesn’t seem to be Elk specific nor Xenomai-related and if it’s possible to replicate in a minimal way and seek assistance on the Tracktion forums.

Sorry for the question but were you able to get the plugin running under a macOS / Windows host?


I was running similar experiments and also reached the conclusion that the problem is not ELK/Sushi/Xenomai related as I’m not able to get the example project running as a VST plugin in Linux VM either. In fact, I also tried in my macOS host and I’m able to have it working normally for standalone and VST2/3 (with bitwig as host) but not with AU, where the AUValidation fails as the plugin crashes when asserting that the configured number of channels does not match with those of the audio buffer (or so I understood, assertion raised here: https://github.com/Tracktion/tracktion_engine/blob/c686909a062a44171c0215cc8a0c1fbbcc320a95/modules/tracktion_engine/utilities/tracktion_AudioUtilities.h#L143).

On Linux VM I can also compile the project and run it as stand-alone and it does not show the triggerAndWaitForCallback errors, but I can’t hear audio output (although this might be because I’m in a virtual machine bla bla).

All this together kind of reinforces the idea that the problem might be with tracktion engine running as plugin in some specific circumstances (VST in Linux, AU in macOS). It seems to me the sensible thing to do would be to report that in the juce/tracktion forum. I’ll try to reproduce all the steps again and report there. I’ll mention @Stefano in the post. Unless you prefer do this differently or you know someone there you’d ask directly, etc.

What do you think?

sure go ahead and post the question on the JUCE Forums.

Can you try to reproduce it with the JUCE plugin host example for Linux? If the issue is also there, then I believe the Tracktion developers should have access to everything to reproduce the issue. I am stez-mind on the JUCE forum.

I just posted the question here https://forum.juce.com/t/problems-using-tracktion-engine-within-a-plugin/36494

I’ve had no luck with the JUCE plugin host in linux (it freezes my VM), but this might be because I’m running a virtual machine and maybe there are problems with the audio devices. Also running JUCE apps as stand alone seem to freeze my VM…

let’s see if someone answers and we get this clarified.

Hi @frederic,
if you have issues with audio on VM, a simple workaround is to use a USB 1.1 audio soundcard and redirect it to the VM. This usually works decently on most setups as USB 1 sharing seems to be much more robust than virtual audio soundcard sharing.

Hmm good idea. Although it almost seems easier to find a machine running linux natively!

hi @Stefano,
I’m trying to further debug this but I’m so far getting so success.
You told me in a message above that you got errors using the EngineInPlugin code and showed a gdb stacktrace. You were doing this in the ELK board or in a dev linux machine. Also, how do you use gdb+ sushi to set breakpoints in the plugin code and see the stack trace?

Hi @frederic,
I did that test on Sushi on my Linux machine.

Quick instructions:

$ gdb ./path-to-sushi-binary
$ b ClassName::method_name # replace with the class/method that you want to break on
# (since in your case the function will be in a plugin and not in the Sushi binary, gdb will ask you if you want to make the breakpoint dependent on future shared library loading, answer yes)
$ run -j -c your_json_config.json # or whatever other CL options you want to pass

When gdb hits a breakpoint, you can then use bt to see a stack trace.

thanks a lot, debugging tip works like charm :slight_smile:

after discussions in the JUCE forum (https://forum.juce.com/t/problems-using-tracktion-engine-within-a-plugin/36494/19) it seems clear that the issues using tracktion engine as a plugin are not particular to elk platform nor sushi. the tracktion team said they have some time allocated early next year to fix issues of tracktion engine as plugin and implement the missing bits. Hopefully when this is done and the engine works properly inside plugin in linux, I’ll be able to continue experimenting with it in elk and finally get it up and running.


Tracktion guys have been working on fixing tracktion engine as a plugin in Linux so we now have a version that we should try with the ELK board and see if it works. Unfortunately now I don’t have a PI available so I can’t do my testing. I’m waiting to get a new PI until ELK support for PI4 is ready and this might take some time still. Maybe if someone else wants to give it a try… Here’s the forum post where the specific branch that should be tested is mentioned: https://forum.juce.com/t/problems-using-tracktion-engine-within-a-plugin/36494/46

First thing would be to try it in a normal linux machine using Sushi. Then in the PI, but for that JUCE probably needs to have the RT patches as well. This was discussed above in this thread. Should be a matter of including twine and overwriting the int64 Time::getHighResolutionTicks() noexcept function. In fact, I guess this patch (when working correctly) should be added to the ELK JUCE branch? Or even better we should have a #if JUCE_ELK with all the graphics and real time patches. I was working on this but stopped when I had to return the PI so I could not continue testing.

@Stefano Do you think someone at ELK could make a test with the tracktion engine changes so we can tell tracktion guys if it works? I’ll try to get a PI back anyway hehe.

1 Like

Hi @frederic,
very nice to hear this!

We are currently testing the Pi 4 and it will be released sometime in April. If you or anyone else is interested in a preview build please write us if you want to beta test it - but be aware that it’s going to have several issues and we’d appreciate any help in finding and fixing them.

For testing out Tracktion integration, we’d love to but we really don’t have time in the near future and we don’t have other special needs other than supporting for your project. But if anyone else here on the forum wants to take a look, please ask questions here and we’d be happy to answer.


Hi @Stefano,

After I got my new Pi I’ve been finally able to test latest tracktion engine changes to see if now I manage to get it working with ELK and… it works!!! :partying_face: I can listen to the engine demo project, even hook a MIDI controller and play a tracktion engine synth they have in the demo!

This is without the patches for an RT safe int64 Time::getHighResolutionTicks() JUCE function. Therefore, I imagine mode switches are happening. I checked documentation to try to assess if this is the case, and that is my output for more /proc/xenomai/sched/stat


I guess this line I underlined indicates that mode switches are happening right? Next thing I’ll try is to fix that.

But this was for the tracktion engine demo only. I have my (bigger) app that I’m developing which I’ll try to compile for ELK next and see what happens. My app only has an extra dependency which is libusb-1.0-0-dev. I don’t know if this is in the SDK, probably not… I guess if it is not, my best option is to include libusb source code in my project somehow so it is compiled as well? Or is there an easy way I could add libusb to the SDK?

In any case this is great news, thanks for all your help!!!

extra note: to compile updated tracktion engine I needed an updated JUCE (newer than the one you customized) so I had to merge changes from more recent JUCE to the ELK JUCE version. It was an easy merge, only with two minor conflicts.

Hi Frederic,
great to hear about the progress!

The issue is if that number is constantly increasing at run-time. Given the high value in your snapshot, it probably is. So try with the obvious things first and then you can look into launching SUSHI+gdb using the --debug-mode-sw flag to spot them.

I just checked and it is packaged in OpenEmbedded but not included in our distro, see the details and versions here:

The library is pretty small so we can include it in the next release that we’ll ship soon. In the meanwhile, you can try to cross-compile the library itself and, maybe with some extra work on your build system for the extra include / library paths, it should work.

Great! Would you mind submitting a PR to:

against the branch mind/headless_plugin_client_next?


great, I can open PR for the updates but I needed a particular juce commit from develop branch (I think), so maybe it is not very useful as my merge does not correspond to a specific juce release. I’ll look into it anyway.

about libusb I’ll try to compile it in my project.

btw, I tried to run sushi in gdb and I got errors saying something similar to sushi not being executable. I saw on forums problem could be related to gcc/gdb versions. have you tried running sushi in gdb for new 0.7.x elk audio os release?

Yes it’s because sushi itself is just a wrapper script against one of several binaries for the various buffer sizes. Try gdb_bX where X is your buffer size as reported by sushi --version, e.g. sushi_b64.

oh great! maybe you could add that to the mode switch debugging docs. thanks!