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