音频的采集和播放

音频的采集和播放主要由专门的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和android,而这两大系统又是嵌入式和手机上的主流系统,android又是基于linux的。本文主要讲这两大系统上的音频采集和播放软件开发。

1,linux

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,如下图所示:

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

这三个模块都有相应的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进行交互。

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之间的耦合以及部分和设备或板子特定的代码。

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实现一些控制功能。

时间: 2024-10-25 20:53:30

音频的采集和播放的相关文章

AudioToolbox--利用AudioQueue音频队列,通过缓存对声音进行采集与播放

都说iOS最恶心的部分是流媒体,其中恶心的恶心之处更在即时语音. 所以我们先不谈即时语音,研究一下,iOS中声音采集与播放的实现. 要在iOS设备上实现录音和播放功能,苹果提供了简单的做法,那就是利用AVAudioRecorder和AVAudioPlayer.度娘大多数 也是如此.但是这种方法有很大的局限性.单说说这种做法:录音,首先得设置录音文件路径,然后录音数据直接写入了文件.播放也是首先给出文件路径,等到音 频整个加载完成了,才能开始播放.这相当不灵活. 我的做法是利用音频队列AudioQ

iOS中声音采集与播放的实现(使用AudioQueue)

都说iOS最恶心的部分是流媒体,其中恶心的恶心之处更在即时语音. 所以我们先不谈即时语音,研究一下,iOS中声音采集与播放的实现. 要在iOS设备上实现录音和播放功能,苹果提供了简单的做法,那就是利用AVAudioRecorder和AVAudioPlayer.度娘大多数也是如此.但是这种方法有很大的局限性.单说说这种做法:录音,首先得设置录音文件路径,然后录音数据直接写入了文件.播放也是首先给出文件路径,等到音频整个加载完成了,才能开始播放.这相当不灵活. 我的做法是利用音频队列AudioQue

麦克风采集与播放 (源码)

在网络聊天系统中,采集麦克风的声音并将其播放出来,是最基础的模块之一.本文我们就介绍如何快速地实现这个基础模块. 一. 基础知识 有几个与声音采集和播放相关的专业术语必须要先了解一下,否则,后面的介绍将无法展开.语音采集指的是从麦克风采集音频数据,即声音样本转换成数字信号.其涉及到几个重要的参数:采样率.采样位数.声道数. 简单的来说: 采样率:即采样频率,就是在1秒内进行采集动作的次数. 采样位数:又叫采样深度,就是每次采集动作得到的数据长度,即使用多少个bit来记录一个样本. 声道数:一般是

C#实现麦克风采集与播放

在网络聊天系统中,采集麦克风的声音并将其播放出来,是最基础的模块之一.本文我们就介绍如何快速地实现这个基础模块. 一. 基础知识 有几个与声音采集和播放相关的专业术语必须要先了解一下,否则,后面的介绍将无法展开.语音采集指的是从麦克风采集音频数据,即声音样本转换成数字信号.其涉及到几个重要的参数:采样率.采样位数.声道数. 简单的来说: 采样率:即采样频率,就是在1秒内进行采集动作的次数. 采样位数:又叫采样深度,就是每次采集动作得到的数据长度,即使用多少个bit来记录一个样本. 声道数:一般是

java合并两段音频成一段 同时播放类似伴奏

/** * * @param partsPaths 要合成的音频路径数组 * @param unitedFilePath 输入合并结果数组 */ public void uniteWavFile(String[] partsPaths, String unitedFilePath) { byte byte1[] = getByte(partsPaths[0]); byte byte2[] = getByte(partsPaths[1]); byte[] out = new byte[byte1.

iOS开发拓展篇—音频处理(音乐播放器2)

iOS开发拓展篇—音频处理(音乐播放器2) 说明:该文主要介绍音乐播放界面的搭建. 一.跳转 1.跳转到音乐播放界面的方法选择 (1)使用模态跳转(又分为手动的和自动的) (2)使用xib并设置跳转 2.两种方法的分析 可以使用模态的方法,添加一个控制器,让这个控制器和音乐播放控制器类进行关联,脱线,设置标识符且在cell的点击事件中执行segue即可. 步骤说明: (1)在storyboard中新拖入一个控制器,然后设置和playing控制器类相关联. (2)设置手动跳转 (3)设置segue

iOS开发拓展篇—音频处理(音乐播放器5)

iOS开发拓展篇—音频处理(音乐播放器5) 实现效果: 一.半透明滑块的设置 1 /** 2 *拖动滑块 3 */ 4 - (IBAction)panSlider:(UIPanGestureRecognizer *)sender { 5 6 //1.获得挪动的距离 7 CGPoint t=[sender translationInView:sender.view]; 8 //把挪动清零 9 [sender setTranslation:CGPointZero inView:sender.view

iOS开发拓展篇—音频处理(音乐播放器3)

iOS开发拓展篇—音频处理(音乐播放器3) 说明:这篇文章主要介绍音频工具类和播放工具类的封装. 一.控制器间数据传递 1.两个控制器之间数据的传递 第一种方法:self.parentViewController.music=self.music[indexPath.row];不能满足 第二种做法:把整个数组传递给它 第三种做法:设置一个数据源,设置播放控制器的数据源是这个控制器.self.parentViewController.dataSource=self;好处:没有耦合性,任何实现了协议

iOS开发拓展篇—音频处理(音乐播放器6)

iOS开发拓展篇—音频处理(音乐播放器6) 一.图片处理 说明: Aspect表示按照原来的宽高比进行缩放. Aspectfit表示按照原来的宽高比缩放,要求看到全部图片,后果是不能完全覆盖窗口,会留有空白. Aspectfill表示按照原来的宽高比缩放,但只能看到部分图片.引发的问题:可能会有一部分超出屏幕. 所以,如果选择了Aspectfill模式,那么需要剪切超出的图片,在storyboard中也可以进行设置. 下面的两种设置是等效的. (1)在storyboard中进行设置 (2)使用代