aboutsummaryrefslogtreecommitdiff
path: root/en/devices/audio/latency_measure.html
blob: 691502e69c2729b807c8e16933644cfda944b8dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<html devsite>
  <head>
    <title>Measuring Audio Latency</title>
    <meta name="project_path" value="/_project.yaml" />
    <meta name="book_path" value="/_book.yaml" />
  </head>
  <body>
  <!--
      Copyright 2017 The Android Open Source Project

      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
  -->



<p>
  This page describes common methods for measuring input and output latency.
</p>



<h2 id="measuringOutput">Measuring Output Latency</h2>

<p>
  There are several techniques available to measure output latency,
  with varying degrees of accuracy and ease of running, described below. Also
see the <a href="testing_circuit.html">Testing circuit</a> for an example test environment.
</p>

<h3 id="ledTest">LED and oscilloscope test</h3>
<p>
This test measures latency in relation to the device's LED indicator.
If your production device does not have an LED, you can install the
  LED on a prototype form factor device. For even better accuracy
  on prototype devices with exposed circuity, connect one
  oscilloscope probe to the LED directly to bypass the light
  sensor latency.
  </p>

<p>
  If you cannot install an LED on either your production or prototype device,
  try the following workarounds:
</p>

<ul>
  <li>Use a General Purpose Input/Output (GPIO) pin for the same purpose.</li>
  <li>Use JTAG or another debugging port.</li>
  <li>Use the screen backlight. This might be risky as the
  backlight may have a non-negligible latency, and can contribute to
  an inaccurate latency reading.
  </li>
</ul>

<p>To conduct this test:</p>

<ol>
  <li>Run an app that periodically pulses the LED at
  the same time it outputs audio.
  <p class="note"><strong>Note:</strong> To get useful results, it is crucial to use the correct
  APIs in the test app so that you're exercising the fast audio output path.
  See <a href="latency_design.html">Design For Reduced Latency</a> for
  background.</p>
  </li>
  <li>Place a light sensor next to the LED.</li>
  <li>Connect the probes of a dual-channel oscilloscope to both the wired headphone
  jack (line output) and light sensor.</li>
  <li>Use the oscilloscope to measure
  the time difference between observing the line output signal versus the light
  sensor signal.</li>
</ol>

  <p>The difference in time is the approximate audio output latency,
  assuming that the LED latency and light sensor latency are both zero.
  Typically, the LED and light sensor each have a relatively low latency
  on the order of one millisecond or less, which is sufficiently low enough
  to ignore.</p>

<h2 id="measuringRoundTrip">Measuring Round-Trip Latency</h2>

<p>
  <a href="http://en.wikipedia.org/wiki/Round-trip_delay_time">Round-trip latency</a>
  is the sum of output latency and input latency.
</p>

<h3 id="larsenTest">Larsen test</h3>
<p>
  One of the easiest latency tests is an audio feedback
  (Larsen effect) test. This provides a crude measure of combined output
  and input latency by timing an impulse response loop. This test is not very useful
  for detailed analysis
  by itself because of the nature of the test, but it can be useful for
  calibrating other tests, and for establishing an upper bound.</p>

<p>To conduct this test:</p>
<ol>
  <li>Run an app that captures audio from the microphone and immediately plays the
  captured data back over the speaker.</li>
  <li>Create a sound externally,
  such as tapping a pencil by the microphone. This noise generates a feedback loop.
  Alternatively, one can inject an impulse into the loop using software.</li>
  <li>Measure the time between feedback pulses to get the sum of the output latency, input latency, and application overhead.</li>
</ol>

  <p>This method does not break down the
  component times, which is important when the output latency
  and input latency are independent. So this method is not recommended for measuring
  precise output latency or input latency values in isolation, but might be useful
  for establishing rough estimates.</p>

  <p>
  Output latency to on-device speaker can be significantly larger than
  output latency to headset connector.  This is due to speaker correction and protection.
  </p>

