jn_pdx jn_pdx - 1 year ago 190
Java Question

How do you determine the audio latency (AudioTrack) on Android?

I have an app in which I use an

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
stops blocking the
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
so far, and compare it to
. It looks basically like:

long currentTimeInFrames = 0;
while(playingAudio) {
currentTimeInFrames += numberOfFramesToWrite;
long delayInFrames = (currentTimeInFrames - audioTrack.getPlaybackHeadPosition());

However, there's still some latency that
doesn't seem to account for that varies by device.

Is there a way to poll the system for the latency of the AudioTrack?

Answer Source

Consider driver's latency. There's hidden function AudioManager.getOutputLatency(int) to get this.

Call it like this:

AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
   Method m = am.getClass().getMethod("getOutputLatency", int.class);
   latency = (Integer)m.invoke(am, AudioManager.STREAM_MUSIC);
}catch(Exception e){

I get about 45 - 50 ms on different devices. Use the result in your calculations.