JUCE GUI freeze when starts PortAudio stream

Hi,

I am new to audio programming and JUCE. I am writing an audio mixer which can receive two input devices and two output devices. It seems that JUCE native AudioDeviceManager class can only open one device at a time, so I am currently implementing this requirement with Portaudio with JUCE GUI.

I created a GUI button, the onclick callback function opens the Portaudio streams.

MainComponent::MainComponent()
{
...
    // click this button to launch Portaudio stream
    addAndMakeVisible(applyButton);
    applyButton.setButtonText("Apply");
    applyButton.onClick = [this] { applyConfigChange(); };
}

void MainComponent::applyConfigChange() {
    // The GUI freeze because the execution of the below method starting a Portaudio stream
    sm.startStream(....);
}

I have read some audio tutorials and I guess the reason that the GUI freezes is that the PortAudio stream is running in the GUI thread. I am also aware that getNextAudioBlock of AudioAppComponent class runs in the Audio thread. However, I don’t think I can use it because it is called for processing each JUCE audio block, but my block processing is done by Portaudio.

I am looking for a method to have the button onclick callback function running in an individual audio thread other than the getNextAudioBlock, or any other ideas.

Thanks.

I have no experience with PortAudio, but a quick look at the Pa_StartStream( stream ); call does not seem to indicate that this is a blocking function. It looks like it begins the audio processing, which in turn starts calling your callback.
After calling Pa_StartStream(), PortAudio will start calling your callback function to perform the audio processing.
I would assume that callback happens on a thread created by PortAudio, but I could be wrong.

IIRC PortAudio also has a processing mode where it waits for the current thread to push in audio. If that is active, I don’t suppose that would work that well with Juce.

Tried with both callback API and Blocking API in Portaudio, both freeze the JUCE GUI.

I wonder if we can change this processing mode in PortAudio…

Don’t know PortAudio, but did you try debugging? Pause execution while running under the debugger and have a look at the call stacks of all threads. This will likely reveal where your UI thread is spending its time hanging :wink:

2 Likes

It should work. We use PortAudio with Juce GUI in our apps.
Pa_OpenStream with a callback and then Pa_StartStream

You are probably doing something wrong.

1 Like

Thanks, the startStream which launch PortAudio streams is running in JUCE Message Thread. Could this be the problem?

Thanks, that’s a good news :smile:

Nop. PA launch a new realtime thread and call you callback on it.

The best advice given so far was the use the debugger to step into the code and see where it is getting stuck…

Thanks, problem solved. There was a while loop blocked the thread. It’s nothing to do with PortAudio :smile: