音频的采集和播放

音频的采集和播放主要由专门的codec芯片完成,主流的codec芯片厂商有Circus Logic、Wolfson等。采集时codec芯片经过A/D采样把声音的模拟信号转换成数字信号并经过I2S总线送给CPU处理,播放时CPU把处理好的数字信号经过I2S总线送给codec芯片并经过D/A转换为模拟信号播放出来。codec芯片除了A/D, D/A功能外还有其余功能,主要有1)对音频通路进行控制,好比播放音乐打电话等在codec芯片内部的流通线路是不同的。2)对音频信号作相应的处理,好比音量控制、功率放大、EQ控制等。linux

音频的采集和播放在软件上主要是写音频的驱动程序,同时提供接口给上层调用。我主要用过linux和android,而这两大系统又是嵌入式和手机上的主流系统,android又是基于linux的。本文主要讲这两大系统上的音频采集和播放软件开发。android

1,linuxspa

Linux中跟音频相关的就是大名鼎鼎的ALSA(Advanced Linux Sound Architecture)了。它是linux上的音频子系统,在kernel space和user space都有相应的代码。kernel space里主要是音频的驱动程序,user space里主要是alsa-lib,也就是提供接口给上层应用程序调用。 User space 和kernel space经过字符设备进行交互。设计

在kernel space里ALSA相关的叫ASOC(ALSA System On Chip), 它有三大模块组成:板载硬件(Machine)、Soc(Platform)、Codec,以下图所示:code

                                                            

Machine是指某一款具体的产品,由此能够看出Machine几乎是不可重用的,每一个Machine上的硬件实现可能都不同,CPU不同,Codec不同,音频的输入、输出设备也不同,Machine为CPU、Codec、输入输出设备提供了一个载体。Platform通常是指某一个SoC平台,只要指定了SoC,那么咱们能够认为它会有一个对应的Platform,它只与SoC相关,与Machine无关,这样咱们就能够把Platform抽象出来,使得同一款SoC不用作任何的改动,就能够用在不一样的Machine中。Codec和Platform同样,是可重用的部件,同一个Codec能够被不一样的Machine使用。orm

这三个模块都有相应的driver. Platform driver是cpu侧的音频驱动,主要由CPU芯片厂商负责编写,主要做用是完成音频数据的管理,经过CPU的数字音频接口(DAI)把音频数据传送给Codec进行处理,最终由Codec输出驱动耳机或者是喇叭的音信信号。在具体实现上,ASoC把Platform驱动分为两个部分:snd_soc_platform_driver和snd_soc_dai_driver。其中,platform_driver负责管理音频数据,把音频数据经过dma或其余操做传送至cpu dai中,dai_driver则主要完成cpu一侧的dai的参数配置,同时也会经过必定的途径把必要的dma等参数与snd_soc_platform_driver进行交互。blog

codec driver是codec芯片侧的音频驱动,主要由codec芯片厂商负责编写,主要做用在上面已说过。ASoC中的一个重要设计原则就是要求Codec驱动是平台无关的,它包含了一些音频的控件(Controls),音频接口,DAMP(动态音频电源管理)的定义和某些Codec IO功能。同platform driver同样,codec driver也分为两个部分:snd_soc_codec_driver和snd_soc_dai_driver,做用也同platform driver相似。接口

Machine driver主要是作产品的厂商编写(产品厂商会购买codec芯片CPU芯片作成一个能用的产品)。Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码。ip

ALSA 在User space里以ALSA-Lib存在,即提供API给应用程序调用。应用时主要有两种模式:block & nonblock,能够根据应用场景选择合适的模式。开发

ALSA是个庞大复杂的子系统,网上关于ALSA的内容特别多,包括kernel space和user space的,这里就很少叙述了。

2,Android

Android是基于linux的,即用的是linux的核,因此在音频驱动部分跟linux是同样的。不一样的是在user space 部分再也不用 ALSA-lib, 取而代之的是tinyalsa, 它是ALSA-Lib的裁剪。同时Android在Native层有media framework, 音频相关的模块有 AudioRecord/AudioTrack/AudioFlinger等,它们有层次关系,从上往下调用最终会调用tinyalsa的API跟kernel交互。

若是从事的是音频类的APP开发,kernel以及media framework都是不可见的,他们能够调用JAVA层提供的API实现音频功能,但这样会存在JAVA层和Native层之间的音频数据拷贝,效率较低,尤为是在实时通讯类APP中。建议使用 Android NDK 提供的 OpenSL ES API 接口,它支持在 native 层直接处理音频数据。OpenSL ES 调用Native层media framework中的AudioRecord/AudioTrack, 从而实现音频数据的采集和播放,这样音频数据就不会到JAVA层了,效率较高。JAVA层跟Native层主要经过JNI实现一些控制功能。

                                    

相关文章
相关标签/搜索