18c2ecf20Sopenharmony_ci=====================
28c2ecf20Sopenharmony_ciALSA PCM Timestamping
38c2ecf20Sopenharmony_ci=====================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciThe ALSA API can provide two different system timestamps:
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci- Trigger_tstamp is the system time snapshot taken when the .trigger
88c2ecf20Sopenharmony_ci  callback is invoked. This snapshot is taken by the ALSA core in the
98c2ecf20Sopenharmony_ci  general case, but specific hardware may have synchronization
108c2ecf20Sopenharmony_ci  capabilities or conversely may only be able to provide a correct
118c2ecf20Sopenharmony_ci  estimate with a delay. In the latter two cases, the low-level driver
128c2ecf20Sopenharmony_ci  is responsible for updating the trigger_tstamp at the most appropriate
138c2ecf20Sopenharmony_ci  and precise moment. Applications should not rely solely on the first
148c2ecf20Sopenharmony_ci  trigger_tstamp but update their internal calculations if the driver
158c2ecf20Sopenharmony_ci  provides a refined estimate with a delay.
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci- tstamp is the current system timestamp updated during the last
188c2ecf20Sopenharmony_ci  event or application query.
198c2ecf20Sopenharmony_ci  The difference (tstamp - trigger_tstamp) defines the elapsed time.
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ciThe ALSA API provides two basic pieces of information, avail
228c2ecf20Sopenharmony_ciand delay, which combined with the trigger and current system
238c2ecf20Sopenharmony_citimestamps allow for applications to keep track of the 'fullness' of
248c2ecf20Sopenharmony_cithe ring buffer and the amount of queued samples.
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciThe use of these different pointers and time information depends on
278c2ecf20Sopenharmony_cithe application needs:
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci- ``avail`` reports how much can be written in the ring buffer
308c2ecf20Sopenharmony_ci- ``delay`` reports the time it will take to hear a new sample after all
318c2ecf20Sopenharmony_ci  queued samples have been played out.
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ciWhen timestamps are enabled, the avail/delay information is reported
348c2ecf20Sopenharmony_cialong with a snapshot of system time. Applications can select from
358c2ecf20Sopenharmony_ci``CLOCK_REALTIME`` (NTP corrections including going backwards),
368c2ecf20Sopenharmony_ci``CLOCK_MONOTONIC`` (NTP corrections but never going backwards),
378c2ecf20Sopenharmony_ci``CLOCK_MONOTIC_RAW`` (without NTP corrections) and change the mode
388c2ecf20Sopenharmony_cidynamically with sw_params
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciThe ALSA API also provide an audio_tstamp which reflects the passage
428c2ecf20Sopenharmony_ciof time as measured by different components of audio hardware.  In
438c2ecf20Sopenharmony_ciascii-art, this could be represented as follows (for the playback
448c2ecf20Sopenharmony_cicase):
458c2ecf20Sopenharmony_ci::
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci  --------------------------------------------------------------> time
488c2ecf20Sopenharmony_ci    ^               ^              ^                ^           ^
498c2ecf20Sopenharmony_ci    |               |              |                |           |
508c2ecf20Sopenharmony_ci   analog         link            dma              app       FullBuffer
518c2ecf20Sopenharmony_ci   time           time           time              time        time
528c2ecf20Sopenharmony_ci    |               |              |                |           |
538c2ecf20Sopenharmony_ci    |< codec delay >|<--hw delay-->|<queued samples>|<---avail->|
548c2ecf20Sopenharmony_ci    |<----------------- delay---------------------->|           |
558c2ecf20Sopenharmony_ci                                   |<----ring buffer length---->|
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciThe analog time is taken at the last stage of the playback, as close
598c2ecf20Sopenharmony_cias possible to the actual transducer
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciThe link time is taken at the output of the SoC/chipset as the samples
628c2ecf20Sopenharmony_ciare pushed on a link. The link time can be directly measured if
638c2ecf20Sopenharmony_cisupported in hardware by sample counters or wallclocks (e.g. with
648c2ecf20Sopenharmony_ciHDAudio 24MHz or PTP clock for networked solutions) or indirectly
658c2ecf20Sopenharmony_ciestimated (e.g. with the frame counter in USB).
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciThe DMA time is measured using counters - typically the least reliable
688c2ecf20Sopenharmony_ciof all measurements due to the bursty nature of DMA transfers.
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciThe app time corresponds to the time tracked by an application after
718c2ecf20Sopenharmony_ciwriting in the ring buffer.
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciThe application can query the hardware capabilities, define which
748c2ecf20Sopenharmony_ciaudio time it wants reported by selecting the relevant settings in
758c2ecf20Sopenharmony_ciaudio_tstamp_config fields, thus get an estimate of the timestamp
768c2ecf20Sopenharmony_ciaccuracy. It can also request the delay-to-analog be included in the
778c2ecf20Sopenharmony_cimeasurement. Direct access to the link time is very interesting on
788c2ecf20Sopenharmony_ciplatforms that provide an embedded DSP; measuring directly the link
798c2ecf20Sopenharmony_citime with dedicated hardware, possibly synchronized with system time,
808c2ecf20Sopenharmony_ciremoves the need to keep track of internal DSP processing times and
818c2ecf20Sopenharmony_cilatency.
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ciIn case the application requests an audio tstamp that is not supported
848c2ecf20Sopenharmony_ciin hardware/low-level driver, the type is overridden as DEFAULT and the
858c2ecf20Sopenharmony_citimestamp will report the DMA time based on the hw_pointer value.
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ciFor backwards compatibility with previous implementations that did not
888c2ecf20Sopenharmony_ciprovide timestamp selection, with a zero-valued COMPAT timestamp type
898c2ecf20Sopenharmony_cithe results will default to the HDAudio wall clock for playback
908c2ecf20Sopenharmony_cistreams and to the DMA time (hw_ptr) in all other cases.
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciThe audio timestamp accuracy can be returned to user-space, so that
938c2ecf20Sopenharmony_ciappropriate decisions are made:
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci- for dma time (default), the granularity of the transfers can be
968c2ecf20Sopenharmony_ci  inferred from the steps between updates and in turn provide
978c2ecf20Sopenharmony_ci  information on how much the application pointer can be rewound
988c2ecf20Sopenharmony_ci  safely.
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci- the link time can be used to track long-term drifts between audio
1018c2ecf20Sopenharmony_ci  and system time using the (tstamp-trigger_tstamp)/audio_tstamp
1028c2ecf20Sopenharmony_ci  ratio, the precision helps define how much smoothing/low-pass
1038c2ecf20Sopenharmony_ci  filtering is required. The link time can be either reset on startup
1048c2ecf20Sopenharmony_ci  or reported as is (the latter being useful to compare progress of
1058c2ecf20Sopenharmony_ci  different streams - but may require the wallclock to be always
1068c2ecf20Sopenharmony_ci  running and not wrap-around during idle periods). If supported in
1078c2ecf20Sopenharmony_ci  hardware, the absolute link time could also be used to define a
1088c2ecf20Sopenharmony_ci  precise start time (patches WIP)
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci- including the delay in the audio timestamp may
1118c2ecf20Sopenharmony_ci  counter-intuitively not increase the precision of timestamps, e.g. if a
1128c2ecf20Sopenharmony_ci  codec includes variable-latency DSP processing or a chain of
1138c2ecf20Sopenharmony_ci  hardware components the delay is typically not known with precision.
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ciThe accuracy is reported in nanosecond units (using an unsigned 32-bit
1168c2ecf20Sopenharmony_ciword), which gives a max precision of 4.29s, more than enough for
1178c2ecf20Sopenharmony_ciaudio applications...
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ciDue to the varied nature of timestamping needs, even for a single
1208c2ecf20Sopenharmony_ciapplication, the audio_tstamp_config can be changed dynamically. In
1218c2ecf20Sopenharmony_cithe ``STATUS`` ioctl, the parameters are read-only and do not allow for
1228c2ecf20Sopenharmony_ciany application selection. To work around this limitation without
1238c2ecf20Sopenharmony_ciimpacting legacy applications, a new ``STATUS_EXT`` ioctl is introduced
1248c2ecf20Sopenharmony_ciwith read/write parameters. ALSA-lib will be modified to make use of
1258c2ecf20Sopenharmony_ci``STATUS_EXT`` and effectively deprecate ``STATUS``.
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ciThe ALSA API only allows for a single audio timestamp to be reported
1288c2ecf20Sopenharmony_ciat a time. This is a conscious design decision, reading the audio
1298c2ecf20Sopenharmony_citimestamps from hardware registers or from IPC takes time, the more
1308c2ecf20Sopenharmony_citimestamps are read the more imprecise the combined measurements
1318c2ecf20Sopenharmony_ciare. To avoid any interpretation issues, a single (system, audio)
1328c2ecf20Sopenharmony_citimestamp is reported. Applications that need different timestamps
1338c2ecf20Sopenharmony_ciwill be required to issue multiple queries and perform an
1348c2ecf20Sopenharmony_ciinterpolation of the results
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ciIn some hardware-specific configuration, the system timestamp is
1378c2ecf20Sopenharmony_cilatched by a low-level audio subsystem, and the information provided
1388c2ecf20Sopenharmony_ciback to the driver. Due to potential delays in the communication with
1398c2ecf20Sopenharmony_cithe hardware, there is a risk of misalignment with the avail and delay
1408c2ecf20Sopenharmony_ciinformation. To make sure applications are not confused, a
1418c2ecf20Sopenharmony_cidriver_timestamp field is added in the snd_pcm_status structure; this
1428c2ecf20Sopenharmony_citimestamp shows when the information is put together by the driver
1438c2ecf20Sopenharmony_cibefore returning from the ``STATUS`` and ``STATUS_EXT`` ioctl. in most cases
1448c2ecf20Sopenharmony_cithis driver_timestamp will be identical to the regular system tstamp.
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ciExamples of timestamping with HDAudio:
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci1. DMA timestamp, no compensation for DMA+analog delay
1498c2ecf20Sopenharmony_ci::
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci  $ ./audio_time  -p --ts_type=1
1528c2ecf20Sopenharmony_ci  playback: systime: 341121338 nsec, audio time 342000000 nsec, 	systime delta -878662
1538c2ecf20Sopenharmony_ci  playback: systime: 426236663 nsec, audio time 427187500 nsec, 	systime delta -950837
1548c2ecf20Sopenharmony_ci  playback: systime: 597080580 nsec, audio time 598000000 nsec, 	systime delta -919420
1558c2ecf20Sopenharmony_ci  playback: systime: 682059782 nsec, audio time 683020833 nsec, 	systime delta -961051
1568c2ecf20Sopenharmony_ci  playback: systime: 852896415 nsec, audio time 853854166 nsec, 	systime delta -957751
1578c2ecf20Sopenharmony_ci  playback: systime: 937903344 nsec, audio time 938854166 nsec, 	systime delta -950822
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci2. DMA timestamp, compensation for DMA+analog delay
1608c2ecf20Sopenharmony_ci::
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci  $ ./audio_time  -p --ts_type=1 -d
1638c2ecf20Sopenharmony_ci  playback: systime: 341053347 nsec, audio time 341062500 nsec, 	systime delta -9153
1648c2ecf20Sopenharmony_ci  playback: systime: 426072447 nsec, audio time 426062500 nsec, 	systime delta 9947
1658c2ecf20Sopenharmony_ci  playback: systime: 596899518 nsec, audio time 596895833 nsec, 	systime delta 3685
1668c2ecf20Sopenharmony_ci  playback: systime: 681915317 nsec, audio time 681916666 nsec, 	systime delta -1349
1678c2ecf20Sopenharmony_ci  playback: systime: 852741306 nsec, audio time 852750000 nsec, 	systime delta -8694
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci3. link timestamp, compensation for DMA+analog delay
1708c2ecf20Sopenharmony_ci::
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci  $ ./audio_time  -p --ts_type=2 -d
1738c2ecf20Sopenharmony_ci  playback: systime: 341060004 nsec, audio time 341062791 nsec, 	systime delta -2787
1748c2ecf20Sopenharmony_ci  playback: systime: 426242074 nsec, audio time 426244875 nsec, 	systime delta -2801
1758c2ecf20Sopenharmony_ci  playback: systime: 597080992 nsec, audio time 597084583 nsec, 	systime delta -3591
1768c2ecf20Sopenharmony_ci  playback: systime: 682084512 nsec, audio time 682088291 nsec, 	systime delta -3779
1778c2ecf20Sopenharmony_ci  playback: systime: 852936229 nsec, audio time 852940916 nsec, 	systime delta -4687
1788c2ecf20Sopenharmony_ci  playback: systime: 938107562 nsec, audio time 938112708 nsec, 	systime delta -5146
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ciExample 1 shows that the timestamp at the DMA level is close to 1ms
1818c2ecf20Sopenharmony_ciahead of the actual playback time (as a side time this sort of
1828c2ecf20Sopenharmony_cimeasurement can help define rewind safeguards). Compensating for the
1838c2ecf20Sopenharmony_ciDMA-link delay in example 2 helps remove the hardware buffering but
1848c2ecf20Sopenharmony_cithe information is still very jittery, with up to one sample of
1858c2ecf20Sopenharmony_cierror. In example 3 where the timestamps are measured with the link
1868c2ecf20Sopenharmony_ciwallclock, the timestamps show a monotonic behavior and a lower
1878c2ecf20Sopenharmony_cidispersion.
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ciExample 3 and 4 are with USB audio class. Example 3 shows a high
1908c2ecf20Sopenharmony_cioffset between audio time and system time due to buffering. Example 4
1918c2ecf20Sopenharmony_cishows how compensating for the delay exposes a 1ms accuracy (due to
1928c2ecf20Sopenharmony_cithe use of the frame counter by the driver)
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ciExample 3: DMA timestamp, no compensation for delay, delta of ~5ms
1958c2ecf20Sopenharmony_ci::
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci  $ ./audio_time -p -Dhw:1 -t1
1988c2ecf20Sopenharmony_ci  playback: systime: 120174019 nsec, audio time 125000000 nsec, 	systime delta -4825981
1998c2ecf20Sopenharmony_ci  playback: systime: 245041136 nsec, audio time 250000000 nsec, 	systime delta -4958864
2008c2ecf20Sopenharmony_ci  playback: systime: 370106088 nsec, audio time 375000000 nsec, 	systime delta -4893912
2018c2ecf20Sopenharmony_ci  playback: systime: 495040065 nsec, audio time 500000000 nsec, 	systime delta -4959935
2028c2ecf20Sopenharmony_ci  playback: systime: 620038179 nsec, audio time 625000000 nsec, 	systime delta -4961821
2038c2ecf20Sopenharmony_ci  playback: systime: 745087741 nsec, audio time 750000000 nsec, 	systime delta -4912259
2048c2ecf20Sopenharmony_ci  playback: systime: 870037336 nsec, audio time 875000000 nsec, 	systime delta -4962664
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ciExample 4: DMA timestamp, compensation for delay, delay of ~1ms
2078c2ecf20Sopenharmony_ci::
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci  $ ./audio_time -p -Dhw:1 -t1 -d
2108c2ecf20Sopenharmony_ci  playback: systime: 120190520 nsec, audio time 120000000 nsec, 	systime delta 190520
2118c2ecf20Sopenharmony_ci  playback: systime: 245036740 nsec, audio time 244000000 nsec, 	systime delta 1036740
2128c2ecf20Sopenharmony_ci  playback: systime: 370034081 nsec, audio time 369000000 nsec, 	systime delta 1034081
2138c2ecf20Sopenharmony_ci  playback: systime: 495159907 nsec, audio time 494000000 nsec, 	systime delta 1159907
2148c2ecf20Sopenharmony_ci  playback: systime: 620098824 nsec, audio time 619000000 nsec, 	systime delta 1098824
2158c2ecf20Sopenharmony_ci  playback: systime: 745031847 nsec, audio time 744000000 nsec, 	systime delta 1031847
216