本文主要是介绍PCM data flow之一:概述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Linux kernel version:3.4.5
SoC:Samsung exynos
Userspace:tinyalsa
音频驱动主要有三部分组成:
1、 Platform:通常指某款SoC平台,如exynos、omap等等。Platform又可细分两部分:
1.1、CPU DAI:在嵌入式系统里面通常指CPU的I2S、PCM总线接口,负责将音频数据从AIF FIFO搬运到CODEC(Playback的情形,Capture则方向相反)。CPU DAI通过snd_soc_register_dai()来注册。注:DAI是Digital Audio Interface的缩写,分为CPU DAI和CODEC DAI,这两者通过I2S/PCM总线连接;AIF是Audio Interface的缩写,一般分为I2S和PCM接口。
1.2、DMA:负责将音频数据从userspace通过DMA操作搬运到AIF FIFO,这部分的逻辑比较复杂,以下几篇会对它详细阐述。DMA操作通过snd_soc_register_platform()来注册。值得留意的是:某些情形下是不需要DMA操作的,比如Modem和CODEC直连,因为Modem本身已经把数据送到它的PCM接口FIFO了,这时只需启动PCM接口把数据搬运到CODEC即可;在这种情形下,Machine驱动snd_soc_dai_link中需要指定.platform_name = "snd-soc-dummy", 这是虚拟出来的DMA驱动。
2、CODEC:对于Playback来说,userspace送过来的PCM数据是经过抽样量化出来的数字信号,在codec经过DAC转换成模拟信号送到外放耳机输出,这样我们就可以听到声音了。Codec字面意思是编解码器,但芯片里面的部件很多,常见的有AIF(音频接口)、DAC、ADC、Mixer、PGA、Line-in、Line-out,有些高端的codec芯片还有EQ、DSP、SRC、DRC、AGC、Echo canceller、Noise suppression等功能。
3、Machine:指某一款机器,它把CPU DAI、CODEC DAI、MODEM DAI各个音频总线接口通过定义dai_link链结起来,然后注册snd_soc_card。和上面两个不一样,Platform和CODEC驱动一般是可以重用的,而Machine有它特定的硬件特性,几乎是不可重用的。所谓的硬件特性指:DAIs之间的链结;通过某个GPIO打开Amplifier;通过某个GPIO检测耳机插拔;使用某个时钟如MCLK/External OSC作为I2S、CODEC模块的基准时钟源等等。
因此从上面的描述来看,对于Playback,PCM数据流向大致是:
- | DMA | | I2S/PCM | | AIF->DAC->PGA/Mixer |
- -----------> AIF FIFO ----------------> CODEC ----------------> SPK/HS/Earpiece
| DMA | | I2S/PCM | | AIF->DAC->PGA/Mixer |
userspace----------------> AIF FIFO ----------------> CODEC ----------------> SPK/HS/Earpiece
这系列初步定为如下几个部分:
1、 当pcm_open时,如何检查hw constraints(硬件特性限制,如支持的通道数/采样率/数据格式、DMA的period size和period count等);如何设置hw params(channels/sample rate/pcm format/period size/period count等);如何设置sw params(start_threshold/stop_threshold/silence_threshold等);如何调用platform/codec/machine的hw_params()回调函数。
2、 当pcm_write时,如何把pcm数据从userspace拷贝到dma_alloc_writecombine()分配出来的dma buffer中;如何触发platform/codec/machine的trigger()函数去启动DMA,把数据从dma buffer搬运到AIF FIFO。但在这之前,会先分析dma buffer分配过程,还有dma搬运的src源地址和dst目的地址如何设定,这部分平台相关。
3、 xrun出现的根源是什么?有些资料这样提及:“xrun指的是,声卡period一到,引发一个中断,告诉alsa驱动,要填入数据,或读走数据,但是问题在于alsa的读取和写入操作必须用户调用writei和readi才会发生的,它不会去缓存数据;如果上层没有用户调用writei和readi,那么就会产生 overrun(录制时,数据都满了,还没被读走)和underrun(需要数据来播放,却不写入数据),统称为xrun”。这里源码上分析它是如何产生的,这样我们知道需要正确配置好哪个参数才能更好避免xrun或取得更好的表现性能。
涉及到的源码文件:
- sound/core/pcm_native.c
- sound/core/pcm_lib.c
- sound/soc/samsung/i2s.c
- sound/soc/samsung/dma.c
- arch/arm/mm/dma-mapping.c
- arch/arm/plat-samsung/dma-ops.c
sound/core/pcm_native.c
sound/core/pcm_lib.c
sound/soc/samsung/i2s.c
sound/soc/samsung/dma.c
arch/arm/mm/dma-mapping.c
arch/arm/plat-samsung/dma-ops.c
可以看到只有pcm_native.c和pcm_lib.c是平台无关的,其他都平台相关。但不要紧,平台相关部分仅仅是dma的初始化和它的操作函数,这一部分在其他平台也是类似的,只是实现不大一致。
这篇关于PCM data flow之一:概述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!