一、Audio音频架构简介

二、Android Audio系统框架

三、Audio架构以及各层的代码分布图

四、音频框架在Android系统中的进一步细化

五、创建声卡和注册声卡

六、Android Audio系统的结构

七、Audio音频原理介绍

八、Audio音频策略制定与策略执行的调用流程

九、Android AudioPolicyService服务启动过程

十、Android系统中所有的音频接口设备保存到AudioFlinger的成员变量mAudioHwDevs中

十一、audio_policy.conf同时定义了多个audio接口

十二、通过AudioFlinger的loadHwModule加载各audio接口对应的库文件实现调用PlaybackThread播放线程或RecordThread录音线程

十三、AudioFlinger的openInput()方法调用流程分析

十四、AudioFlinger的openOutput()方法的调用流程分析

十五、Audio系统为了能正常播放音频数据,需要创建抽象的音频输出接口对象,打开音频输出过程

十六、打开音频输入的流程

十七、打开音频输出后,在AudioFlinger与AudioPolicyService中的表现形式

十八、打开音频输入后,在AudioFlinger与AudioPolicyService中的表现形式

十九、AudioPolicyService加载完系统定义的所有音频接口,并生成相应的数据对象

二十、AudioPolicyService与AudioTrack和AudioFlinger的关系

二十一、AudioPolicyService注册名为服务的流程

二十二、AudioTrack构造过程

二十三、AudioTrack和AudioFlinger的关系

二十四、audio_policy与AudioPolicyService、AudioPolicyCompatClient之间的关系

一、Audio音频架构简介

APP

整个音频体系的最上层

Framework

MediaPlayer和MediaRecorder、AudioTrack和AudioRecorder,Android系统为控制音频系统提供了AudioManager、AudioService及AudioSystem类,这些都是framework为便利上层应用开发所设计的

Libraries

系统服务AudioFlinger和AudioPolicyService(比如:ServiceManager、LocationManagerService、ActivityManagerService等等),音频体系中另一个重要的系统服务是MediaPlayerService

HAL

硬件抽象层是AudioFlinger直接访问的对象,这说明了两个问题,一方面AudioFlinger并不直接调用底层的驱动程序;另一方面,AudioFlinger上层(包括和它同一层的MediaPlayerService)的模块只需要与它进行交互就可以实现音频相关的功能了。因而我们可以认为AudioFlinger是Android音频系统中真正的“隔离板”,无论下面如何变化,上层的实现都可以保持兼容。音频方面的硬件抽象层主要分为两部分,即AudioFlinger和AudioPolicyService。实际上后者并不是一个真实的设备,只是采用虚拟设备的方式来让厂商可以方便地定制出自己的策略,抽象层的任务是将AudioFlinger/AudioPolicyService真正地与硬件设备关联起来

以前Android系统中的Audio系统依赖于ALSA-lib,但后期就变为了tinyalsa,这样的转变不应该对上层造成破坏。因而Audio HAL提供了统一的接口来定义它与AudioFlinger/AudioPolicyService之间的通信方式,这就是audio_hw_device、audio_stream_in及audio_stream_out等等存在的目的,这些Struct数据类型内部大多只是函数指针的定义,是一些“壳”。当AudioFlinger/AudioPolicyService初始化时,它们会去寻找系统中最匹配的实现(这些实现驻留在以audio.primary.*,audio.a2dp.*为名的各种库中)来填充这些“壳”

理解Android音频系统的时候分为两条线索

以库为线索,比如:AudioPolicyService和AudioFlinger都是在libaudioflinger库中,而AudioTrack、AudioRecorder等一系列实现则在libmedia库中

以进程为线索,库并不代表一个进程,进程则依赖于库来运行。虽然有的类是在同一个库中实现的,但并不代表它们会在同一个进程中被调用。比如AudioFlinger和AudioPolicyService都驻留于名为mediaserver的系统进程中,而AudioTrack/AudioRecorder和MediaPlayer/MediaRecorder一样实际上只是应用进程的一部分,它们通过binder服务来与其它系统进程通信

二、Android Audio系统框架

三、Audio架构以及各层的代码分布图

四、音频框架在Android系统中的进一步细化

五、创建声卡和注册声卡

六、Android Audio系统的结构

七、Audio音频原理介绍

AudioFlinger、AudioPolicyService和AudioTrack/AudioRecorder抛开MediaPlayer、MediaRecorder这些与应用开发直接关联的部分,整个音频系统的核心就是由这三者构建而成的。其中前两个都是System Service,驻留在mediaserver进程中,不断地处理AudioTrack/AudioRecorder的请求。音频的回放和录制从大的流程上看都是相似的,所以我们侧重于对AudioTrack的分析

