東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

Exoplayer学习08 android 音频HAL层架构学习

2021年5月28日星期五



学习方法很重要。

官方文档很全。

中文文档估计是机器翻译,看着就很奇怪。


1,android音频架构

android 音频的 硬件抽象层(HAL层)将 android.media包中api 实际调用到底层的音频驱动和硬件。

此处配图 ape_fwk_audio.png

如图中所示,在android Framework层中,提供了android.media的api,向上提供给三方应用,api 向下会调用JNI glue classes(粘合类)来调用native Framework中实现,如AudioRecord.cpp、AudioTrack.cpp,native framework调用Binder IPC Proxies 通过进程通信来访问 媒体服务 Media Service。

媒体服务MediaService实现了与HAL层实际交互的代码,HAL层提供硬件的所有功能,HAL层功能的实现会调用硬件相应驱动,从而调用物理硬件。

硬件驱动存放在Linux内核中,如Linux声音架构ALSA、开放声音系统OSS或自定义驱动程序。

2,定义

AudioEffect:音效处理  http://developer.android.com/reference/android/media/audiofx/AudioEffect.html

AudioFlinger:声音服务实现,运行在 mediaserver进程。

AudioMixer:混音,AudioFlinger中的模块,负责合并音轨、应用衰减、应用音效。

AudioResample:采样率转换,AudioFlinger中模块。https://source.android.com/devices/audio/src

audio policy:策略。

AudioRecord:从音频输入设备接收数据的低级别API。https://developer.android.com/reference/android/media/AudioRecord.html

audio source:枚举,指明声音来源;

track:音频流,youAudioTrack或AudioRecord API控制;

AudioTrack:用于向音频输出设备发送数据的低级别API。https://developer.android.com/reference/android/media/AudioTrack.html

OpenSL ES:Khronos 集团推行的音频 API 标准

MediaPlayer:播放音视频的客户端API;

SoundPool:播放音频的客户端API;

ToneGenerator:用于播放双音多频(DTMF)信号的客户端API;

tinyalsa:ALSA内核上采用BSD许可的小型用户模式API,用于实现HAL;

tee sink:一个AudioFlinger调试功能;

mediaserver:Android系统进程,包含AudioFlinger等媒体相关服务.


3,音频策略配置

在android7.0之前,采用device/<company>/<device>/audio/audio_policy.conf 路径配置 audio policy。

在android7.0之后,采用/system/etc/******/audio_policy_configuration.xml

此文件用于描述音频拓扑。

示例

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <globalConfiguration speaker_drc_enabled="true"/>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>Speaker</item>
                <item>Earpiece</item>
                <item>Built-In Mic</item>
            </attachedDevices>
            <defaultOutputDevice>Speaker</defaultOutputDevice>
            <mixPorts>
                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="primary input" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="Earpiece" sources="primary output"/>
                <route type="mix" sink="Speaker" sources="primary output"/>
                <route type="mix" sink="Wired Headset" sources="primary output"/>
                <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/>
            </routes>
        </module>
        <xi:include href="a2dp_audio_policy_configuration.xml"/>
    </modules>

    <xi:include href="audio_policy_volumes.xml"/>
    <xi:include href="default_volume_tables.xml"/>
</audioPolicyConfiguration>

顶层结构中 包含与 各个音频HAL硬件模块 对应的模块,其中每个模块都有一系列配置:

Mix ports :describe the possible config profiles for streams that can be opened at the audio HAL for playback and capture.

                    描述可以在音频HAL中打开以进行播放和捕获的流的可能配置配置文件;

Device ports : describe the devices that can be attached with their type (and optionally address and audio properties, if relevant).

                    描述可以连接的设备及其类型(如果相关,还可以选择地址和音频属性)。

Routes : is separated from the mix port descriptor, enabling the description of routes from device to device or stream to device.

                路由与mix ports 描述符分开,从而可以描述从设备到设备或从流到设备的路由。

4,音效

可以使用audio_effects.xml静态创建音效,或使用系统API创建和启用音效。

静态方式创建,在audio_effects.xml添加特定部分,如

<deviceEffects>
<devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom">
        <apply effect="agc"/>
      </devicePort>
  </deviceEffects>
  

或使用系统API创建,使用 android.media.audiofx.AudioEffect类

从android10开始,音效也支持多声道。。。。

5,音视频同步

android media framework可以使用几种方式处理 音视频内容

本地解码、压缩音频分载offload、压缩音频直通(AC 3)、多媒体隧道(tunneling)、多媒体直通。

图中描述 多媒体对到音频同步流程。

看的头疼,太难了。。。。

--
senRsl
2021年05月28日13:56:12

没有评论 :

发表评论