ALSA子系统(一)------Frames Periods

你好!这里是风筝的博客,

欢迎和我一起交流。


FramesPeriods

一帧(frame)相当于要播放的一个样本,而与通道数或位数无关。
例如

  • 1帧立体声48khz 16位PCM流为4字节.
  • 1帧5.1声道 48khz 16位PCM流为12字节.

一个周期(period)是每个硬件中断之间的帧数。 poll()将每个周期返回一次。

缓冲区(buffer)是环形缓冲区。缓冲区大小必须始终大于一个周期大小,通常是2 * 周期的大小,但是某些硬件每个缓冲区可以做到支持8个周期,缓冲区大小也可能不是周期大小的整数倍。

现在,如果硬件已设置为48K Hz,2个周期,每个周期有1024个帧,缓冲区大小为2048帧。硬件将处理每个缓冲区会中断2次。 ALSA将努力保证缓冲区尽可能是满的。一旦播放了第一周期的样本(samples ),则将第三周期的样本数据转移到第一周期样本数据所占用的空间,同时播放第二周期样本。 (正常的环形缓冲区行为)。

Additional example

这是上述讨论的替代示例。

假设我们要处理一个立体声,16位,44.1 KHz的音频流,单向的(即播放或录音)。 然后我们有:

  • 立体声(stereo) = 2通道
  • 1个模拟样本(analog sample)16位= 2字节
  • 1帧代表来自所有通道的1个模拟样本; 这里我们有2个通道,依此类推:
    • 1帧=(通道数)(以字节为单位的1个样本大小)=(2个通道)(每个样本2个字节(16位))= 4个字节(32位)
  • 要维持2x 44.1 KHz模拟采样率,系统必须能够支持以Bytes / sec为单位的数据传输速率:
    • bsp_rate =(通道数)(以字节为单位的1个样本大小)(采样率)=(1帧)(采样率)=(2个通道)(2个字节/样本)*(44100样本/秒)= 2 * 2 * 44100 = 176400字节/秒
      ALSA子系统(一)------Frames Periods_第1张图片

现在,如果ALSA每秒中断一次,对于请求的字节大小,我们需要每秒准备好176400字节(在每秒结束时),以便在44.1Khz上维持16位模拟立体声。

  • 如果它每半秒钟中断一次,则对于相同的流,对于每个中断我们需要准备176400/2 = 88200字节;
  • 如果中断每100毫秒触发一次,则对于每个中断我们需要准备176400 *(0.1 / 1)= 17640字节。

通过设置以帧为单位的周期大小,我们可以控制何时生成此PCM中断。

  • 因此,如果我们设置16位双通道44.1k的音频流,并且period_size为4410帧=>(对于16位双通道 44.1Khz,则1帧等于4个字节,因此4410帧等于4410 * 4 = 17640字节)=> 每17640字节(即每100毫秒)将产生一个中断。
  • 相应地,buffer_size应该至少为2 * period_size = 2 * 4410 = 8820帧(或8820 * 4 = 35280字节)。

ALSA是运行时来决定实际的buffer_size和period_size,具体取决于:请求的通道数及其各自的属性(速率和采样分辨率) ,以及在snd_pcm_hardware结构中设置的参数(在驱动程序中)。

“帧”(frames)代表单位,1帧=通道 * sample_bytes。
在您的情况下,一帧对应于2个通道x 16位= 4字节。

周期是指环形缓冲区中的周期数。 在OSS中,称为作为“片段”。

所以

  • buffer_size = period_size *周期
  • period_bytes = period_size * bytes_per_frame
  • bytes_per_frame =通道* bytes_per_sample

我还是不明白’period_size’和’period’是什么?

“period”定义了更新状态的频率,通常通过中断的调用。
“ period_size”定义帧大小对应于“period time”。
这个术语对应于OSS上的“片段大小”。 在主要的声音硬件上,环形缓冲区分为几部分,并在每个边界上产生一个irq。
period_size定义此块的大小。

在某些硬件上,irq是根据计时器控制的。 在这种情况下,将周期定义为调用irq的计时器频率。

来自:https://alsa-project.org/main/index.php/FramesPeriods

你可能感兴趣的:(ALSA子系统,alsa,period_size,period,period_count)