赞
踩
通过本文可了解Android系统的音频架构,基本组件及功能,大概了解常用的播放模式,音频流传输路径,低延迟音频的一些能力,AudioServer服务的初始化。本文仅供交流学习。
Audio系统的核心实现均在native c++层,提供java/C++ API供应用使用Audio部分能力,通过hal隔离硬件差异。
Android Audio Framework系统架构
google提供的车载音频路由
音频数据传输路径
音频系统使用该属性进行音频焦点控制、音频通道路由及音量控制等,一般在应用开发中常用。
- AudioAttributes {
- mUsage //指定为什么要播放该声音,该声音的作用是什么。用来控制焦点、路由及音量决策(USAGE_MEDIA、 USAGE_VOICE_COMMUNICATION、未知等)
- mContentType //指定播放来源的类型(CONTENT_TYPE_MOVIE、CONTENT_TYPE_MUSIC、语音、发音、未知等)
- mSource
- mFlags //指定音频框架如何对音频播放应用效果
- mTags / mFormattedTags / mBundle (key value pairs)
- }
系统音频设备类型主要用于区分系统支持的录音及播音设备能力,一般在audio hal开发中常用。Android系统定义的设备类型如下(定义audio-base.h里):
设备类型 | 描述 |
---|---|
AUDIO_DEVICE_OUT_BUS | 输出设备,Android 的主要输出(车载应用下Android 的所有音频均通过这种方式) |
AUDIO_DEVICE_OUT_TELEPHONY_TX | 输出设备,电话下行数据(车载相关) |
AUDIO_DEVICE_OUT_EARPIECE | 输出设备,听筒(手机) |
AUDIO_DEVICE_OUT_SPEAKER | 输出设备,扬声器(手机) |
AUDIO_DEVICE_IN_BUS | 输入设备,基本的录音设备(车载相关) |
AUDIO_DEVICE_IN_FM_TUNER | 输入设备,收音机的输入(车载相关) |
AUDIO_DEVICE_IN_LINE | 输入设备,AUX IN音频(车载相关) |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP | 输入设备,通过蓝牙接收到的音乐(车载相关) |
AUDIO_DEVICE_IN_TELEPHONY_RX | 输入设备,电话上行数据 |
负责音频路由,音频录音或播音设备的选择。是运行在audioserver 进程中一个服务。在手机场景负责插上耳机的音频通道切换,车载场景负责音频的路由即选择何种音源在哪个设备播放。
是Audio数据消费者,消费音频数据并推进Audio hal、并与Audio Hal对接完成一些控制操作。也是运行在audioserver 进程中一个服务。内部涉及的关键模块:
Audio数据生产者,用于向音频输出设备发送音频数据数,播放的数据为 PCM 格式音频数据,每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到 AudioFlinger中,由AudioFlinger把所有的AudioTrack进行混合,然后输送到Audio HAL中进行播放。
目前Android11同时最多可以创建128个音频流。
Android目前支持3种播放模式,最常用的是deep buffer模式。具体采用那种播放模式,是在audioPolicy中根据音频流属性AudioAttribute进行控制的。
Android开发中最常用的播放模式,音乐等对时延要求不高的声音输出采用该模式。边加载边播放,由CPU进行解码,再送入AudioFlinger进行混音播放。处理流程如下:
低延迟播放模式,用于按键音、游戏背景音等对时延要求高场景。一次加载完数据,应用一般采用soundpool播放。处理流程如下:
也是用于音乐播放,但将音频解码的部分放在aDSP进行解码,混音及音效处理,这样可以降低CPU的负载,目前支持的格式有MP3/AAC。处理流程如下:
Android提供AAudio进行低延迟音频的开发,通过mmap的方式进行音频数据的传输,对比普通的匿名共享内存+内核缓冲区的方式减少一次内存拷贝。AAudio也提供两种工作模式:
EXCLUSIVE mode
该模式下,应用可直接通过mmap的地址空间,将音频数据写入驱动。
SHARED mode
该模式下,应用需通过AudioServer对接mmap的地址空间,将音频数据写入驱动。但AudioServer不会对音频数据进行混音,音效处理等,因此延迟也会大大减少。
Open Sound Library for Embedded Systems,Android NDK 提供的OpenSL ES API 接口,它支持在 native 层直接处理音频数据,因此可减少java与native之间的数据拷贝工作。
通过init进程fork出来audioserver进程。
- //frameworks/av/media/audioserver/audioserver.rc
- service audioserver /system/bin/audioserver
- class core
- user audioserver
- onrestart restart audio-hal-2-0
- ioprio rt 4 //设置io优先级
- disabled
main_audioserver的main函数被调用,进行AudioFlinger 及 AudioPolicyService服务的启动及初始化。
- //frameworks\av\media\audioserver\main_audioserver.cpp
- int main(int argc __unused, char **argv)
- {
- sp<ProcessState> proc(ProcessState::self());
- sp<IServiceManager> sm = defaultServiceManager();
- ALOGI("ServiceManager: %p", sm.get());
- //1.初始化AudioFlinger
- AudioFlinger::instantiate();
- //2.初始化AudioPolicyService
- AudioPolicyService::instantiate();
- }
AudioFlinger服务继承自BinderService,BnAudioFlinger。
instantiate是BinderService里实现的通用方法,会创建对应AudioFlinger服务, 并加入ServiceManager中。
- // frameworks\native\libs\binder\include\binder\BinderService.h
- static status_t publish(
- bool allowIsolated = false,
- int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
- sp<IServiceManager> sm(defaultServiceManager());
- //创建AudioFlinger服务并加入ServiceManager中
- return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
- dumpFlags);
- }
-
- static void instantiate() { publish(); }
AudioFlinger构造函数如下:
主要进行与audio hal及音效hal服务的绑定。
- // frameworks/av/services/audioflinger/AudioFlinger.cpp
- AudioFlinger::AudioFlinger()
- : BnAudioFlinger(),.....{
- // 创建mDevicesFactoryHal示例,与audio hal服务绑定。
- mDevicesFactoryHal = DevicesFactoryHalInterface::create();
- mEffectsFactoryHal = EffectsFactoryHalInterface::create();
- }
audioflinger继承自Refbase,因此也会执行onFirstRef()函数,不过google已经将重要的初始化逻辑迁移进了构造函数执行了。
AudioPolicyService初始化的重要逻辑在其onFirstRef()中实现。
- //frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
- void AudioPolicyService::onFirstRef()
- {
- {
- Mutex::Autolock _l(mLock);
- // start audio commands thread
- mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
- // start output activity command thread
- mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
- // 创建AudioPolicyManager,policy中大部分核心工作均在AudioPolicyManager中实现
- mAudioPolicyClient = new AudioPolicyClient(this);
- mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
- }
- // load audio processing modules
- sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
- {
- Mutex::Autolock _l(mLock);
- mAudioPolicyEffects = audioPolicyEffects;
- }
-
- mUidPolicy = new UidPolicy(this);
- mUidPolicy->registerSelf();
-
- mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
- mSensorPrivacyPolicy->registerSelf();
- }

关联文章
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。