1.1 音频框架
转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492
Android的音频系统在很长一段时间内都是外界诟病的焦点。的确,早期的Android系统在音频处理上相比于IOS有一定的差距,这也是很多专业的音乐播放软件开发商没有推出Android平台产品的一个重要原因。但这并不代表它的音频框架一无是处,相反,基于Linux系统的Android平台有很多值得我们学习的地方。
1.1.1 Linux下的音频框架
在计算机发展的早期,电脑的声音处理设备是由一个非常简易的loudspeaker外加发声器(Tone Generator)构成的,功能相对局限。后来人们想到了以plug-in的形式来扩展音频设备,“Sound blaster”就是其中很有名的一个。这种早期的声卡以插件方式连接到电脑主板上,并提供了更多复杂的音频设备。可想而知,独立的硬件设计也意味着成本的增加,于是随着技术的发展,便又出现了板载声卡,也就是我们俗称的“集成声卡”。板载声卡又分为“软声卡”和“硬声卡”。如果声卡本身没有主处理芯片,而只有解码芯片,需要通过CPU运算来执行处理工作,那么就是“软声卡”,反之就是“硬声卡”。通常面向低端市场的计算机都会包含一个集成的声卡设备以降低成本。
一个典型的声卡通常包含三个部分:
· Connectors
用于声卡与外放设备,如扬声器、耳机的连接,又被称为“jacks”
· Audio Circuits
声卡的主要实现体,它负责信号的放大、混音、以及模拟数字转换等操作
· Inte易做图ce
连接声卡与计算机总线的单元,比如PCI总线
我们可以通过“cat/proc/asound/cards”命令来查看计算机中安装的声卡设备,如下例子所示:
目前市面上声卡的种类众多,既有复杂的高性能的,也有低端的简易的,那么对于一个操作系统来说,它如何管理这些音频设备,并向上层应用提供统一的接口呢?
Android严格来讲只是一个Linux系统,它依赖于内核提供的各种驱动支持,包括音频驱动。因此我们有必要先花点时间来学习下Linux平台下的两种主要的音频驱动架构:
· OSS (Open Sound System)
早期Linux版本采用的是OSS框架,它也是Unix及类Unix系统中广泛使用的一种音频体系。OSS既可以指OSS接口本身,也可以用来表示接口的实现。OSS的作者是Hannu Savolainen,就职于4Front Technologies公司。由于涉及到知识产权问题,OSS后期的支持与改善不是很好,这也是Linux内核最终放弃OSS的一个原因。
另外,OSS在某些方面也遭到了人们的质疑,比如:
对新音频特性的支持不足;
缺乏对最新内核特性的支持等等。
当然,OSS做为Unix下统一音频处理操作的早期实现,本身算是比较成功的。它符合“一切都是文件”的设计理念,而且做为一种体系框架,其更多地只是规定了应用程序与操作系统音频驱动间的交互,因而各个系统可以根据实际的需求进行定制开发。总的来说,OSS使用了如下表所示的设备节点:
表格 13‑1 OSS采用的设备节点
设备节点
说明
/dev/dsp
向此文件写数据à输出到外放Speaker
向此文件读数据à从Microphone进行录音
/dev/mixer
混音器,用于对音频设备进行相关设置,比如音量调节
/dev/midi00
第一个MIDI端口,还有midi01,midi02等等
/dev/sequencer
用于访问合成器(synthesizer),常用于游戏等效果的产生
· ALSA(Advanced Linux Sound Architecture)
ALSA是Linux社区为了取代OSS而提出的一种框架,是一个源代码完全开放的系统(遵循GNU GPL和GNU LGPL)。ALSA在Kernel 2.5版本中被正式引入后,OSS就逐步被排除在内核之外。当然,OSS本身还是在不断维护的,只是不再为Kernel所采用而已。
ALSA相对于OSS提供了更多,也更为复杂的API接口,因而开发难度相对来讲加大了一些。为此,ALSA专门提供了一个供开发者使用的工具库,以帮助他们更好地使用ALSA的API。根据官方文档的介绍,ALSA有如下特性:
Ø 高效支持大多数类型的audio inte易做图ce(不论是消费型或者是专业型的多声道声卡)
Ø 高度模块化的声音驱动
Ø SMP及线程安全(thread-safe)设计
Ø 在用户空间提供了alsa-lib来简化应用程序的编写
Ø 与OSS API保持兼容,这样子可以保证老的OSS程序在系统中正确运行
ALSA主要由下表所示的几个部分组成:
表格 13‑2 Alsa-project Package
Element
Description
alsa-driver
内核驱动包
alsa-lib
用户空间的函数库
alsa-utils
包含了很多实用的小程序,比如
alsactl:用于保存设备设置
amixer:是一个命令行程序,用于声量和其它声音控制
alsamixer:amixer的ncurses版
acconnect和aseqview:制作MIDI连接,以及检查已连接的端口列表
aplay和arecord:两个命令行程序,分别用于播放和录制多种格式的音频
alsa-tools
包含一系列工具程序
alsa-firmware
音频固件支持包
alsa-plugins
插件包,比如jack,pulse,maemo
alsa-oss
用于兼容OSS的模拟包
pyalsa
用于编译Python版本的alsa lib
Alsa主要的文件节点如下:
Information Inte易做图ce (/proc/asound)
Control Inte易做图ce (/dev/snd/controlCX)
Mixer Inte易做图ce (/dev/snd/mixerCXDX)
PCM Inte易做图ce (/dev/snd/pcmCXDX)
Raw MIDI Inte易做图ce (/dev/snd/midiCXDX)
Sequencer Inte易做图ce (/dev/snd/seq)
Timer Inte易做图ce (/dev/snd/timer)
关于ALSA的更多知识,建议大家可以自行参阅相关文档,这对于后面理解整个Audio系统是不无裨益的。
1.1.2 TinyAlsa
一看“Tiny”这个词,大家应该能猜到这是一个ALSA的缩减版本。实际上在Android系统的其它地方也可以看到类似的做法——既想用开源项目,又嫌工程太大太繁琐,怎么办?那就只能瘦身了,于是很多Tiny-XXX就出现了。
在早期版本中,Android系统的音频架构主要是基于ALSA的,其上层实现可以看做是ALSA的一种“应用”。后来可能是由于ALSA所存在的一些不足,Android后期版本开始不再依赖于ALSA提供的用户空间层的实现,因而我们在它的库文件夹中已经找不到alsa相关的lib了,如下图所示:
图 13‑7 Android4.1与早期版本在音频库上的区别
而取代它的是tinyalsa相关的库文件,如下图所示:
同时我们可以看到externl目录下多了一个“tinyalsa”文件夹,其中包含了为数不多的几个源码文件,如下所示:
表格 13‑3 Tiny-alsa工程文件
Source File
Description
Android.mk
makefile
mixer.c
Mixer Inte易做图ce实现
pcm.c
PCM Inte易做图ce实现
tinycap.c
Caputer工具
tinymix.c
Mixer工具
tinyplay.c
Play工具
include/tinyalsa/asoundlib.h
头文件
可见TinyAlsa与原版Alsa的差异还是相当大的,它只是部分支持了其中的两种Inte易做图ce,而像Raw MIDI、Sequencer、Timer等Inte易做图ce则没有涉及到——当然这对于一般的嵌入式设备还是足够了。
TinyAlsa作为Alsa-lib的一个替代品,自面世已来得到的公众评价有褒有贬,不能一概而论——对于每个厂商来说,合适自己的就是最好的。而且各厂商也可以在此基础上扩展自己的功能,真正的把ALSA利用到极致。
1.1.3 Android系统上的音频框架
一个好的系统架构,需要尽可能地降低上层与具体硬件的耦合,这既是操作系统的设计目的,对于音频系统也是如此。音频系统的雏形框架可以简单的用下图来表示:
图 13‑8 音频系统的雏形框架
在这个图中,除去Linux本身的Audio驱动外,整个Android音频实现都被看成了User。因而我们可以认为Audio Driver就是上层与硬件间的“隔离板”。但是如果单纯采用上图所示的框架来设计音频系统,对上层应
补充:移动开发 , Android ,