This might have gone unnoticed, but this code:
if (bufferSize < sampsNeeded + 8)
{
bufferPos %= bufferSize;
Can leads to (extremely rare) divide-by-zero exception being generated.
What happens, is that the main thread has just finished setting the callback:
#0 0x00007f89f4ba2474 in __pthread_mutex_unlock_usercnt (mutex=0x21a7c58, decr=<value optimized out>) at pthread_mutex_unlock.c:52
#1 0x00000000006bb7ea in juce::CriticalSection::exit (this=0x21a7c58) at ../../src/native/common/juce_posix_SharedCode.h:59
#2 0x0000000000429687 in ~ScopedLock (this=0x7fff1744b2d0, __in_chrg=<value optimized out>) at ../../include/../../Libraries/Juce/src/containers/../utilities/../events/../threads/juce_ScopedLock.h:78
#3 0x00000000006d41ff in juce::ALSAThread::setCallback (this=0x21a7b30, newCallback=0x21c06f8) at ../../src/native/linux/juce_linux_Audio.cpp:511
#4 0x00000000006d5074 in juce::ALSAAudioIODevice::start (this=0x2122530, callback=0x21c06f8) at ../../src/native/linux/juce_linux_Audio.cpp:788
And the alsa thread called :
#0 0x0000000000586f90 in juce::ResamplingAudioSource::getNextAudioBlock (this=0x21c0520, info=...) at ../../src/audio/audio_sources/juce_ResamplingAudioSource.cpp:112
#1 0x000000000058604d in juce::AudioSourcePlayer::audioDeviceIOCallback (this=0x21c06f8, inputChannelData=0x21a8288, totalNumInputChannels=0, outputChannelData=0x21a7e80, totalNumOutputChannels=6,
numSamples=8192) at ../../src/audio/audio_sources/juce_AudioSourcePlayer.cpp:157
#2 0x00000000006d4335 in juce::ALSAThread::run (this=0x21a7b30) at ../../src/native/linux/juce_linux_Audio.cpp:540
Since the prepareToPlay wasn’t called yet (it’s called after setCallback returns, but before start returns), the Resampling’s audio source is called to fill some buffer while it’s not “prepared”, thus leading bufferSize = 0.
This workaround might work if you change the start function to read instead:
void start (AudioIODeviceCallback* callback)
{
if (! isOpen_)
callback = 0;
if (callback != 0)
callback->audioDeviceAboutToStart (this);
internal->setCallback (callback);
isStarted = (callback != 0);
}
Please confirm that “internal” can’t be changed from the outside (which should be ok, unless someone is calling stop() inside the audioDeviceAboutToStart, but he will see the previous callback which is IMHO what was expected)