把所有媒体相关的native层服务(包括AudioFlinger,MediaPlayerService,CameraService和AudioPolicyService)启动起来,编译生成的mediaserver将被烧录到设备的/system/bin/mediaserver路径,然后由系统启动时的init进程启动

Audio系统的结构

libmedia.so提供Audio接口,这些Audio接口既向上层开放,也向本地代码开放

libaudiofilnger.so提供Audio接口实现

Audio硬件抽象层提供到硬件的接口,供AudioFlinger调用

Audio使用JNI和JAVA对上层提供接口

media库中的Audio框架部分

Android 的Audio的核心框架在media库中提供,其中对上面主要实现AudioSystem、AudioTrack和AudioRecorder三个类。提供了IAudioFlinger类接口,在这个类中,可以获得IAudioTrack和IAudioRecorder两个接口,分别用于声音的播放和录制。AudioTrack和AudioRecorder分别通过调用IAudioTrack和IAudioRecorder来实现

Audio系统的头文件

路径为:frameworks/base/include/media/

AudioSystem.h

IAudioFlinger.h

AudioTrack.h

IAudioTrack.h

AudioRecorder.h

IAudioRecorder.h

Ixxx的接口通过AudioFlinger来实现,其他接口通过JNI向上层提供接口

Audio系统的头文件在frameworks/base/include/media/目录中,主要的头文件如下

AudioSystem.h:media库的Audio部分对上层的总管接口

IAudioFlinger.h:需要下层实现的总管接口

AudioTrack.h:放音部分对上接口

IAudioTrack.h:放音部分需要下层实现的接口

AudioRecorder.h:录音部分对上接口

IAudioRecorder.h:录音部分需要下层实现的接口

IAudioFlinger.h、IAudioTrack.h和IAudioRecorder.h这三个接口通过下层的继承来实现(即:AudioFlinger)

AudioFlinger.h,AudioTrack.h和AudioRecorder.h是对上层提供的接口,它们既供本地程序调用(例如:声音的播放器、录制器等),也可以通过JNI向Java层提供接口

AudioTrack和AudioRecorder都具有start,stop和pause等接口。前者具有write接口,用于声音的播放,后者具有read接口,用于声音的录制

AudioSystem用于Audio系统的控制工作,主要包含一些set和get接口,是一个对上层的类

AudioFlinger是Audio系统的核心,来自AudioTrack的数据,最终在这里得到处理并被写入Audio HAL层

MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包含了AudioTrack。使用AudioTrack播放音乐

MediaPlayer提供了更完整的封装和状态控制,相比MediaPlayer,AudioTrack更为精练、高效,实际上MediaPlayerService的内部实现就是使用了AudioTrack把所有媒体相关的native层服务(包括AudioFlinger,MediaPlayerService,CameraService和AudioPolicyService)启动起来,编译生成的mediaserver将被烧录到设备的/system/bin/mediaserver路径,然后由系统启动时的init进程启动

两种Audio Hardware HAL接口定义

legacy:hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h

非legacy:hardware/libhardware/include/hardware/audio.h

前者是2.3及之前的音频设备接口定义,后者是4.0的接口定义,为了兼容以前的设计,4.0实现一个中间层:hardware/libhardware_legacy/audio/audio_hw_hal.cpp,结构与其他的audio_hw.c大同小异,差别在于open方法事实上legacy也要封装成非legacy中的audio.h,确切的说需要一个联系legacy interface和not legacy interface的中间层,这里的audio_hw_hal.cpp就充当这样的一个角色了

hardware/libhardware/modules/audio/

createAudioHardware()函数

external/tinyalsa/

mixer.c      类alsa-lib的control,作用音频部件开关、音量调节等

pcm.c        类alsa-lib的pcm,作用音频pcm数据回放录制

上面的hardware/libhardware_legacy/audio/、hardware/libhardware/modules/audio/、device/samsung/tuna/audio/是同层的。之一是legacy audio,用于兼容2.2时代的alsa_sound;之二是stub audio接口;之三是Samsung Tuna的音频抽象层实现。调用层次:AudioFlinger -> audio_hw -> tinyalsa

