(Bug - Resolved?) AudioSourcePlayer::setSource interferes with other audio

Encountered on OS X El Capitan.

Audio playing from other applications (for instance, Chrome) is muted when I set the audio source to an AudioSourcePlayer object. Oddly, playing audio through the AudioSourcePlayer will restore the other audio with clicks/pops or reduced volume, but after a few seconds it will sound almost as it was before launching my application.

FirstSynthAudioManager()
{
	deviceManager = new AudioDeviceManager();
	deviceManager->initialise(2, 2, 0, true, String::empty, 0);
	deviceManager->addAudioCallback(&audioSourcePlayer);
	
	synthAudioSource = new FirstSynthAudioSource();
	audioSourcePlayer.setSource(synthAudioSource);
	deviceManager->addMidiInputCallback(String::empty, &(synthAudioSource->midiCollector));
}

If I call initialise with only one output channel needed, the bug applies only to one speaker.
Perhaps there’s something I can do programmatically to get around this?

It sounds to me, as if you were blocking the audio thread, which can block the audio driver itself, so it cannot deliver any audio. Hence the distortion or interruption on the other audio applications.
So you can check, if it will go away if you remove all code from your FirstSynthAudioSource::getNextAudioBlock().
The other idea I have would be, if you call prepareToPlay before you add the source to the player. Very often the initialisations are the ones that block too long. Make sure, that prepareToPlay is not issued from the audio thread.

But could still be, that there is a bug on El Capo, I’m developing on Yosemitee.

Good luck

1 Like

I’ve had a go at reproducing this (on El Capitan), but I don’t see the same behaviour. @daniel’s suggestions are good ones!

Hey guys, thanks for the advice / giving it a go.

Without any code changes, the behaviour stopped happening after restarting my machine…
Perhaps a bug in the OS instead.

Cheers!

It is still possible, that you have allocations going on in the audio thread, which were only bad enough to notice when your machine was heavily used.
I also have that behaviour from time to time, when I have breakpoints running xcode, which obviously stop the audio thread at arbitrary points.
But good that you have it going now.

Funny enough, after a few more builds the behaviour returns.
I’m still getting my bearings around JUCE so I’m not entirely sure about what’s executing in which thread. I take it that if my AudioSource is owned by a Component, it’s running in the UI thread (which would be bad), but does the AudioDeviceManager change this?

I should seek out some resources on the threading model here :slight_smile:

The ownership is not important here. It depends, which mechanism calls a method/function.
Whatever is called from the initialise, as result of a Component like button or Slider, or as a result of a Timer callback, is the MessageThread (what you call correctly the UI thread).
Also especially the prepareToPlay is called from the MessageThread, so you can do safely allocations.

Everything which is done in a processBlock and getNextAudioBlock of AudioSources is normally a result of the AudioIODeviceCallback, which is an AudioProcessorPlayer, AudioSourcePlayer and SoundPlayer.

Good luck, it pays off to put some thoughts into that :slight_smile: