I realize this has been answered and it's an old question. However, to clarify, on my playback queue, I don't use Clear()
. I simply stop the playback and then wait for the queue to drain by using GetState(state)
in a loop, like so:
SLresult res;
SLAndroidSimpleBufferQueueState state = {0};
res = (*playbackBufferQueue)->GetState(playbackBufferQueue, &state);
while (state.count && (res == SL_RESULT_SUCCESS))
{
prevState = state;
res = (*m_playbackBufferQueue)->GetState(m_playbackBufferQueue, &state);
// Otherwise this will peg the CPU
sleep(1);
}
And to support low latency you have use the "optimal" rate and sample size, which you query from Android. Can you do this using native API calls? Of course not, don't be silly. Do it in Java and pass it back to native:
int getBestPlaybackRate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
return Integer.parseInt(audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
}
return 0;
}
int getBestBufferSize() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
return Integer.parseInt(audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
}
return 0;
}