Audio硬件抽象层的实现在各个系统中可能是不同的,需要使用代码去继承相应的类并实现它们,作为Android系统本地框架层和驱动程序接口AudioFlinger继承了libmedia.so(Audio本地框架类)里面的接口,上层调用的只是libmedia.so部分的接口,但实际上调用的内容是libaudioflinger.so,使用JNI和Java对上层提供接口,JNI部分通过调用libmedia.so库提供的接口来实现

Audio硬件抽象层提供到硬件的接口,供AudioFlinger调用,Audio的硬件抽象层实际上是各个平台开发过程中需要主要关注和独立完成的部分,因为Android中的Audio系统不涉及编解码环节,只负责上层系统和底层Audio硬件的交互,所以通常以PCM作为输入/输出格式

IAudioFlinger类接口通过该类可以获得IAudioTrack和IAudioRecorder两个接口,分别用于声音的播放和录制,AudioTrack和AudioRecorder分别通过调用IAudioTrack和IAudioRecorder来实现

硬件抽象层主要实现了AudioStreamInALSA和AudioStreamOutALSA两个类,这两个类又会调用该文件下的 ALSAStreamOps类的方法。AudioStreamInALSA是录音部分调用的路径。在AudioStreamInALSA的构造函数中会对alsa进行一些初始化参数设置,

AudioStreamInALSA的read方法是最主要的方法,audioflinger层的read调用就是对 AudioStreamInALSA的read的调用。由于

录音部分出现单声道和双声道数据传输的问题,修改read方法如下,即可实现了录音功能正常, 避免了在编码的时候修改数据时其他编码仍不能工作的弊端

八、Audio音频策略制定与策略执行的调用流程

AudioPolicyService是策略的制定者,AudioFlinger则是策略的执行者

AudioTrack是AudioFlinger的客户端,AudioFlinger是Android系统中Audio管理的中枢

在Android中AudioPolicyService最终都会调用到AudioFlinger中去,因为AudioFlinger实际创建并管理了硬件设备

AudioFlinger类是代表整个AudioFlinger服务的类,其余所有的工作类都是通过内部类的方式在其中定义的

九、Android AudioPolicyService服务启动过程

AudioPolicyService完成的工作

加载audio_policy.default.so库得到audio_policy_module模块

通过audio_policy_module模块打开audio_policy_device设备

通过audio_policy_device设备创建audio_policy

hw_get_module函数加载硬件抽象层模块的过程

audio_policy实现在audio_policy_hal.cpp中,audio_policy_service_ops实现在AudioPolicyService.cpp中。create_audio_policy()函数就是创建并初始化一个legacy_audio_policy对象,AudioPolicyCompatClient是对audio_policy_service_ops的封装类,对外提供audio_policy_service_ops数据结构中定义的接口

Android AudioPolicyService服务启动过程

引用AudioPolicyCompatClient对象,这样音频管理器AudioPolicyManager就可以使用audio_policy_service_ops中的接口

优先加载/vendor/etc/audio_policy.conf配置文件,如果该配置文件不存在,则加载/system/etc/audio_policy.conf配置文件,如果该文件还是不存在,则通过函数defaultAudioPolicyConfig()来设置默认音频接口

设置各种音频流对应的音量调节点

通过名称打开对应的音频接口硬件抽象库

打开mAttachedOutputDevices对应的输出

将输出IOProfile封装为AudioOutputDescriptor对象

设置当前音频接口的默认输出设备

打开输出,在AudioFlinger中创建PlaybackThread线程,并返回该线程的id

设置可以使用的输出设备为mAttachedOutputDevices

将输出描述符对象AudioOutputDescriptor及创建的PlaybackThread线程id以键值对形式保存

设置默认输出设备

AudioPolicyManagerBase对象构造过程中主要完成以下几个步骤

loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE)加载audio_policy.conf配置文件

initializeVolumeCurves()初始化各种音频流对应的音量调节点

加载audio policy硬件抽象库:mpClientInterface->loadHwModule(mHwModules[i]->mName)

打开attached_output_devices输出mpClientInterface->openOutput();

保存输出设备描述符对象addOutput(output, outputDesc);

十、Android系统中所有的音频接口设备保存到AudioFlinger的成员变量mAudioHwDevs中

audio_policy.conf文件

从audio_policy.conf文件中可以发现,系统包含了primary、a2dp、usb等音频接口,对应着系统中的audio.<primary/a2dp/usb>.<device>.so。每个音频接口中又包含了若干个outputs & inputs,并且每个output or input又包含了若干个devices,且还有采样频率,声道数等信息。这些devices信息、采样频率信息 & 声道信息等都会保存在各自module的IOProfile中。按上文中audio_policy.conf配置文件所描述,系统最后会生成6个modules(eg.primary,a2dp,hdmi,r_submix,hs_usb & usb)以及7个outputs

