音频系统.docx
- 文档编号:24682924
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:28
- 大小:2.73MB
音频系统.docx
《音频系统.docx》由会员分享,可在线阅读,更多相关《音频系统.docx(28页珍藏版)》请在冰豆网上搜索。
音频系统
音频系统
audio系统
一硬件架构
1总体架构:
2Pxa955与codec和BT的连接:
3CP中的编解码模块和voiceenhancementcomponent:
4ABU的内部架构:
DMA传输分为两种模式:
中断驱动传输和自动DMA传输。
中断驱动传输是当数据请求条件满足时,产生中断,在中断处理函数里配置DMA,启动传输。
采用的是自动DMA数据传输。
当数据从用户空间拷贝到内核buffer后,当内核buffer不为空时,配置ABU和DMA的参数,启动DMA,当ABU的SysRxFiFo中的数据小于播放水位线,即有空间从DMA接收数据时,产生DMA请求,DMA控制器获得数据请求后,启动传输。
每传输完DMA的一个描述符后,产生一次中断,在中断函数中,更新ABU和内核buffer的指针状态,分配下一个DMA描述符缓冲区的地址。
5Codec的内部架构:
Codec中的增益放大器
所用到的codec通路
LEVANTE_AnaMIC1_TO_PCM_L
通话时,MIC通路
LEVANTE_AnaMIC1_LOUD_TO_PCM_L
通话免提时,MIC通路
LEVANTE_AnaMIC2_TO_PCM_L
通话插耳机时,MIC通路
LEVANTE_PCM_L_TO_EAR_VIA_DAC1
通话时,听筒通路
LEVANTE_PCM_L_TO_SPKR_VIA_DAC1
通话免提时,SPEAKER通路
LEVANTE_PCM_L_TO_HS
通话插耳机时,耳机通路
LEVANTE_I2S_TO_EAR_VIA_DAC1
用听筒放音频的通路
LEVANTE_I2S_TO_SPKR_VIA_DAC1
用SPERKER放音频的通路
LEVANTE_I2S_TO_HS
用耳机放音频的通路
LEVANTE_AnaMIC1_LOUD_TO_PCM_L_APPS
APPS录音时,MIC通路
LEVANTE_AnaMIC2_TO_PCM_L_APPS
插着耳机用APPS录音时,耳机上的MIC通路
LEVANTE_I2S_TO_SPKR_HS
插着耳机,来电铃音通路
二软件架构
1架构图
2控制流和数据流的路径
控制流:
APHiFi播放/录音
Androidaudiosystem→MarvelHAL→ALSALib→CtrlPlugin→AudioServer→AM→ACM→LevanteComponent→ALSALib→LevanteKernelDriver→LevanteAudioHWCodec
CPvoicecall通路/音量控制
Androidaudiosystem→MarvellHAL→ALSALib→CtrlPlugin→AudioServer→AM→ACM→LevanteComponent→ALSALib→LevanteKernelDriver→LevanteAudioHWCodec
Androidaudiosystem→MarvellHAL→ALSALib→CtrlPlugin→AudioServer→AM→ACM→audiostub→Communicationsubsystem
CPvoicecallMUTE控制
AndroidRIL→MarvellTelephony→AudioServer→AM→ACM→audiostub→Communicationsubsystem
数据流:
APHiFi播放
Androidaudiosystem→MarvellHAL→ALSALib→ALSAcore/ABUdriver→LevanteAudioHWCodec
APHiFi录音
LevanteAudioHWCodec→ALSAcore/ABUdriver→ALSALib→MarvellHAL→Androidaudiosystem
AP向CP发送数据进行播放
Androidaudiosystem→MarvellHAL→ALSALib→PCMPlugin→AudioServer→AM→ACM→audiostub→Communicationsubsystem
CP录音发送到AP
Communicationsubsystem→audiostub→ACM→AM→AudioServer→PCMPlugin→ALSALib→MarvellHAL→Androidaudiosystem
3软件各功能块描述
3.1MarvellHAL
3.1.1功能
通过ALSALib连接Androidaudiosystem和Marvell的硬件系统。
从Androidaudiosystem获取音频路由通知,发送到AudioServer
从AndroidaudioApps获取音频数据,通过ALSALib发送到codec或者Communicationsubsystem。
从ALSALib获取数据发送到AndroidaudioApps。
3.1.2代码位置
vendor/marvell/generic/libaudio/AudioHardware.cpp
vendor/marvell/saarbmg1/libaudiopath/AudioPath.c
3.1.3通路配置实例
通过以下函数来配置路由通知。
voidenable_audio_path_for_device(uint32_tdevices,unsignedcharleft,unsignedcharright)
voiddisable_audio_path_for_device(uint32_tdevices)
voidset_volume_for_device(uint32_tdevices,unsignedcharleft,unsignedcharright)
其中,enable_audio_path_for_device将参数device与结构数组audio_path_list[]中各个数组元素的device成员进行匹配,然后调用相匹配的数组元素的enable成员所指向的函数,比如enable_loud_speaker。
audio_path_list[]中支持的设备有:
AndroidDEVICE
HAL/AudioServer
numid
DEVICE
DEVICE_OUT_EARPIECE
8
0
DEVICE_OUT_SPEAKER
22
SPEAKER_DEVICE
DEVICE_OUT_WIRED_HEADSET
26
HEADSET_DEVICE
DEVICE_OUT_WIRED_HEADPHONE
28
HEADPHONE_DEVICE
DEVICE_OUT_BLUETOOTH_SCO
24
BLUETOOTH_DEVICE
DEVICE_OUT_BLUETOOTH_SCO_HEADSET
24
BLUETOOTH_DEVICE
DEVICE_OUT_DEFAULT
36
SONIFICATION_DEVICE
DEVICE_IN_BUILTIN_MIC
32
RECORD_DEVICE
DEVICE_IN_WIRED_HEADSET
32
RECORD_DEVICE
DEVICE_IN_COMMUNICATION
34
RECORD_LOFI_DEVICE
DEVICE_IN_VOICE_CALL
30
PHONE_DEVICE
enable_loud_speaker调用control_info_to_numid和send_amixer_control,函数control_info_to_numid将四个参数(intclient,intmethod_type,intmethod_id,intdevice)与一个numid对应,根据marvell\saarbmg1\libaudiopath\MarvellAmixer.h文件中的gItemCtlInfo来转换,numid为所匹配的gItemCtlInfo数组中的元素的下标加1。
函数send_amixer_control将通过调用ALSAlib接口和numid来使用CtrlPlugin。
3.2ALSALib
3.2.1功能
提供了全部的ALSA内核的接口,给用户空间来使用:
控制接口(/dev/snd/controlCX)
混音器接口(/dev/snd/mixerCXDX)
PCM接口(/dev/snd/pcmCXDX)
RawMIDI接口(/dev/snd/midiCXDX)
音序接口(/dev/snd/seq)
定时器接口(/dev/snd/timer)
这些接口都是以文件的方式被提供。
3.2.2代码位置
external/alsa-lib/src/
3.3PCMPlugin/CtrlPlugin
3.3.1功能
PCMPlugin和CtrlPlugin都属于ALSALib的插件。
PCMPlugin将PCM数据流存储于一个文件,或者将一个已经存在的文件作为输入数据源。
可以用于通话录音。
CtrlPlugin传输Androidaudiosystem的控制请求至audioserver的IPC。
3.3.2代码位置
vendor/marvell/generic/telephony/Drivers/aud_sw/linux_audio/alsa_plugin/phone/pcm_phone.c
vendor/marvell/generic/telephony/Drivers/aud_sw/linux_audio/alsa_plugin/phone/ctl_phone.c
3.3.3通路配置实例
CtrlPlugin的代码结构按照ALSA规范来实现,主要用来实现功能的函数为:
在send_amixer_control中调用了snd_ctl_elem_value_set_integer和snd_ctl_elem_write,再往下会调用上图结构体中的phone_write_integer,phone_write_integer中会将上面提到过的numid转换回(intclient,intmethod_type,intmethod_id,intdevice)四个参数,转换所根据的表是上面提到的gItemCtlInfo(marvell\saarbmg1\libaudiopath\MarvellAmixer.h)的一份拷贝marvell\generic\telephony\drivers\aud_sw\linux_audio\alsa_plugin\phone\MarvellAmixer.h。
然后将四个参数通过audioserver的ipc接口发送给audioserver处理。
3.4AudioServer
3.4.1功能
包含4部分
1IPC通信
为ALSALib和ACM提供了通信控制通道和数据通道
2ScenarioManager
有5种主要的音频场景
Voicecall
HIFIplaybackontheAppsside
Appsrecordingandplaynotduringavoicecall
RecordvoiccallbyApps(withoutBT)
RecordvoiccallbyApps(withBT)
音频设备
BTheadset
Speakerphone
Internalmic
Headsetmic
Stereoheadset
ScenarioManager从IPC收到信息,配置不同的音频场景与不同的音频设备。
ScenarioManager调用AM的API来实现这些配置。
3Streamingmanager
在ACM和ALSAPCMplugin之间传输数据
4AudioAccessorydetect
检测耳机/蓝牙耳机的插入与拔出,发送消息至Streamingmanager,做相应的音频处理。
3.4.2代码位置
marvell\generic\telephony\drivers\aud_sw\linux_audio\src\Audio_server.c。
3.4.3通路配置实例
接收CtrlPlugin发出socket的函数是socket_loop,如下面代码,处理socket消息是在plugin_client_handler中。
在plugin_client_handler中,根据上面传入的四个参数中的client_type和method_type,分别调用不同的函数,代码如下图。
函数appliance_plugin_ctl_write,根据不同的device_type,向下调用AM层的接口函数,操作AM中相应的活动和设备,代码下图。
函数phone_plugin_ctl_write调用的是AMAudioActivitySet(AM_ACTIVITY_PCM_PLAYBACK,isOn)。
3.5AudioManager(AM)
3.5.1功能
根据audioserver层传下来的设备和活动信息,根据自身的逻辑,如优先级等,建立数据库,包含设备、格式、方向、音量、静音参数,传递给ACM层。
3.5.2代码位置
vendor/marvell/generic/telephony/Drivers/aud_sw/AM/src/am.c
3.5.3通路配置实例
AM中包含以下几种活动和设备:
在AMAudioTask函数中接受消息队列,先根据消息队列的参数设置applianceMask和stateMask。
然后,audioDeviceSet=amStateApplianceCBFunc(stateMask,_applianceMask);最后调用amDeviceManager();。
在amStateApplianceCBFunc()中,先根据_applianceMask和设备优先级,获得appliance。
然后根据stateMask设置相应的format、dir、volume和mute,并作为参数调用函数amDeviceSetFunc()。
在amDeviceSetFunc()中,根据传入的appliance、format、dir、volume和mute等参数,通过查表AM_DeviceSetLUTdeviceSetDefaultLUT[],将参数映射为ACM的参数,获得数据库_audioDeviceSet[]。
在amDeviceManager()中,对数据库进行遍历,对相应的设备,调用ACM中的函数ACMAudioDeviceEnable()等,将参数传递下去。
3.6Audiocomponentsmanager(ACM)
3.6.1功能
在ACM中,将设备信息映射为对各组件和组件内部通路的管理。
3.6.2代码位置
vendor/marvell/generic/telephony/Drivers/aud_sw/ACM/src/acm_control.c
3.6.3通路配置实例
ACMAudioDeviceEnable(ACM_AudioDevicedevice,ACM_AudioFormatformat,ACM_AudioVolumevolume)函数中,根据参数device和format,访问acm_nvm.h中的映射表DEVICE_DEFAULT_TABLE_LEVANTE,映射为相应的组件、通路、通路方向和和voiceenhancementcomponent的各模块的参数。
对匹配上的组件,执行相关的ACMEnablePath(path,Volume)函数。
表DEVICE_DEFAULT_TABLE_LEVANTE的结构为:
例如,
组件句柄提供了标准函数对每个组件进行控制和配置:
3.7LevanteComponent
3.7.1功能
在LevanteComponent中,将组件内的通路信息映射为pathoutput和pathinput端点信息,分别对各个端点配置不同的寄存器信息,并对各通路的增益进行校准。
3.7.2代码位置
vendor/marvell/generic/telephony/Drivers/aud_sw/ACM/src/audioLevante.c
vendor/marvell/generic/telephony/Drivers/aud_sw/ACM/src/audioGpo.c
vendor/marvell/generic/telephony/Drivers/aud_sw/ACM/src/audioBluetooth.c
3.7.3通路配置实例
在GPOPathEnable函数中,调用ioctl接口,操作驱动层提供的设备/dev/gpo。
驱动层的实现在kernel/drivers/char/audioGpoSet.c中。
在LevantePathEnable(unsignedcharpath,ACM_AudioVolumevolume)函数中,首先调用
LevanteAddPathToList()函数,然后调用LevanteUpdateHardware()函数;
Codec中有多个放大器,每个放大器都对应着多个通路经过,每条通路都经过多个放大器。
根据通路和此通路经过的每个放大器中对此通路的校准参数,确定所经过的每个放大器的增益大小。
3.8LevanteAdapter
3.8.1功能
通过调用ALSAlib的控制接口,实现LevanteI2CWrite()和LevanteI2CRead()函数。
3.8.2代码位置
vendor/marvell/generic/telephony/Drivers/aud_sw/linux_audio/src/amixer.c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 音频系统