]>
Commit | Line | Data |
---|---|---|
20a1d0f4 TI |
1 | ===================== |
2 | ALSA PCM Timestamping | |
3 | ===================== | |
4 | ||
229d0430 PLB |
5 | The ALSA API can provide two different system timestamps: |
6 | ||
7 | - Trigger_tstamp is the system time snapshot taken when the .trigger | |
20a1d0f4 TI |
8 | callback is invoked. This snapshot is taken by the ALSA core in the |
9 | general case, but specific hardware may have synchronization | |
10 | capabilities or conversely may only be able to provide a correct | |
11 | estimate with a delay. In the latter two cases, the low-level driver | |
12 | is responsible for updating the trigger_tstamp at the most appropriate | |
13 | and precise moment. Applications should not rely solely on the first | |
14 | trigger_tstamp but update their internal calculations if the driver | |
15 | provides a refined estimate with a delay. | |
229d0430 PLB |
16 | |
17 | - tstamp is the current system timestamp updated during the last | |
20a1d0f4 TI |
18 | event or application query. |
19 | The difference (tstamp - trigger_tstamp) defines the elapsed time. | |
229d0430 | 20 | |
a5d48be4 | 21 | The ALSA API provides two basic pieces of information, avail |
229d0430 PLB |
22 | and delay, which combined with the trigger and current system |
23 | timestamps allow for applications to keep track of the 'fullness' of | |
24 | the ring buffer and the amount of queued samples. | |
25 | ||
26 | The use of these different pointers and time information depends on | |
27 | the application needs: | |
28 | ||
20a1d0f4 TI |
29 | - ``avail`` reports how much can be written in the ring buffer |
30 | - ``delay`` reports the time it will take to hear a new sample after all | |
31 | queued samples have been played out. | |
229d0430 PLB |
32 | |
33 | When timestamps are enabled, the avail/delay information is reported | |
34 | along with a snapshot of system time. Applications can select from | |
20a1d0f4 TI |
35 | ``CLOCK_REALTIME`` (NTP corrections including going backwards), |
36 | ``CLOCK_MONOTONIC`` (NTP corrections but never going backwards), | |
37 | ``CLOCK_MONOTIC_RAW`` (without NTP corrections) and change the mode | |
229d0430 PLB |
38 | dynamically with sw_params |
39 | ||
40 | ||
41 | The ALSA API also provide an audio_tstamp which reflects the passage | |
42 | of time as measured by different components of audio hardware. In | |
43 | ascii-art, this could be represented as follows (for the playback | |
44 | case): | |
20a1d0f4 | 45 | :: |
229d0430 | 46 | |
20a1d0f4 TI |
47 | --------------------------------------------------------------> time |
48 | ^ ^ ^ ^ ^ | |
49 | | | | | | | |
50 | analog link dma app FullBuffer | |
51 | time time time time time | |
52 | | | | | | | |
53 | |< codec delay >|<--hw delay-->|<queued samples>|<---avail->| | |
54 | |<----------------- delay---------------------->| | | |
55 | |<----ring buffer length---->| | |
229d0430 | 56 | |
229d0430 PLB |
57 | |
58 | The analog time is taken at the last stage of the playback, as close | |
59 | as possible to the actual transducer | |
60 | ||
a5d48be4 | 61 | The link time is taken at the output of the SoC/chipset as the samples |
229d0430 PLB |
62 | are pushed on a link. The link time can be directly measured if |
63 | supported in hardware by sample counters or wallclocks (e.g. with | |
64 | HDAudio 24MHz or PTP clock for networked solutions) or indirectly | |
65 | estimated (e.g. with the frame counter in USB). | |
66 | ||
67 | The DMA time is measured using counters - typically the least reliable | |
a5d48be4 | 68 | of all measurements due to the bursty nature of DMA transfers. |
229d0430 PLB |
69 | |
70 | The app time corresponds to the time tracked by an application after | |
71 | writing in the ring buffer. | |
72 | ||
a5d48be4 | 73 | The application can query the hardware capabilities, define which |
229d0430 | 74 | audio time it wants reported by selecting the relevant settings in |
a5d48be4 | 75 | audio_tstamp_config fields, thus get an estimate of the timestamp |
229d0430 PLB |
76 | accuracy. It can also request the delay-to-analog be included in the |
77 | measurement. Direct access to the link time is very interesting on | |
78 | platforms that provide an embedded DSP; measuring directly the link | |
79 | time with dedicated hardware, possibly synchronized with system time, | |
80 | removes the need to keep track of internal DSP processing times and | |
81 | latency. | |
82 | ||
83 | In case the application requests an audio tstamp that is not supported | |
84 | in hardware/low-level driver, the type is overridden as DEFAULT and the | |
85 | timestamp will report the DMA time based on the hw_pointer value. | |
86 | ||
87 | For backwards compatibility with previous implementations that did not | |
88 | provide timestamp selection, with a zero-valued COMPAT timestamp type | |
89 | the results will default to the HDAudio wall clock for playback | |
90 | streams and to the DMA time (hw_ptr) in all other cases. | |
91 | ||
92 | The audio timestamp accuracy can be returned to user-space, so that | |
93 | appropriate decisions are made: | |
94 | ||
95 | - for dma time (default), the granularity of the transfers can be | |
96 | inferred from the steps between updates and in turn provide | |
97 | information on how much the application pointer can be rewound | |
98 | safely. | |
99 | ||
100 | - the link time can be used to track long-term drifts between audio | |
101 | and system time using the (tstamp-trigger_tstamp)/audio_tstamp | |
102 | ratio, the precision helps define how much smoothing/low-pass | |
103 | filtering is required. The link time can be either reset on startup | |
104 | or reported as is (the latter being useful to compare progress of | |
105 | different streams - but may require the wallclock to be always | |
106 | running and not wrap-around during idle periods). If supported in | |
107 | hardware, the absolute link time could also be used to define a | |
108 | precise start time (patches WIP) | |
109 | ||
110 | - including the delay in the audio timestamp may | |
111 | counter-intuitively not increase the precision of timestamps, e.g. if a | |
112 | codec includes variable-latency DSP processing or a chain of | |
113 | hardware components the delay is typically not known with precision. | |
114 | ||
115 | The accuracy is reported in nanosecond units (using an unsigned 32-bit | |
116 | word), which gives a max precision of 4.29s, more than enough for | |
117 | audio applications... | |
118 | ||
119 | Due to the varied nature of timestamping needs, even for a single | |
120 | application, the audio_tstamp_config can be changed dynamically. In | |
20a1d0f4 | 121 | the ``STATUS`` ioctl, the parameters are read-only and do not allow for |
229d0430 | 122 | any application selection. To work around this limitation without |
20a1d0f4 | 123 | impacting legacy applications, a new ``STATUS_EXT`` ioctl is introduced |
229d0430 | 124 | with read/write parameters. ALSA-lib will be modified to make use of |
20a1d0f4 | 125 | ``STATUS_EXT`` and effectively deprecate ``STATUS``. |
229d0430 PLB |
126 | |
127 | The ALSA API only allows for a single audio timestamp to be reported | |
128 | at a time. This is a conscious design decision, reading the audio | |
129 | timestamps from hardware registers or from IPC takes time, the more | |
130 | timestamps are read the more imprecise the combined measurements | |
131 | are. To avoid any interpretation issues, a single (system, audio) | |
132 | timestamp is reported. Applications that need different timestamps | |
133 | will be required to issue multiple queries and perform an | |
134 | interpolation of the results | |
135 | ||
136 | In some hardware-specific configuration, the system timestamp is | |
e8369d65 | 137 | latched by a low-level audio subsystem, and the information provided |
229d0430 PLB |
138 | back to the driver. Due to potential delays in the communication with |
139 | the hardware, there is a risk of misalignment with the avail and delay | |
140 | information. To make sure applications are not confused, a | |
141 | driver_timestamp field is added in the snd_pcm_status structure; this | |
142 | timestamp shows when the information is put together by the driver | |
20a1d0f4 | 143 | before returning from the ``STATUS`` and ``STATUS_EXT`` ioctl. in most cases |
229d0430 PLB |
144 | this driver_timestamp will be identical to the regular system tstamp. |
145 | ||
146 | Examples of typestamping with HDaudio: | |
147 | ||
148 | 1. DMA timestamp, no compensation for DMA+analog delay | |
20a1d0f4 TI |
149 | :: |
150 | ||
151 | $ ./audio_time -p --ts_type=1 | |
152 | playback: systime: 341121338 nsec, audio time 342000000 nsec, systime delta -878662 | |
153 | playback: systime: 426236663 nsec, audio time 427187500 nsec, systime delta -950837 | |
154 | playback: systime: 597080580 nsec, audio time 598000000 nsec, systime delta -919420 | |
155 | playback: systime: 682059782 nsec, audio time 683020833 nsec, systime delta -961051 | |
156 | playback: systime: 852896415 nsec, audio time 853854166 nsec, systime delta -957751 | |
157 | playback: systime: 937903344 nsec, audio time 938854166 nsec, systime delta -950822 | |
229d0430 PLB |
158 | |
159 | 2. DMA timestamp, compensation for DMA+analog delay | |
20a1d0f4 TI |
160 | :: |
161 | ||
162 | $ ./audio_time -p --ts_type=1 -d | |
163 | playback: systime: 341053347 nsec, audio time 341062500 nsec, systime delta -9153 | |
164 | playback: systime: 426072447 nsec, audio time 426062500 nsec, systime delta 9947 | |
165 | playback: systime: 596899518 nsec, audio time 596895833 nsec, systime delta 3685 | |
166 | playback: systime: 681915317 nsec, audio time 681916666 nsec, systime delta -1349 | |
167 | playback: systime: 852741306 nsec, audio time 852750000 nsec, systime delta -8694 | |
229d0430 PLB |
168 | |
169 | 3. link timestamp, compensation for DMA+analog delay | |
20a1d0f4 TI |
170 | :: |
171 | ||
172 | $ ./audio_time -p --ts_type=2 -d | |
173 | playback: systime: 341060004 nsec, audio time 341062791 nsec, systime delta -2787 | |
174 | playback: systime: 426242074 nsec, audio time 426244875 nsec, systime delta -2801 | |
175 | playback: systime: 597080992 nsec, audio time 597084583 nsec, systime delta -3591 | |
176 | playback: systime: 682084512 nsec, audio time 682088291 nsec, systime delta -3779 | |
177 | playback: systime: 852936229 nsec, audio time 852940916 nsec, systime delta -4687 | |
178 | playback: systime: 938107562 nsec, audio time 938112708 nsec, systime delta -5146 | |
229d0430 PLB |
179 | |
180 | Example 1 shows that the timestamp at the DMA level is close to 1ms | |
181 | ahead of the actual playback time (as a side time this sort of | |
182 | measurement can help define rewind safeguards). Compensating for the | |
a5d48be4 | 183 | DMA-link delay in example 2 helps remove the hardware buffering but |
229d0430 PLB |
184 | the information is still very jittery, with up to one sample of |
185 | error. In example 3 where the timestamps are measured with the link | |
186 | wallclock, the timestamps show a monotonic behavior and a lower | |
187 | dispersion. | |
188 | ||
189 | Example 3 and 4 are with USB audio class. Example 3 shows a high | |
190 | offset between audio time and system time due to buffering. Example 4 | |
191 | shows how compensating for the delay exposes a 1ms accuracy (due to | |
192 | the use of the frame counter by the driver) | |
193 | ||
194 | Example 3: DMA timestamp, no compensation for delay, delta of ~5ms | |
20a1d0f4 TI |
195 | :: |
196 | ||
197 | $ ./audio_time -p -Dhw:1 -t1 | |
198 | playback: systime: 120174019 nsec, audio time 125000000 nsec, systime delta -4825981 | |
199 | playback: systime: 245041136 nsec, audio time 250000000 nsec, systime delta -4958864 | |
200 | playback: systime: 370106088 nsec, audio time 375000000 nsec, systime delta -4893912 | |
201 | playback: systime: 495040065 nsec, audio time 500000000 nsec, systime delta -4959935 | |
202 | playback: systime: 620038179 nsec, audio time 625000000 nsec, systime delta -4961821 | |
203 | playback: systime: 745087741 nsec, audio time 750000000 nsec, systime delta -4912259 | |
204 | playback: systime: 870037336 nsec, audio time 875000000 nsec, systime delta -4962664 | |
229d0430 PLB |
205 | |
206 | Example 4: DMA timestamp, compensation for delay, delay of ~1ms | |
20a1d0f4 TI |
207 | :: |
208 | ||
209 | $ ./audio_time -p -Dhw:1 -t1 -d | |
210 | playback: systime: 120190520 nsec, audio time 120000000 nsec, systime delta 190520 | |
211 | playback: systime: 245036740 nsec, audio time 244000000 nsec, systime delta 1036740 | |
212 | playback: systime: 370034081 nsec, audio time 369000000 nsec, systime delta 1034081 | |
213 | playback: systime: 495159907 nsec, audio time 494000000 nsec, systime delta 1159907 | |
214 | playback: systime: 620098824 nsec, audio time 619000000 nsec, systime delta 1098824 | |
215 | playback: systime: 745031847 nsec, audio time 744000000 nsec, systime delta 1031847 |