ALSA期间的含义

时间:2014-06-04 14:48:18

标签: c linux audio alsa

我在Linux上使用ALSA和音频应用程序,我发现很棒的文档解释了如何使用它:1this one。虽然我有一些问题需要理解这部分设置:

 /* Set number of periods. Periods used to be called fragments. */ 
if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0) < 0) {
  fprintf(stderr, "Error setting periods.\n");
  return(-1);
}

当我使用播放模式时,意味着设置一段时间 并且:

/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame)     */
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize * periods)>>2) < 0) {
  fprintf(stderr, "Error setting buffersize.\n");
  return(-1);
}

以及关于延迟的相同问题,我该如何理解?

2 个答案:

答案 0 :(得分:12)

我假设您已阅读并理解this section of linux-journal。您还可以在ALSA的上下文中找到this blog澄清有关期间大小选择(或博客中的片段)的内容。引用:

  

你不应该滥用声音设备的片段逻辑。它就像   这样:

     
    

延迟由缓冲区大小定义        唤醒间隔由片段大小定义。

  
     

缓冲区填充水平将在“完全缓冲区”之间振荡。并且“满了   缓冲区减去1x片段大小减去OS调度延迟&#39;设置   较小的片段大小会增加CPU负载并减少电池电量   自从强制CPU更频繁地唤醒以来的时间。 OTOH它增加了   因为你先填满了播放缓冲区,所以安全性会降低。选择   因此,片段大小是你应该做的平衡   您在功耗和辍学安全之间的需求。随着现代   处理器和一个良好的操作系统调度程序,如Linux设置   片段大小不是缓冲区大小的一半而不是   很有意义。

     

...   (哦,ALSA使用术语&#39;期间&#39;用于我所称的&#39;片段&#39;   以上。它是同义词)

基本上,通常您会将period设置为2(就像您引用的howto中所做的那样)。然后periodsize * period是您的总缓冲区大小(以字节为单位)。最后,latency是由许多样本的缓冲引起的延迟,并且可以通过将缓冲区大小除以样本被回放的速率来计算(即,根据公式{{1}在代码注释中)。

例如,来自howto的参数:

  • period = 2
  • periodsize = 8192 bytes
  • rate = 44100Hz
  • 16位立体声数据(每帧4个字节)

对应的总缓冲区大小为latency = periodsize * periods / (rate * bytes_per_frame)字节,延迟为16384 /(44100 * 4)~0.093秒。

另请注意,您的硬件可能对支持的期间大小有一些大小限制(请参阅this trouble shooting guide

答案 1 :(得分:4)

当应用程序尝试将样本写入缓冲区时,如果缓冲区已满,则进程进入休眠状态。它被硬件通过中断唤醒;这个中断在每个时期结束时提出。

每个缓冲区应该至少有两个周期;否则,当唤醒发生时缓冲区已经为空,这会导致欠载。

增加周期数(即减少周期大小)会增加因调度或处理延迟而导致的欠载的安全边际。

延迟与缓冲区大小成正比:当您完全填充缓冲区时,只有在播放完所有其他样本后,硬件才会播放最后写的样本。