本篇谈谈Alsa驱动中的buffer,主要介绍下相关的名词变量,这些变量是理解代码的关键。

以下内容清楚的解释了相关概念,见参考资料1

Sample:样本长度,音频数据最基本的单位,常见的有8位和16位。

Channel:声道数分为单声道mono和立体声stereo。

Frame:帧,构成一个完整的声音单元,Frame = Sample * channel。

Rate:又称Sample rate,采样率,即每秒的采样次数,针对帧而言。

Interleaved:交错模式,一种音频数据的记录方式,在交错模式下,数据以连续桢的形式存放,即首先记录完桢1的左声道样本和右声道样本(假设为立体声),再开始桢2的记录。而在非交错模式下,首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。多数情况下使用交错模式。

Period size:周期,每次硬件中断处理音频数据的帧数,对于音频设备的数据读写,以此为单位。

Buffer size:数据缓冲区大小,这里特指runtime的buffer size,而不是snd_pcm_hardware定义的buffer_bytes_max。一般来说Buffer size =period_size * period_count,period_count相当于处理完一个buffer数据所需的硬件中断次数。

下面一张图直观的表示buffer/period/frame/sample之间的关系:

eda软件具有逻辑功能的有哪些(Alsa音频驱动中的缓冲区分析一相关名词解释)(1)

eda软件具有逻辑功能的有哪些(Alsa音频驱动中的缓冲区分析一相关名词解释)(2)

start_threshold:缓冲区的数据超过该值时,硬件开始启动数据传输。如果太大, 从开始播放到声音出来时延太长,甚至可导致太短促的声音根本播不出来;如果太小, 又可能容易导致XRUN.

stop_threshold:缓冲区空闲区大于该值时,硬件停止传输。默认情况下,这个数 为整个缓冲区的大小,即整个缓冲区空了,就停止传输。但偶尔的原因导致缓冲区空, 如CPU忙,增大该值,继续播放缓冲区的历史数据,而不关闭再启动硬件传输(一般此 时有明显的声音卡顿),可以达到更好的体验

eda软件具有逻辑功能的有哪些(Alsa音频驱动中的缓冲区分析一相关名词解释)(3)

默认值

eda软件具有逻辑功能的有哪些(Alsa音频驱动中的缓冲区分析一相关名词解释)(4)

silence_threshold. 这个值本来是配合stop_threshold使用,往缓冲区填充静音 数据,这样就不会重播历史数据了。

用户空间配置stop_threshold可选择方案1或方案2,配置silence_threshold选择继 续播放的原有的音频数据还是静意数据了。个人经验,偶尔的系统繁忙导致的这种状态, 重复播放原有的音频数据会显得更平滑,效果更好。

在不同的场景下,合理的参数就是在性能、时延、功耗等之间达到较好的平衡。

eda软件具有逻辑功能的有哪些(Alsa音频驱动中的缓冲区分析一相关名词解释)(5)

见参考资料2

hw_ptr_base:当前HW buffer在Ring buffer中的起始位置。当读指针到达HW buffer尾部时,hw_ptr_base按buffer size移动.

hw_ptr:HW buffer的读指针。alsa driver将数据从HW buffer中读走并送到声卡硬件时,hw_ptr就会移动到新位置。

appl_ptr:HW buffer的写指针。app在调用snd_pcm_write写数据,alsa core将数据copy到HW buffer后,appl_ptr就更新。

boundary:Ring buffer边界。hw_ofs是读指针在当前HW buffer中的位置。由alsa driver的pointer()返回。

appl_ofs:是写指针在当前HW buffer中的位置。 hw_ptr的更新是通过调用snd_pcm_update_hw_ptr0完成。

音频搬运数据少不了DMA的参与,在sound系统中和DMA引擎相关的代码在sound/core/pcm_dmaengine.c中,DMA传输大概分成如下3步:

  1. dmaengine_pcm_prepare_and_submit初始化一个具体的DMA传输描述符,并插入到DMA引擎的传输队列, 其中dmaengine_prep_dma_cyclic初始化一个具体的周期性的DMA传输描述符号,sound系统中的period_size参数在这设置到DMA引擎中
  2. 调用dma_async_issue_pending启动DMA对应通道的传输。
  3. DMA周期完成后会调用回调函数 dmaengine_pcm_dma_complete

另外由于谈及buffer少不了延迟,https://www.alsa-project.org/main/index.php/Test_latency.c提供了测试驱动层delay的小程序,感兴趣的可以时间跑一下。

参考资料:

  1. https://blog.csdn.net/donkeymoto/article/details/19085599
  2. http://www.echojb.com/hardware/2016/12/21/283392.html

,