You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
4.1 KiB
68 lines
4.1 KiB
4 months ago
|
## Audio Latency Measurement
|
||
|
|
||
|
Audio output latency as measured by WALT is the time that passes from the moment an application
|
||
|
decides to output a tone until it can be detected via the headphone jack. Microphone latency is
|
||
|
defined similarly.
|
||
|
|
||
|
Low latency audio IO on Android can be achieved via JNI C/C++ code.
|
||
|
Documentation and sample code can be found on the
|
||
|
[High Performance Audio website](http://googlesamples.github.io/android-audio-high-performance/).
|
||
|
|
||
|
|
||
|
### Reported values
|
||
|
|
||
|
We are trying to stick to the following (overlapping) principles
|
||
|
1. Timestamp events as close to hardware as possible. Most events up the stack can be easily timed with software alone.
|
||
|
1. Measure time intervals that are likely to have low variability.
|
||
|
|
||
|
##### Playback
|
||
|
|
||
|
In order to avoid warm up latency during audio playback it is
|
||
|
[recommended to constantly enqueue buffers containing silence](http://googlesamples.github.io/android-audio-high-performance/guides/audio-output-latency.html#avoid-warm-up-latency).
|
||
|
WALT app follows this pattern.
|
||
|
|
||
|
The audio data buffers are enqueued in the
|
||
|
[player callback](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L107)
|
||
|
and the latency reported by WALT app is the time from the
|
||
|
[Enqueue() call](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L123)
|
||
|
until 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.
|
||
|
|
||
|
##### Recording
|
||
|
The reported latency is the time from the moment the last frame in a buffer was recorded until the
|
||
|
[recorder callback](https://github.com/google/walt/blob/v0.1.6/android/WALT/app/src/main/jni/player.c#L345)
|
||
|
receiving that buffer is executed.
|
||
|
|
||
|
TODO: Is the round trip latency expected to be Recording latency + Playback latency + one buffer length?
|
||
|
|
||
|
### Sample measurements
|
||
|
|
||
|
| Device | OS version | Buffer | Playback [ms] | Recording* [ms] |
|
||
|
| :--- | :--- | :--- | ---: | ---: |
|
||
|
| Nexus 5 | M4B30Z (6.0.1) | 240 frames @ 48 kHz = 5 ms | 27.6 | 2.5 |
|
||
|
| Nexus 5X | NRD91P (7.0) | 192 frames @ 48 kHz = 4 ms | 14.9 | 3.5 |
|
||
|
| Nexus 7 | LMY47Q (5.1) | 240 frames @ 48 kHz = 5 ms | 32.1 | 16.3 |
|
||
|
| Nexus 9 | MMB29K (6.0.1) | 128 frames @ 48 kHz = 2.6 ms | 9.8 | 1.0 |
|
||
|
| Nexus 6P | MHC19I (6.0.1) | 192 frames @ 48 kHz = 4 ms | 15.3 | 1.6 |
|
||
|
| Pixel | NDE63P (7.1) | 192 frames @ 48 kHz = 4 ms | 8.9 | 1.7 |
|
||
|
| Pixel XL | NDE63H (7.1) | 192 frames @ 48 kHz = 4 ms | 9.1 | 1.6 |
|
||
|
|
||
|
\* WALT clock synchronization accuracy is about 1 ms hence the relative error for recording latency can be fairly high.
|
||
|
|
||
|
#### Published round trip measurements
|
||
|
Superpowered Inc. maintains an open source app for measuring round trip audio latency -
|
||
|
[Superpowered Latency App](https://github.com/superpoweredSDK/SuperpoweredLatency).
|
||
|
|
||
|
* [Audio round trip measurements published by Android group](https://source.android.com/devices/audio/latency_measurements.html#measurements)
|
||
|
* [Audio round trip measurements published by Superpowered Inc.](http://superpowered.com/latency)
|
||
|
|
||
|
|
||
|
### Hardware
|
||
|
|
||
|
Audio signal for measuring microphone latency is generated as a square wave using the Teensy tone()
|
||
|
function ([currently at 5 kHz](https://github.com/google/walt/blob/v0.1.6/arduino/walt/walt.ino#L310)).
|
||
|
The signal is attenuated by a simple circuit similar to the
|
||
|
[ChromeOS/Android audio loopback dongle](https://source.android.com/devices/audio/loopback.html).
|
||
|
|
||
|
Audio output signal from the phone is detected when audio line voltage crosses a predefined
|
||
|
threshold (currently about 65 mV).
|