Blame view

kernel/linux-rt-4.4.41/Documentation/sound/alsa/timestamping.txt 10.5 KB
5113f6f70   김현기   kernel add
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
  The ALSA API can provide two different system timestamps:
  
  - Trigger_tstamp is the system time snapshot taken when the .trigger
  callback is invoked. This snapshot is taken by the ALSA core in the
  general case, but specific hardware may have synchronization
  capabilities or conversely may only be able to provide a correct
  estimate with a delay. In the latter two cases, the low-level driver
  is responsible for updating the trigger_tstamp at the most appropriate
  and precise moment. Applications should not rely solely on the first
  trigger_tstamp but update their internal calculations if the driver
  provides a refined estimate with a delay.
  
  - tstamp is the current system timestamp updated during the last
  event or application query.
  The difference (tstamp - trigger_tstamp) defines the elapsed time.
  
  The ALSA API provides reports two basic pieces of information, avail
  and delay, which combined with the trigger and current system
  timestamps allow for applications to keep track of the 'fullness' of
  the ring buffer and the amount of queued samples.
  
  The use of these different pointers and time information depends on
  the application needs:
  
  - 'avail' reports how much can be written in the ring buffer
  - 'delay' reports the time it will take to hear a new sample after all
  queued samples have been played out.
  
  When timestamps are enabled, the avail/delay information is reported
  along with a snapshot of system time. Applications can select from
  CLOCK_REALTIME (NTP corrections including going backwards),
  CLOCK_MONOTONIC (NTP corrections but never going backwards),
  CLOCK_MONOTIC_RAW (without NTP corrections) and change the mode
  dynamically with sw_params
  
  
  The ALSA API also provide an audio_tstamp which reflects the passage
  of time as measured by different components of audio hardware.  In
  ascii-art, this could be represented as follows (for the playback
  case):
  
  
  --------------------------------------------------------------> time
    ^               ^              ^                ^           ^
    |               |              |                |           |
   analog         link            dma              app       FullBuffer
   time           time           time              time        time
    |               |              |                |           |
    |< codec delay >|<--hw delay-->|<queued samples>|<---avail->|
    |<----------------- delay---------------------->|           |
  			         |<----ring buffer length---->|
  
  The analog time is taken at the last stage of the playback, as close
  as possible to the actual transducer
  
  The link time is taken at the output of the SOC/chipset as the samples
  are pushed on a link. The link time can be directly measured if
  supported in hardware by sample counters or wallclocks (e.g. with
  HDAudio 24MHz or PTP clock for networked solutions) or indirectly
  estimated (e.g. with the frame counter in USB).
  
  The DMA time is measured using counters - typically the least reliable
  of all measurements due to the bursty natured of DMA transfers.
  
  The app time corresponds to the time tracked by an application after
  writing in the ring buffer.
  
  The application can query what the hardware supports, define which
  audio time it wants reported by selecting the relevant settings in
  audio_tstamp_config fields, get an estimate of the timestamp
  accuracy. It can also request the delay-to-analog be included in the
  measurement. Direct access to the link time is very interesting on
  platforms that provide an embedded DSP; measuring directly the link
  time with dedicated hardware, possibly synchronized with system time,
  removes the need to keep track of internal DSP processing times and
  latency.
  
  In case the application requests an audio tstamp that is not supported
  in hardware/low-level driver, the type is overridden as DEFAULT and the
  timestamp will report the DMA time based on the hw_pointer value.
  
  For backwards compatibility with previous implementations that did not
  provide timestamp selection, with a zero-valued COMPAT timestamp type
  the results will default to the HDAudio wall clock for playback
  streams and to the DMA time (hw_ptr) in all other cases.
  
  The audio timestamp accuracy can be returned to user-space, so that
  appropriate decisions are made:
  
  - for dma time (default), the granularity of the transfers can be
    inferred from the steps between updates and in turn provide
    information on how much the application pointer can be rewound
    safely.
  
  - the link time can be used to track long-term drifts between audio
    and system time using the (tstamp-trigger_tstamp)/audio_tstamp
    ratio, the precision helps define how much smoothing/low-pass
    filtering is required. The link time can be either reset on startup
    or reported as is (the latter being useful to compare progress of
    different streams - but may require the wallclock to be always
    running and not wrap-around during idle periods). If supported in
    hardware, the absolute link time could also be used to define a
    precise start time (patches WIP)
  
  - including the delay in the audio timestamp may
    counter-intuitively not increase the precision of timestamps, e.g. if a
    codec includes variable-latency DSP processing or a chain of
    hardware components the delay is typically not known with precision.
  
  The accuracy is reported in nanosecond units (using an unsigned 32-bit
  word), which gives a max precision of 4.29s, more than enough for
  audio applications...
  
  Due to the varied nature of timestamping needs, even for a single
  application, the audio_tstamp_config can be changed dynamically. In
  the STATUS ioctl, the parameters are read-only and do not allow for
  any application selection. To work around this limitation without
  impacting legacy applications, a new STATUS_EXT ioctl is introduced
  with read/write parameters. ALSA-lib will be modified to make use of
  STATUS_EXT and effectively deprecate STATUS.
  
  The ALSA API only allows for a single audio timestamp to be reported
  at a time. This is a conscious design decision, reading the audio
  timestamps from hardware registers or from IPC takes time, the more
  timestamps are read the more imprecise the combined measurements
  are. To avoid any interpretation issues, a single (system, audio)
  timestamp is reported. Applications that need different timestamps
  will be required to issue multiple queries and perform an
  interpolation of the results
  
  In some hardware-specific configuration, the system timestamp is
  latched by a low-level audio subsytem, and the information provided
  back to the driver. Due to potential delays in the communication with
  the hardware, there is a risk of misalignment with the avail and delay
  information. To make sure applications are not confused, a
  driver_timestamp field is added in the snd_pcm_status structure; this
  timestamp shows when the information is put together by the driver
  before returning from the STATUS and STATUS_EXT ioctl. in most cases
  this driver_timestamp will be identical to the regular system tstamp.
  
  Examples of typestamping with HDaudio:
  
  1. DMA timestamp, no compensation for DMA+analog delay
  $ ./audio_time  -p --ts_type=1
  playback: systime: 341121338 nsec, audio time 342000000 nsec, 	systime delta -878662
  playback: systime: 426236663 nsec, audio time 427187500 nsec, 	systime delta -950837
  playback: systime: 597080580 nsec, audio time 598000000 nsec, 	systime delta -919420
  playback: systime: 682059782 nsec, audio time 683020833 nsec, 	systime delta -961051
  playback: systime: 852896415 nsec, audio time 853854166 nsec, 	systime delta -957751
  playback: systime: 937903344 nsec, audio time 938854166 nsec, 	systime delta -950822
  
  2. DMA timestamp, compensation for DMA+analog delay
  $ ./audio_time  -p --ts_type=1 -d
  playback: systime: 341053347 nsec, audio time 341062500 nsec, 	systime delta -9153
  playback: systime: 426072447 nsec, audio time 426062500 nsec, 	systime delta 9947
  playback: systime: 596899518 nsec, audio time 596895833 nsec, 	systime delta 3685
  playback: systime: 681915317 nsec, audio time 681916666 nsec, 	systime delta -1349
  playback: systime: 852741306 nsec, audio time 852750000 nsec, 	systime delta -8694
  
  3. link timestamp, compensation for DMA+analog delay
  $ ./audio_time  -p --ts_type=2 -d
  playback: systime: 341060004 nsec, audio time 341062791 nsec, 	systime delta -2787
  playback: systime: 426242074 nsec, audio time 426244875 nsec, 	systime delta -2801
  playback: systime: 597080992 nsec, audio time 597084583 nsec, 	systime delta -3591
  playback: systime: 682084512 nsec, audio time 682088291 nsec, 	systime delta -3779
  playback: systime: 852936229 nsec, audio time 852940916 nsec, 	systime delta -4687
  playback: systime: 938107562 nsec, audio time 938112708 nsec, 	systime delta -5146
  
  Example 1 shows that the timestamp at the DMA level is close to 1ms
  ahead of the actual playback time (as a side time this sort of
  measurement can help define rewind safeguards). Compensating for the
  DMA-link delay in example 2 helps remove the hardware buffering abut
  the information is still very jittery, with up to one sample of
  error. In example 3 where the timestamps are measured with the link
  wallclock, the timestamps show a monotonic behavior and a lower
  dispersion.
  
  Example 3 and 4 are with USB audio class. Example 3 shows a high
  offset between audio time and system time due to buffering. Example 4
  shows how compensating for the delay exposes a 1ms accuracy (due to
  the use of the frame counter by the driver)
  
  Example 3: DMA timestamp, no compensation for delay, delta of ~5ms
  $ ./audio_time -p -Dhw:1 -t1
  playback: systime: 120174019 nsec, audio time 125000000 nsec, 	systime delta -4825981
  playback: systime: 245041136 nsec, audio time 250000000 nsec, 	systime delta -4958864
  playback: systime: 370106088 nsec, audio time 375000000 nsec, 	systime delta -4893912
  playback: systime: 495040065 nsec, audio time 500000000 nsec, 	systime delta -4959935
  playback: systime: 620038179 nsec, audio time 625000000 nsec, 	systime delta -4961821
  playback: systime: 745087741 nsec, audio time 750000000 nsec, 	systime delta -4912259
  playback: systime: 870037336 nsec, audio time 875000000 nsec, 	systime delta -4962664
  
  Example 4: DMA timestamp, compensation for delay, delay of ~1ms
  $ ./audio_time -p -Dhw:1 -t1 -d
  playback: systime: 120190520 nsec, audio time 120000000 nsec, 	systime delta 190520
  playback: systime: 245036740 nsec, audio time 244000000 nsec, 	systime delta 1036740
  playback: systime: 370034081 nsec, audio time 369000000 nsec, 	systime delta 1034081
  playback: systime: 495159907 nsec, audio time 494000000 nsec, 	systime delta 1159907
  playback: systime: 620098824 nsec, audio time 619000000 nsec, 	systime delta 1098824
  playback: systime: 745031847 nsec, audio time 744000000 nsec, 	systime delta 1031847