xref: /aosp_15_r20/external/walt/docs/AudioLatency.md (revision bf47c6829f95be9dd55f4c5bbc44a71c90aad403)
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