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