snd_pcm_runtime结构几乎包含了音频缓冲逻辑所有的信息:
snd_pcm_uframes_t(无符号类型)与snd_pcm_sframes_t(有符号类型)为内核中音频帧的单位。snd_pcm_substream结构的runtime成员用于记录缓冲的运行状态。内核环形缓冲实际大小为runtime->buffer_size(音频帧),基地址为runtime->dma_area。应用层读写指针为runtime->control->appl_ptr,硬件读写指针为runtime->status->hw_ptr。为了计算方便,内核将这个缓冲虚拟成runtime->boundary大小:
runtime->control->appl_ptr的范围从0到runtime->boundary,但实际写数据时的地址会映射到runtime->dma_area开始的区域:
appl_ofs=appl_ptr%runtime->buffer_size;
ALSA环形缓冲逻辑如图15-6所示。
图15-6 ALSA音频缓冲逻辑
应用层调用Alsalib的snd_pcm_writei函数写音频数据,snd_pcm_writei函数通过IOCTL命令(SNDRV_PCM_IOCTL_WRITEI_FRAMES)向内核写入音频数据,该命令会调用内核的snd_pcm_lib_write1函数,而snd_pcm_lib_write1函数会根据runtime->control->appl_ptr找到当前应用指针,复制应用层的数据到内核后更新runtime->control->appl_ptr:
(www.xing528.com)
DMA控制器每次传输runtime->period_size个音频帧,传输完毕会调用snd_pcm_update_hw_ptr0函数更新硬件指针,并进行下一次runtime->period_size个音频帧的传输,周而复始。
snd_pcm_playback_hw_avail函数返回已经到达的音频数据:
snd_pcm_playback_avail函数返回剩余音频缓冲:
runtime->start_threshold是声卡处于准备状态时启动音频播放的缓冲阈值,内核缓冲的数据量大于这个阈值,则启动播放。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。