ALSA中有几个“高分辨率”时间戳功能:
snd_pcm_status_get_trigger_htstamp
snd_pcm_status_get_audio_htstamp
snd_pcm_status_get_driver_htstamp
snd_pcm_status_get_htstamp
我想了解结果函数代表什么时间点.
我目前的理解是trigger_htstamp表示流启动/停止/暂停的时间. snd_pcm_status_get_trigger_htstamp返回一个常量值,当我将audio_htstamp添加到该值时,结果非常接近当前系统时间.
audio_htstamp似乎从我的系统上的零开始,并且增加了一个等于我使用的周期大小的值.因此在我的系统上它是一个简单的帧计数器.如果我理解ALSA正确,audio_htstamp也可以根据系统功能以更准确的方式工作.
driver_htstamp我猜这个名字是音频驱动程序生成的时间戳.
问题1:通常生成时间戳driver_htstamp是什么时候?
使用htstamp,我真的不确定它在何时何地生成.我预感它可能与DMA有关.
问题2:htstamp在哪里生成?
问题3:何时生成htstamp?
问题4:假设是audio_htstamp< htstamp< driver_htstamp一般是否正确? 这似乎是我写的一个小测试program,但我想验证我的假设.
我在ALSA文档中找不到此信息.
解决方法:
我只是为了我自己的目的挖掘了这些东西的代码,所以我想我会分享我发现的东西.
这些时间戳的目的是让您确定不同时钟速率的细微差别;最重要的是,在这种情况下,Linux用于一般计时的主系统时钟与确定样本移入和移出声音设备的速率的不同时钟相比较.这对于需要保持来自不同硬件设备的音频同步的应用非常重要,因为不同物理时钟的速率永远不会完全相同.
使用的技术有时被称为“交叉时间戳”;您从要比较的时钟中尽可能接近地捕获时间戳,并定期重复此时间戳.通常会引入一些测量误差,但是一些相对简单的滤波可以很好地表征时钟计数速率的差异.
核心PCM驱动程序安排在音频流启动时尽可能接近系统时钟时间戳,然后在询问系统时钟和音频时钟(可以以不同方式测量)之间进行交叉时间戳检查移动样本的DMA引擎的硬件指针的状态.
测量音频时钟的默认方法是通过DMA硬件指针比较.这不是非常精确,但在更长的时间内,您仍然可以很好地衡量速率差异.在snd_pcm_update_hw_ptr0开始时,捕获系统时间戳;这将最终成为htstamp.然后检查DMA指针,如果确定它们自上次检查后已移动,则根据DMA复制的帧数和音频时钟的标称频率计算audio_htstamp.然后,一旦完成所有DMA指针更新并且在snd_pcm_update_hw_ptr0返回之前,就会在driver_htstamp中捕获另一个系统时间戳.当您使用DMA hw_ptr方法计算audio_htstamp时,这并不意味着要使用.
如果您碰巧使用HDAudio驱动程序的音频设备,您可以使用另一种更精确的方法来测量音频时钟.它提供了一个名为get_time_info的额外操作回调,用于代替捕获系统和音频时间戳的默认方法.在HDAudio的情况下,htstamp的系统时间戳尽可能接近当它读取由与音频时钟相同的时钟源驱动的内部计数器时;这形成了audio_htstamp.之后,完成相同的DMA hw_ptr簿记,但跳过将指针移动转换为时间的代码.但是,在例程结束之前,driver_htstamp仍然处于正常状态;这是“让应用程序检测低级硬件读取的参考tstamp是否提供延迟”,如代码中的注释所示.这是因为无法保证get_time_info回调将采用新的系统时间戳;它可能先前已记录音频时间戳以及系统时间戳作为中断处理程序的一部分.在这种情况下,您获得的时间戳可能与hw_ptr簿记计算的可用帧和延迟帧计数不匹配,但driver_htstamp将告知您进行这些计算时最接近的系统时间.
在任何情况下,代码都设计为在两种情况下尽可能紧密地捕获htstamp和audio_htstamp,并且对于htstamp – trigger_htstamp来表示在音频时钟的audio_htstamp测量的时段期间经过的系统时间量.你大多不需要使用driver_htstamp,但我想它可能会与USB音频驱动程序一起使用,因为我认为它和HDAudio是唯一对这些接口做任何特殊处理的人.
虽然它不包含您可能想知道的所有详细信息,但是它的文档是内核文档的一部分:http://lxr.free-electrons.com/source/Documentation/sound/alsa/timestamping.txt?v=4.9