Hi,
To determine the timestamp of captured audio, we do something along the lines:
ts = snd_pcm_status_get_htstamp() - time(snd_pcm_status_get_delay()) snd_pcm_readi(buf) process(buf, ts)
However for PCM drivers that only update its hw_pointer in steps of periods (in irq-handler), the attributes in snd_pcm_status() struct will not be in sync even though ALSA thinks so. For example, the avail property will correspond to the time of the last IRQ, not at the specified timestamp returned by snd_pcm_status_get_htstamp(). This will introduce timestamp jitter which depends on system IRQ latency and also when the userspace application issues it syscall to read status. For an embedded system under heavy load, the A/V sync is unacceptable when using ALSA timestamps.
Several mainline PCM drivers do this kind of hw-pointer caching in their irq handlers, perhaps because the DMA HW does not support progress counting.
Possible solutions:
1) If DMA HW supports progress counter, implement it.
2) If DMA HW is not supported, implement it in software (estimate position using elapsed time since last irq). Only requires driver changes.
3) If DMA HW is not supported, return use last irq timestamp as the timestamp returned by snd_pcm_status_get_htstamp() . Probably requires ALSA Core changes.
I've tested 1) and results in much improved A/V sync on our systems. If would be kind of convenient if ALSA SoC Core could provide a generic pointercallback for solution 2), if the PCM driver specifies that it does not support HW progress counter. Otherwise we will see a lot of duplicate code for estimating position. AFAIK, ALSA already maintains a timestamp for last irq.
Magnus Olsson Axis Communications / Product Platforms