http://blog.youkuaiyun.com/sepnic/article/details/6740640
音频系统概述
专业术语:
- ASLA - Advanced Sound Linux Architecture
- OSS - 以前的Linux音频体系结构,被ASLA取代并兼容
- Codec - Coder/Decoder
- I2S/PCM/AC97 - Codec与CPU间音频的通信协议/接口/总线
- DAI - Digital Audio Interface 其实就是I2S/PCM/AC97
- DAC - Digit to Analog Conversion
- ADC - Analog to Digit Conversion
- DSP - Digital Signal Processor
- Mixer - 混音器,将来自不同通道的几种音频模拟信号混合成一种模拟信号
- Mute - 消音,屏蔽信号通道
- PCM - Pulse Code Modulation 一种从音频模拟信号转换成数字信号的技术,区别于PCM音频通信协议
- Sample Rate - ADC的频率,每秒采样的次数,典型值如44.1KHZ
- Sample Length- 比如24bit,就是将音频模拟信号按照2的24次方进行等分
- SSI - Serial Sound Interface
- DAPM - Dynamic Audio Power Management
ASLA - Advanced Sound Linux Architecture
OSS - 以前的Linux音频体系结构,被ASLA取代并兼容
Codec - Coder/Decoder
I2S/PCM/AC97 - Codec与CPU间音频的通信协议/接口/总线
DAI - Digital Audio Interface 其实就是I2S/PCM/AC97
DAC - Digit to Analog Conversion
ADC - Analog to Digit Conversion
DSP - Digital Signal Processor
Mixer - 混音器,将来自不同通道的几种音频模拟信号混合成一种模拟信号
Mute - 消音,屏蔽信号通道
PCM - Pulse Code Modulation 一种从音频模拟信号转换成数字信号的技术,区别于PCM音频通信协议
Sample Rate - ADC的频率,每秒采样的次数,典型值如44.1KHZ
Sample Length- 比如24bit,就是将音频模拟信号按照2的24次方进行等分
SSI - Serial Sound Interface
DAPM - Dynamic Audio Power Management
以Codec作为研究对象,它的输入有Mic(Microphone)、PhoneIn电话信号等,输出有耳机HP(Headphone)、扬声器SPK(Speaker)和PhoneOut电话信号。另外需要注意在Codec与CPU端间也有音频数字信号的输入输出。
1、播放
2、录音
3、电话上行
4、电话下行
5、通过蓝牙电话上行
6、通过蓝牙电话下行
以上摘自:http://blog.youkuaiyun.com/qianjin0703/article/details/6387662
Loon:1-4即播放、录音、打电话、接听电话和我们目前的音频系统基本是一致的,也应该属于常规设计。5-6增加了蓝牙模块,只是画出了CODEC与Bluetooth的接法,CODEC与CPU、Bluetooth与CPU的连接未给出。我们CODEC只有一组DAI(可以配置成I2S或PCM),那么CODEC到Bluetooth、CODEC到CPU能否复用一组DAI?设计中……
WM9713音频通路设计
CODEC : WM9713
要求:通话录音、电话背景音播放。支持耳机以及蓝牙耳机
- WM9713 路由控制:
- 本机:
- AP声音播放 : DAC -> SPKMIXER -> SPK
- 录音 : MIC1 -> REC -> ADC (板载MIC接MIC1)
- 电话上行 : MIC1 -> MONOMIXER -> MONO -> 模组输入
- 电话下行 : 模组输出 -> HEADSET / 免提状态 : 模组输出 -> MONOIN/PCBEFF -> SPKMIXER -> SPK
- 通话录音 : MONOMIXER -> REC (电话上行), MONOIN -> REC (电话下行)
- 背景音播放 : DAC -> MONOMIXER
- 耳机:
- AP声音播放 : DAC -> HPMIXER -> HP
- 录音 : MIC2A -> REC -> ADC (耳机MIC接MIC2A)
- 电话上行 : MIC1 -> MONOMIXER -> MONO -> 模组 (这里明显用板载MIC进行电话上行,个人觉得用耳机MIC效果更好)
- 电话下行 : 模组输出 -> LINE -> HPMIXER -> HP
- 通话录音 : MONOMIXER -> REC (电话上行), HPMIXER -> REC (电话下行)
- 背景音播放 : DAC -> MONOMIXER
- 蓝牙耳机:蓝牙耳机通过CODEC的PCM接口连接。
- AP声音播放 : DAC -> HPMIXER -> REC -> ADC -> PCM -> BLUETOOTH
- 录音 : BLUETOOTH -> PCM -> VOICEDAC -> ADC
- 电话上行 : BLUETOOTH -> PCM -> VOICEDAC -> MONOMIXER -> MONO -> 模组输入
- 电话下行 : MONOIN/PCBEFF -> HPMIXER -> REC -> ADC -> BLUETOOTH
- 背景音播放 : DAC -> MONOMIXER
WM9713 路由控制:
本机:
AP声音播放 : DAC -> SPKMIXER -> SPK
录音 : MIC1 -> REC -> ADC (板载MIC接MIC1)
电话上行 : MIC1 -> MONOMIXER -> MONO -> 模组输入
电话下行 : 模组输出 -> HEADSET / 免提状态 : 模组输出 -> MONOIN/PCBEFF -> SPKMIXER -> SPK
通话录音 : MONOMIXER -> REC (电话上行), MONOIN -> REC (电话下行)
背景音播放 : DAC -> MONOMIXER
耳机:
AP声音播放 : DAC -> HPMIXER -> HP
录音 : MIC2A -> REC -> ADC (耳机MIC接MIC2A)
电话上行 : MIC1 -> MONOMIXER -> MONO -> 模组 (这里明显用板载MIC进行电话上行,个人觉得用耳机MIC效果更好)
电话下行 : 模组输出 -> LINE -> HPMIXER -> HP
通话录音 : MONOMIXER -> REC (电话上行), HPMIXER -> REC (电话下行)
背景音播放 : DAC -> MONOMIXER
蓝牙耳机:蓝牙耳机通过CODEC的PCM接口连接。
AP声音播放 : DAC -> HPMIXER -> REC -> ADC -> PCM -> BLUETOOTH
录音 : BLUETOOTH -> PCM -> VOICEDAC -> ADC
电话上行 : BLUETOOTH -> PCM -> VOICEDAC -> MONOMIXER -> MONO -> 模组输入
电话下行 : MONOIN/PCBEFF -> HPMIXER -> REC -> ADC -> BLUETOOTH
背景音播放 : DAC -> MONOMIXER
以上摘自:http://blog.youkuaiyun.com/dycl3/article/details/2645835
WM9713框图:
蓝牙通话框图:
蓝牙通话框图,指示错了,应该是“蓝色表示电话下行,红色表示电话上行”。特此更正!
如何在Android平台上使用USB Audio设备
需求:USB Headset插上去后,声音要从本地CODEC切换到USB Headset输出/输入。
上网搜了有关USB Audio Hotplug的东西,比较适用的资源如下:
1、Hotplugging USB audio devices (Howto)
题目看起来很吻合我们的问题,事实上并没有多少参考价值。其中脚本/etc/hotplug/usb/extigy或许可以捕捉到USB Audio设备的热插拔事件,应该可以进一步验证和利用,留意这点。
这是利用udev来获取USB热插拔事件,虽然Android没有udev,但例子程序对热插拔事件字符串的处理值得参考。
其实我们工作的第一步:验证USB Headset是否可以回放录音。
3.1、插上USB Headset,可以看到alsa的确加载了USB Audio,如下:
- ~ # cat /proc/asound/cards
- 0 [WMTSOC ]: HWDAC - WMT_SOC
- WMT_SOC (HWDAC)
- 1 [default ]: USB-Audio - C-Media USB Headphone Set
- C-Media USB Headphone Set at usb-0000:00:06.0-1, full speed
~ # cat /proc/asound/cards
0 [WMTSOC ]: HWDAC - WMT_SOC
WMT_SOC (HWDAC)
1 [default ]: USB-Audio - C-Media USB Headphone Set
C-Media USB Headphone Set at usb-0000:00:06.0-1, full speed
3.2、参考了这个链接,写了如下的配置文件/etc/asond.conf:
- pcm.!default {
- type asym
- playback.pcm {
- type plug
- slave.pcm "hw:1,0"
- }
- capture.pcm {
- type plug
- slave.pcm "hw:1,0"
- }
- }
pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm "hw:1,0"
}
capture.pcm {
type plug
slave.pcm "hw:1,0"
}
}
重启后,声音就从Headset出来了。
hw:1,0对应card1即USB-Audio - C-Media USB Headphone Set
到此,需要考虑在Android平台切换USB Audio的实现问题了。有几个途径:1/ hotplug/usb;2/ udev;3/ netlink。这里就是netlink的实现方式,链接里有个证实可用的例子程序,目前可能需要做热插拔事件字符串的处理。
难点:
Android音频设备的切换底层入口是alsa_default.cpp,目前看来需要在asound.conf定义好local CODEC和USB Audio的plug;还需要修改alsa_default.cpp,最主要Android要知道USB Audio插上时打开USB Audio的plug,USB Audio拔下时打开local CODEC的plug。这样一想,修改的幅度还是蛮大的。而且未能确定如果在播放的过程中,切换音频设备是否有影响?如果alsa允许只是配置好asound.conf达到同样的目的,那就好办了,可惜目前找不到这方面的资料,应该没有这个便利了。
进展:
2011/9/19:按照以上难点分析,大致完成了整个Android框架层的代码和ALSA配置文件,基本实现了USB Audio热插拔时的音频设备切换。但有个很大的问题:在播放时切换音频设备会导致AudioFlinger服务crash(之前做2G通话时也遇到这个问题,用其他办法规避了)。看来在切换音频设备时,应该停止播放;等切换完成后,再恢复播放。
传闻Android3.1开始支持USB Audio设备:“Your device will support USB Host Mode, applications can now manage connected USB peripherals such as audio devices. input devices, communications devices, and more.”。但Android3.1何时才能开源?
已经有思路了,刚想起Android本身不是支持Bluetooth音频吗?Bluetooth Headset的切换应该与USB Headset本质差不多吧。应该仔细研究下蓝牙音频是如何实现的。Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager