audioDeviceIOCallback() never gets called? (in CLI application)

Hello ! Newbie question here…

I am trying to write a simple CLI application, on a Linux computer (Nvidia Jetson NANO). The idea is to start having it outputting a sine wave (and to handle input audio in the future).

Having troubles finding a good tutorial on how to handle this, I started from this thread.
What I did is creating a class inheriting from an audioDeviceIOCallback, and implementing an AudioDeviceManager.

My problem is, it seems to me that the audio callback is never being executed. When I debug my program, I see that the executable actually never enters in it.
At the same time, if I use the playTestSound() method, I can actually hear the test sound. So I don’t think it’s a device problem, i.e. the device not being opened or so.

Here is a simplified version of my code:

main.cpp:

int main(){

    initialiseJuce_GUI();
    AudioDevice ad;
    while(true);
    shutdownJuce_GUI();

    return 0;
}

AudioDevice.h:

class AudioDevice :  juce::AudioIODeviceCallback   {

public:

    AudioDevice()
   {
    mDeviceManager.initialiseWithDefaultDevices(2, 1);
    mDeviceManagerSetup = {
            "USB Audio Device, USB Audio; Direct hardware device without any conversions", //Output device
            "USB Audio Device, USB Audio; Direct hardware device without any conversions", //Input device
            44100, //Sample Rate
            512, //Buffer size
            1, //Input channels
            true, 
            2, //output channels
            false
    };

    mDeviceManager.setAudioDeviceSetup(mDeviceManagerSetup, true);

    if (auto* device = mDeviceManager.getCurrentAudioDevice())
    {
         //....
    }
    else
    {
        std::cout<< ("No audio device open");
    }

    //mDeviceManager.playTestSound(); **//Works if uncommented!** 
    mDeviceManager.addAudioCallback(this);

    ListAvailableInputDevices();
    ListAvailableOutputDevices();
   }
    ~AudioDevice();

    //void ListAvailableInputDevices();
    //void ListAvailableOutputDevices();

    void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples)
{
 for (int channi = 0; channi < numOutputChannels; channi++)
    {
        for (int i = 0; i < numSamples; i++)
        {
            outputChannelData[channi][i] = osc.getCurrentSample();
        }
    }
}
private:

    SineOsc osc;

    //members
    AudioDeviceManager mDeviceManager;
    AudioDeviceManager::AudioDeviceSetup mDeviceManagerSetup;

    //Function overrides
    void audioDeviceAboutToStart(AudioIODevice* device)
    {
      DBG("audioDeviceAboutToStart:\nDevice : " << device->getName() << "\nSampleRate : " << device->getCurrentSampleRate() << "\nBufferSize : " << device->getCurrentBufferSizeSamples());
    }
    void audioDeviceStopped()
{
    DBG("Stopped");
}



};

Some details:

  • playTestSound() works if uncommented

  • audioDeviceAboutToStart() gets called

  • audioDeviceStopped never gets called

  • audioDeviceIOCallback never gets called

  • Listing the audio device/channels I get two output channels output, one input channel.

  • I didn’t provide the code for Osc, it’s a simple class that generates a sine wave. The code works, but it doesn’t get called in first place, since the callback is never executed.

Does anyone know what could be causing this/how to solve it? Also, who calls the audioDeviceIOCallback() ?

Thanks in advance :slight_smile:

Well I solved it myself. I’ll keep the answer here. There is no

void audioDeviceIOCallback(...) override

Only

void audioDeviceIOCallbackWithContext(...) override

It was indeed a noob question, I got confused by some posts that mentioned audioDeviceIOCallback().

The stuff was changed to use audioDeviceIOCallbackWithContext instead of audioDeviceIOCallback at some point. That should now probably be a compiler error instead of getting the wrong behavior on run…Tip for the Juce developers?

AFAIK, there is nothing they can do about it. It was indeed a noob questions because @Barsay you are missing the override attribute to the function. The compiler would have told you, you are making this mistake.

EDIt: they maybe able to do some fancy template magic when adding the IO callback to the device manager, but that will result in all people getting warnings, that are actually implementing a method of that name on purpose.

It used to be backwards compatible, I don’t know the reason for removing it.
As far as I can see there was no cost involved…