十一、audio_policy.conf同时定义了多个audio接口

不同的Android产品在音频的设计上通常是存在差异的,而这些差异可以通过Audio的配置文件audio_policy.conf来获得。在Android系统中音频配置文件存放路径有两处,存放地址可以从AudioPolicyManagerBase.cpp文件中获取

在AudioPolicyManager.cpp文件中可以知道系统会首先加载vendor/etc目录下的configure文件,再加载system/etc目录下的configure文件。若这两者加载都发生错误的话,系统会加载default配置文件,并命名为primary module

通过loadGlobalConfig(root)函数来读取这些全局配置信息,通过loadHwModules()函数来加载系统配置的所有audio接口(加载音频接口),由于audio_policy.conf可以定义多个音频接口,因此该函数循环调用loadHwModule()来解析每个音频接口参数信息。Android定义HwModule类来描述每一个audio接口参数,定义IOProfile类来描述输入输出模式配置

/system/etc/audio_policy.conf

/vendor/etc/audio_policy.conf

加载audio_module模块

AudioPolicyManager通过读取audio_policy.conf配置文件,可以知道系统当前支持哪些音频接口以及attached的输入输出设备、默认输出设备。接下来就需要加载这些音频接口的硬件抽象库

AudioPolicyClientInterface提供了加载音频接口硬件抽象库的接口函数,AudioPolicyCompatClient通过代理audio_policy_service_ops实现AudioPolicyClientInterface接口

AudioPolicyCompatClient将音频模块加载工作交给audio_policy_service_ops,AudioPolicyService又将其转交给AudioFlinger

当AudioPolicyManagerBase构造时,它会根据用户提供的audio_policy.conf来分析系统中有哪些audio接口(primary,a2dp以及usb),然后通过AudioFlinger::loadHwModule加载各audio接口对应的库文件,并依次打开其中的output(openOutput)和input(openInput)

打开音频输出时创建一个audio_stream_out通道,并创建AudioStreamOut对象以及新建PlaybackThread播放线程

打开音频输入时创建一个audio_stream_in通道,并创建AudioStreamIn对象以及创建RecordThread录音线程

audio_policy.conf文件定义了两种音频配置信息 

当前系统支持的音频输入输出设备及默认输入输出设备,这些信息是通过global_configuration配置项来设置,在global_configuration中定义了三种音频设备信息

attached_output_devices:已连接的输出设备

default_output_device:默认输出设备

attached_input_devices:已连接的输入设备

系统支持的音频接口信息

audio_policy.conf定义了系统支持的所有音频接口参数信息,比如primary、a2dp、usb等

每种音频接口包含输入输出,每种输入输出又包含多种输入输出配置,每种输入输出配置又支持多种音频设备。AudioPolicyManagerBase首先加载/vendor/etc/audio_policy.conf,如果该文件不存在,则加载/system/etc/audio_policy.conf

audio_policy.conf同时定义了多个audio 接口,每一个audio接口包含若干output和input,而每个output和input又同时支持多种输入输出模式,每种输入输出模式又支持若干种设备

十二、通过AudioFlinger的loadHwModule加载各audio接口对应的库文件实现调用PlaybackThread播放线程或RecordThread录音线程

十三、AudioFlinger的openInput()方法调用流程分析

十四、AudioFlinger的openOutput()方法的调用流程分析

十五、Audio系统为了能正常播放音频数据,需要创建抽象的音频输出接口对象,打开音频输出过程

十六、打开音频输入的流程

十七、打开音频输出后,在AudioFlinger与AudioPolicyService中的表现形式

十八、打开音频输入后,在AudioFlinger与AudioPolicyService中的表现形式

十九、AudioPolicyService加载完系统定义的所有音频接口,并生成相应的数据对象

二十、AudioPolicyService与AudioTrack和AudioFlinger的关系

二十一、AudioPolicyService注册名为服务的流程

二十二、AudioTrack构造过程

二十三、AudioTrack和AudioFlinger的关系

二十四、audio_policy与AudioPolicyService、AudioPolicyCompatClient之间的关系

关注微信公众号,获取更多最新文章

Android Audio音频系统之深入浅出相关推荐

  1. 理解 Audio 音频系统二 之 audioserver AudioPolicyService

    理解 Audio 音频系统二 之 AudioPolicyService 二.audioserver & AudioPolicyService + AudioPolicy 启动流程总结 1. A ...

  2. Android ALSA音频系统架构分析(1)----从Loopback了解Audio

    /*********************************** * Author:刘江明 * Environment:MTK Android 6.0 * Date:2017年05月25日 * ...

  3. <一>Android Audio音频框架

    目录 1.0 设备驱动 2.0  android hal层 3.0  选择设备的暗箱策略AudioPolicy 4.0  软件层面的混音,AudioFlinger 5.0 完整的对外接口 AudioS ...

  4. Audio音频系统 —AudioFlinger(1)

    Android音频系统之AudioFlinger(一) 分类: Android专栏 2013-04-15 18:01 992人阅读 评论(0) 收藏 举报 目录(?)[+] AudioFlinger ...

  5. Android Audio音频通路(七)

    android audio 生产者与消费者 简介 全面接触生产者/消费者问题是在操作系统原理中,并发性原理讨论的问题 生产者/消费者问题.最近的工作偏向音频,接着上一篇文章,用生产者,消费者模型来理解 ...

  6. Android Audio 音频输出设备切换

    扬声器输出和耳机输出是音频系统最基本的音频输出通路,实际应用中用户可根据自己需要随意切换,具体表现是通过插入耳机选择耳机输出,拔出耳机选择默认的扬声器输出. 如图5-13所示,扬声器与耳机输出切换的实 ...

  7. android 车载音频系统,索尼推出支持Android Auto和Carplay车载音响系统

    拼 命 加 载 中 ... 索尼电子一直都有涉及各行各业(乱点科技树),不过它家的电子车载音响系统估计大家都没听说过吧?索尼电子8月19日推出一款XAV-AX100车载音响系统以更新其产品线. 如果你 ...

  8. Android Audio 音频路由

    一.在 AudioPolicyService 中,选择音频路由时会从当前音频流的类型获取音频的路由策略: /frameworks/av/services/audiopolicy/managerdefa ...

  9. Android中实现系统声音录制(内置声源的录制)-音频通道及framework调用流程分析

    推荐阅读 Android Audio音频系统 Android Framework学习路线

  10. Android audio音频流数据异常问题分析

    一.背景 在 Android 系统的开发过程当中,音频异常问题通常有如下几类,无声,调节不了声音,爆音,声音卡顿,声音效果异常(忽大忽小,低音缺失等)等.尤其声音效果这部分问题通常从日志上信息量较少, ...

最新文章

  1. PHP:第五章——字符串的概念
  2. 最新最全国内外架构开源技术干货资料
  3. linux常见基本命令
  4. Ubuntu16.04 下 Python3 虚拟环境安装 OpenCV
  5. 本周Web2.0小工具推荐[2008-09-13]
  6. 【01】 课程介绍 - 计算机视觉概述
  7. Hibernate之Criteria查询
  8. mysql格式化日期成分_MySQL格式化日期
  9. 【干货】这样写总结年终奖翻倍!
  10. append和extend区别
  11. 房地产软件信息化——CRM的“中海模式”穆利堂-movno1
  12. XMind 8 pro 破解教程
  13. 安卓系统中默认打开蓝牙 HCI snoop 文件的方法
  14. 生物与环境 —— 生命的力量
  15. 神威太湖之光之超级计算机,中国研发的“神威·太湖之光”,超级计算机能给我们带来什么?...
  16. 当电脑打开显示每日新闻联播主要内容
  17. 不用刷新,用 dfuse 流式搜索提供即时用户体验
  18. proe安装后 显示服务器未连接,proe许可证服务器主机名
  19. Dubbo线程池耗尽问题
  20. Pipeline流水线项目构建

热门文章

  1. Power Apps相关介绍
  2. godaddy又支持支付宝支付了。今天backorder了一个域名,尝试用支付宝支付。居然可以支付了。当时的汇率结算。...
  3. 【SDC】StreamSets实战之路-11-基础篇- StreamSets-数据流开发- Edge数据流设计
  4. 速腾聚创三维激光雷达 实现cartographer 建图复现工作(代完成)
  5. 运行navicat报出Missing required library libmysql_d.dll,126问题
  6. 拉钩教育高薪训练营学习笔记——分布式理论与分布式架构设计理论
  7. 支付宝第三代理支付 - 支付宝客户端授权
  8. 算法导论学习笔记13_贪心算法
  9. 通过银行卡号查询银行卡类型接口
  10. Java常用类详细讲解