仅为多方学习过程记录,学习源如下,感谢所有技术分享:
Android 9-Audio 介绍Android音频相关内容,包含应用层到HAL层,主要基于Android P进行剖析。
Android9.0CarAudio分析之而AUDIO_DEVICE_OUT_BUS
目录
Auto音频的三大核心,一个是音频管理(声音焦点),一个是音频流管理(音频路由),一个是Audiohal实现。
音频播放分为MediaPlayer和AudioTrack两种方案。MediaPlayer可以播放多种格式的声音文件,AudioTrack只能播放PCM数据流。
MediaPlayer在播放音频时,在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,最后由AudioFlinger进行混音,传递音频给硬件播放出来。
1.AudioTrack
- AudioTrack.MODE_STREAM:用户在应用程序通过write方式把数据一次一次得写到AudioTrack中。
- 采样率:mSampleRateInHz(MediaRecoder 的采样率通常是8000Hz AAC的通常是44100Hz。 设置采样率为44100,目前为常用的采样率,官方文档表示这个值可以兼容所有的设置)
- 通道数目:mChannelConfig(目前最多只支持双声道)
- 音频量化位数:mAudioFormat(只支持8bit和16bit两种)/** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
- AudioTrack向FIFO中写入音频数据,AudioFlinger从FIFO中读取音频数据,经Mixer后送给AudioHardware进行播放。AudioTrack是FIFO的数据生产者;AudioFlinger是FIFO的数据消费者;
- 调用逻辑图:
2. AudioFlinger
- AudioFlinger负责与底层audio alsa进行交互的实现者。属于audioserver进程,init进程fork出来的,首先初始化audioflinger服务,其次初始化audiopolicyservice服务,进一步通过audiopolicyservice和audioflinger完成音频hal层的初始化。
3.动态路由
- 动态路由的初始化,它是汽车路由的核心。在CarAudioService的init()中,以mUseDynamicRouting区分是否启动动态路由。默认为false,不启用动态路由。我们要使用动态路由,所以这个变量要打开。
- 在setupDynamicRouting中Audiocontrol 对应在native的 hal层,和java层的交互通过HIDL的方式实现,AudioPolicy 是Android很重要的一个组成部分,做为native对外的api,我们可以直接拿来使用,定制自己声音路由策略,以及音频焦点优先级策略。
4.AudioPolicy
- 列举所有输出端口
- 获取device是输出设备的的设备信息,而这些设备的信息,是存在audiopolicy配置文件中的。Android9.0AudioPolicy之audio_policy_configuration.xml
- 拿到这些输出的outdevice信息后,继续过滤出device是AUDIO_DEVICE_OUT_BUS的设备信息
- 创建CarAudioDeviceInfo 并将这些放入集合中,BusNumber就是audio_policy_configuration中device标签下 address属性里bus后面的那个数字,一般定义都是BUS1,BUS2或者BUS001,BUS002等BUS后面的数字最多3位
- 映射context和physical bus
- 路由bus策略的映射。可以简单理解为AudioAttribute的usage与AUDIO_OUT_DEVICE_BUS的映射
- 将contextNumber通过AudioControl与busNumber做map映射,同时存入集合
- 列举出所有physical buses并建立音频路由策略
- 我们拿到了out的device,又拿到了contextNumber和busNumber的映射,那么第三部分就是真正实现他们的组装
- contextNumber拿到AudioAttriute的usage,usage封装到AudioMixingRule中,最终将封装了AudioAttribute的AudioMixingRule与对应的AudioDeviceInfo一同组装到AudioMix中。也就是把输出通路与AudioAttribute映射在一起了,这样我们通过Audiotrack或者mediaplayer等音视频播放器播放时,只要指定了AudioAttributes,也就指定了输出设备。