Hi!
Some background: we are using FMOD as the audio middleware, and have changed the default output to OpenSL (for devices that report FEATURE_AUDIO_LOW_LATENCY).
(I'm skipping the sad part about the devices which report the feature, but actually do not support fast mixer :( ).
For capable devices, we are detecting the native params (sampling frequency and buffer size), and applying them accordingly. We are "feeding" the simple buffer queue with buffers of native size on each callback. Default total ring buffer size is 512 samples x 4, it is being filled in a separate mixer thread to prevent underruns. The things are working pretty fine so far.
However, attaching a Bluetooth speaker/headset breaks the sound.
I’m testing on a Nexus 6 (48kHz/192 samples native device params) and a small BT speaker. A simplest project that plays an audio clip on button click.
I've used a logging version of FMOD to understand what’s going on, and here is what I see:
Before I connect the Bluetooth device, updateOutputCallback that I registered for the SL_IID_ANDROIDSIMPLEBUFFERQUEUE is being called every ~4ms which perfectly matches the native params. I’m “feeding” the buffer queue with 192 samples of audio. The sound goes perfectly well.
After I connect the Bluetooth device, the updateOutputCallback timing is becoming strange. It is being called every 50 to 150 ms, consuming enourmous amount of data (around 5000 samples), and then sleeping again for 50-150 ms. Since the default total audio ring buffer size is 512x4 = 2048 samples, the sound gets played “looped” and slowly progressing through the audio clip.
I can fix it by forcing the buffer size to 2048x4 (I am still submitting 192 samples to the buffer queue every callback). This is not a nice solution since changing buffer configuration in runtime means FMOD reset and reloading sounds, but it’s better than nothing. Also it means *HUGE* latency :(
Here is what I see in logcat when connecting the speaker:
01-21 12:58:50.838: I/AudioFlinger(373): AudioStreamOut::open(), mHalFormatIsLinearPcm = 1
01-21 12:58:50.838: I/AudioFlinger(373): HAL output buffer size 2560 frames, normal sink buffer size 2560 frames
01-21 12:58:50.839: I/AudioFlinger(373): AudioFlinger's thread 0xafb40000 ready to run
Do my observations look correct? Is the strange callback timing related to power saving needed for Bluetooth?
Does it make sense to change the ring buffer size in runtime to 4x2048, and then reset it back to initial value when BT output is disconnected?
Thanks!
Yury