<p>
We have published an example implementation at
<a href="https://android.googlesource.com/platform/frameworks/wilhelm/+/master/tests/examples/slesTestFeedback.cpp">slesTestFeedback.cpp</a>.
This is a command-line app and is built using the platform build environment;
however it should be straightforward to adopt the code for other environments.
You will also need the <a href="avoiding_pi.html#nonBlockingAlgorithms">non-blocking</a> FIFO code
located in the <code>audio_utils</code> library.
</p>

<h3 id="loopback">Audio Loopback Dongle</h3>

<p>
  The <a href="loopback.html">Dr. Rick O'Rang audio loopback dongle</a> is handy for
  measuring round-trip latency over the headset connector.
  The image below demonstrates the result of injecting an impulse
  into the loop once, and then allowing the feedback loop to oscillate.
  The period of the oscillations is the round-trip latency.
  The specific device, software release, and
  test conditions are not specified here.  The results shown
  should not be extrapolated.
</p>

<img src="images/round_trip.png" alt="round-trip measurement" id="figure1" />
<p class="img-caption">
  <strong>Figure 1.</strong> Round-trip measurement
</p>

<p>You may need to remove the USB cable to reduce noise,
and adjust the volume level to get a stable oscillation.
</p>

<h2 id="measuringInput">Measuring Input Latency</h2>

<p>
  Input latency is more difficult to measure than output latency. The following
  tests might help.
</p>

<p>
One approach is to first determine the output latency
  using the LED and oscilloscope method and then use
  the audio feedback (Larsen) test to determine the sum of output
  latency and input latency. The difference between these two
  measurements is the input latency.
</p>

<p>
  Another technique is to use a GPIO pin on a prototype device.
  Externally, pulse a GPIO input at the same time that you present
  an audio signal to the device.  Run an app that compares the
  difference in arrival times of the GPIO signal and audio data.
</p>

<h2 id="reducing">Reducing Latency</h2>

<p>To achieve low audio latency, pay special attention throughout the
system to scheduling, interrupt handling, power management, and device
driver design. Your goal is to prevent any part of the platform from
blocking a <code>SCHED_FIFO</code> audio thread for more than a couple
of milliseconds. By adopting such a systematic approach, you can reduce
audio latency and get the side benefit of more predictable performance
overall.
</p>


 <p>
  Audio underruns, when they do occur, are often detectable only under certain
  conditions or only at the transitions. Try stressing the system by launching
  new apps and scrolling quickly through various displays. But be aware
  that some test conditions are so stressful as to be beyond the design
  goals. For example, taking a bugreport puts such enormous load on the
  system that it may be acceptable to have an underrun in that case.
</p>

<p>
  When testing for underruns:
</p>
  <ul>
  <li>Configure any DSP after the app processor so that it adds
  minimal latency.</li>
  <li>Run tests under different conditions
  such as having the screen on or off, USB plugged in or unplugged,
  WiFi on or off, Bluetooth on or off, and telephony and data radios
  on or off.</li>
  <li>Select relatively quiet music that you're very familiar with, and which is easy
  to hear underruns in.</li>
  <li>Use wired headphones for extra sensitivity.</li>
  <li>Give yourself breaks so that you don't experience "ear fatigue."</li>
  </ul>

<p>
  Once you find the underlying causes of underruns, reduce
  the buffer counts and sizes to take advantage of this.
  The eager approach of reducing buffer counts and sizes <i>before</i>
  analyzing underruns and fixing the causes of underruns only
  results in frustration.
</p>

<h3 id="tools">Tools</h3>
<p>
  <code>systrace</code> is an excellent general-purpose tool
  for diagnosing system-level performance glitches.
</p>

<p>
  The output of <code>dumpsys media.audio_flinger</code> also contains a
  useful section called "simple moving statistics." This has a summary
  of the variability of elapsed times for each audio mix and I/O cycle.
  Ideally, all the time measurements should be about equal to the mean or
  nominal cycle time. If you see a very low minimum or high maximum, this is an
  indication of a problem, likely a high scheduling latency or interrupt
  disable time. The <i>tail</i> part of the output is especially helpful,
  as it highlights the variability beyond +/- 3 standard deviations.
</p>

  </body>
</html>