I have an app in which I use an AudioTrack
in streaming mode to play dynamically generated audio. The app doesn't have to respond instantaneously to inputs, so the latency issues don't bother me for that side of the program.
The problem is that I have an animation that needs to be as precisely 'in-sync' as possible with the audio and it seems that different devices have different amounts of time between when the AudioTrack
stops blocking the write()
call and asks for more data, and when that audio is played from the speaker.
My current solution gets me most of the way there -- I count the number of frames I've passed in to the AudioTrack
so far, and compare it to getPlaybackHeadPosition()
. It looks basically like:
long currentTimeInFrames = 0;
while(playingAudio) {
currentTimeInFrames += numberOfFramesToWrite;
long delayInFrames = (currentTimeInFrames - audioTrack.getPlaybackHeadPosition());
audioTrack.write(frameBuffer,0,sampleSize);
doAnimationAfterDelay(delayInFrames);
}
However, there's still some latency that getPlaybackHeadPosition()
doesn't seem to account for that varies by device.
Is there a way to poll the system for the latency of the AudioTrack?
Consider driver's latency. There's hidden function AudioManager.getOutputLatency(int) to get this.
Call it like this:
I get about 45 - 50 ms on different devices. Use the result in your calculations.