1*bf47c682SAndroid Build Coastguard Worker## Audio Latency Measurement 2*bf47c682SAndroid Build Coastguard Worker 3*bf47c682SAndroid Build Coastguard WorkerAudio output latency as measured by WALT is the time that passes from the moment an application 4*bf47c682SAndroid Build Coastguard Workerdecides to output a tone until it can be detected via the headphone jack. Microphone latency is 5*bf47c682SAndroid Build Coastguard Workerdefined similarly. 6*bf47c682SAndroid Build Coastguard Worker 7*bf47c682SAndroid Build Coastguard WorkerLow latency audio IO on Android can be achieved via JNI C/C++ code. 8*bf47c682SAndroid Build Coastguard WorkerDocumentation and sample code can be found on the 9*bf47c682SAndroid Build Coastguard Worker [High Performance Audio website](http://googlesamples.github.io/android-audio-high-performance/). 10*bf47c682SAndroid Build Coastguard Worker 11*bf47c682SAndroid Build Coastguard Worker 12*bf47c682SAndroid Build Coastguard Worker### Reported values 13*bf47c682SAndroid Build Coastguard Worker 14*bf47c682SAndroid Build Coastguard WorkerWe are trying to stick to the following (overlapping) principles 15*bf47c682SAndroid Build Coastguard Worker1. Timestamp events as close to hardware as possible. Most events up the stack can be easily timed with software alone. 16*bf47c682SAndroid Build Coastguard Worker1. Measure time intervals that are likely to have low variability. 17*bf47c682SAndroid Build Coastguard Worker 18*bf47c682SAndroid Build Coastguard Worker##### Playback 19*bf47c682SAndroid Build Coastguard Worker 20*bf47c682SAndroid Build Coastguard WorkerIn order to avoid warm up latency during audio playback it is 21*bf47c682SAndroid Build Coastguard Worker[recommended to constantly enqueue buffers containing silence](http://googlesamples.github.io/android-audio-high-performance/guides/audio-output-latency.html#avoid-warm-up-latency). 22*bf47c682SAndroid Build Coastguard WorkerWALT app follows this pattern. 23*bf47c682SAndroid Build Coastguard Worker 24*bf47c682SAndroid Build Coastguard WorkerThe audio data buffers are enqueued in the 25*bf47c682SAndroid Build Coastguard Worker[player callback](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L107) 26*bf47c682SAndroid Build Coastguard Workerand the latency reported by WALT app is the time from the 27*bf47c682SAndroid Build Coastguard Worker[Enqueue() call](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L123) 28*bf47c682SAndroid Build Coastguard Workeruntil there is a detectable signal on the wire. Note that this does not include the time between the moment the app decided to output a tone until the Enqueue() call. This is somewhat counterintuitive but this time is deliberately omitted. In case of the WALT app code this time is likely be uniformly distributed between 0 and the length of the buffer (5 ms in case of Nexus 5) and therefore would contribute considerable variance but little interesting information if included in the reported latency. 29*bf47c682SAndroid Build Coastguard Worker 30*bf47c682SAndroid Build Coastguard Worker##### Recording 31*bf47c682SAndroid Build Coastguard WorkerThe reported latency is the time from the moment the last frame in a buffer was recorded until the 32*bf47c682SAndroid Build Coastguard Worker[recorder callback](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L345) 33*bf47c682SAndroid Build Coastguard Workerreceiving that buffer is executed. 34*bf47c682SAndroid Build Coastguard Worker 35*bf47c682SAndroid Build Coastguard WorkerTODO: Is the round trip latency expected to be Recording latency + Playback latency + one buffer length? 36*bf47c682SAndroid Build Coastguard Worker 37*bf47c682SAndroid Build Coastguard Worker### Sample measurements 38*bf47c682SAndroid Build Coastguard Worker 39*bf47c682SAndroid Build Coastguard Worker| Device | OS version | Buffer | Playback [ms] | Recording* [ms] | 40*bf47c682SAndroid Build Coastguard Worker| :--- | :--- | :--- | ---: | ---: | 41*bf47c682SAndroid Build Coastguard Worker| Nexus 5 | M4B30Z (6.0.1) | 240 frames @ 48 kHz = 5 ms | 27.6 | 2.5 | 42*bf47c682SAndroid Build Coastguard Worker| Nexus 5X | NRD91P (7.0) | 192 frames @ 48 kHz = 4 ms | 14.9 | 3.5 | 43*bf47c682SAndroid Build Coastguard Worker| Nexus 7 | LMY47Q (5.1) | 240 frames @ 48 kHz = 5 ms | 32.1 | 16.3 | 44*bf47c682SAndroid Build Coastguard Worker| Nexus 9 | MMB29K (6.0.1) | 128 frames @ 48 kHz = 2.6 ms | 9.8 | 1.0 | 45*bf47c682SAndroid Build Coastguard Worker| Nexus 6P | MHC19I (6.0.1) | 192 frames @ 48 kHz = 4 ms | 15.3 | 1.6 | 46*bf47c682SAndroid Build Coastguard Worker| Pixel | NDE63P (7.1) | 192 frames @ 48 kHz = 4 ms | 8.9 | 1.7 | 47*bf47c682SAndroid Build Coastguard Worker| Pixel XL | NDE63H (7.1) | 192 frames @ 48 kHz = 4 ms | 9.1 | 1.6 | 48*bf47c682SAndroid Build Coastguard Worker 49*bf47c682SAndroid Build Coastguard Worker\* WALT clock synchronization accuracy is about 1 ms hence the relative error for recording latency can be fairly high. 50*bf47c682SAndroid Build Coastguard Worker 51*bf47c682SAndroid Build Coastguard Worker#### Published round trip measurements 52*bf47c682SAndroid Build Coastguard WorkerSuperpowered Inc. maintains an open source app for measuring round trip audio latency - 53*bf47c682SAndroid Build Coastguard Worker[Superpowered Latency App](https://github.com/superpoweredSDK/SuperpoweredLatency). 54*bf47c682SAndroid Build Coastguard Worker 55*bf47c682SAndroid Build Coastguard Worker* [Audio round trip measurements published by Android group](https://source.android.com/devices/audio/latency_measurements.html#measurements) 56*bf47c682SAndroid Build Coastguard Worker* [Audio round trip measurements published by Superpowered Inc.](http://superpowered.com/latency) 57*bf47c682SAndroid Build Coastguard Worker 58*bf47c682SAndroid Build Coastguard Worker 59*bf47c682SAndroid Build Coastguard Worker### Hardware 60*bf47c682SAndroid Build Coastguard Worker 61*bf47c682SAndroid Build Coastguard WorkerAudio signal for measuring microphone latency is generated as a square wave using the Teensy tone() 62*bf47c682SAndroid Build Coastguard Workerfunction ([currently at 5 kHz](https://github.com/google/walt/blob/v0.1.6/arduino/walt/walt.ino#L310)). 63*bf47c682SAndroid Build Coastguard WorkerThe signal is attenuated by a simple circuit similar to the 64*bf47c682SAndroid Build Coastguard Worker[ChromeOS/Android audio loopback dongle](https://source.android.com/devices/audio/loopback.html). 65*bf47c682SAndroid Build Coastguard Worker 66*bf47c682SAndroid Build Coastguard WorkerAudio output signal from the phone is detected when audio line voltage crosses a predefined 67*bf47c682SAndroid Build Coastguard Workerthreshold (currently about 65 mV). 68