Stuck on AudioDeviceManager initialization and how to debug

Hi,
I’m new here and I just started developing for Elk os. I’m currently trying to get a simple Juce vst2 plugin to run on the elk-pi hat. The plugin is an audio recorder adapted from the Juce demo app (All the graphical bits are removed)

The plugin itself worked as a regular Juce plugin, it also worked on the pc as a headless plugin.
It compiles successfully for the rpi4 and it starts up on the board (I know that because I print info to a file with the Juce FileLogger).
And here I found a problem:
At some point in the code the plugin calls the initialise method on a juce::AudioDeviceManager object : the issue is that the plugin seems to stop here because In the logs I cannot find anything that should be printed after that.
I know very little about gdb but I called gdb sushi_b64, specified catch throw, ran sushi with the plugin and nothing bad comes up (tho I think that juce doesn’t use exceptions).
At this point sushi doesn’t even respond to SIGINT but I don’t know how to debug it.
Also /tmp/sushi.log remains completely empty and it seems that the plugin randomly worked once because I found a complete log and a single recording saved after running sushi multiple times from gdb.

How would you go about debugging this? How about best practices for debugging this kind of plugins? Is this a known problem with the AudioDeviceManager and the headless version of plugins?

Thank you in advance for reading my confused thoughts, I hope this makes sense.
I leave here a piece of the code where everything stops

AudioDeviceManager& audioDeviceManager { getSharedAudioDeviceManager (1, 0) };
...
logText("Asking runtime permission");
RuntimePermissions::request (RuntimePermissions::recordAudio,
    [this] (bool granted)
    {
        std::string grantStatus = granted ? "granted" : "NOT granted";
        logText("Permission callback called (permission " + grantStatus + ")");
        int numInputChannels = granted ? 2 : 0;
        logText("Initializing audioDeviceManager");

        //<- Until here log is printed and permission is granted
        
        String initRes = audioDeviceManager.initialise (numInputChannels, 2, nullptr, true, {}, nullptr);

        logText("Initialization result: '" + initRes.toStdString() + "'");  //<- This is not printed
    });
1 Like

Hi domenico and welcome to the forum.
From reading https://docs.juce.com/master/classAudioDeviceManager.html#details it looks like AudioDeviceManager is a wrapper class for an audio device, ie soundcard or audio input/output. That’s not something you would usually use in a plugin, unless you have a very specific use case. Are you sure this is code that should go in a plugin and not in a standalone app?

If you run Sushi with gdb and it hangs, it should be possible to stop it using ctrl-c and see which thread(s) is blocked and where. Only in special circumstances like timers or syscalls in the audio thread have we seen freezes that couldn’t be caught with gdb.

If /tmp/sushi.log is completely empty, then that sounds odd though, it should at least print a few lines when starting up everytime.

If you have access to a regular linux machine (a virtual machine also works) you could build and run Sushi with your plugin there and see what you get (just remember to run Sushi with the jack frontend). You could also use debug builds of both sushi and you plugin to get better stack traces.
A regular linux distribution is usually more forgiving when it comes to threading and realtime issues than the xenomai-enabled Elk distribution, which can make debugging easier.

4 Likes

Thank you! It makes a lot of sense.

Thanks also for the suggestions, I’ll try running sushi on my machine too.