失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android Framework 音频子系统(02)音频系统框架

Android Framework 音频子系统(02)音频系统框架

时间:2019-10-05 16:18:29

相关推荐

Android Framework 音频子系统(02)音频系统框架

该系列文章总纲链接:专题分纲目录 Android Framework 音频子系统​​​​​​​

本章关键点总结 & 说明:

本章节主要关注➕ 以上思维导图下边音频系统框架 部分即可。主要是对音频系统框架 有一个基本的认识。

1 Android 音频系统框架简介

音频系统的 整个框架图如下所示:

针对这张框架图。对几个关键的音频类进行说明:

AudioFlinger:接收多个APP的数据,合并下发;是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完 成。AudioPolicyService:决定选择哪个设备输出,接上耳机用耳机,接上蓝牙设备用蓝牙;是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。AudioTrack:一个代理,APP 通过AudioTrack(binder通信,分Java层和C++层) 来访问AudioFlinger。

接下来从AndioTrack、AudioFlinger、AudioHAL的视角更详细的解读Audio的框架

从该图中我们要了解以下几个基本知识:

一个声卡对应 一/多个device。(device是指:喇叭、麦克风耳机等)一/多个device对应一个设备节点。一/多个设备节点(比如:/dev/snd/pcmc0d0p这种节点)对应一个output,output是多个device的组合;这些device属于同一个硬件上的不同端口。这些device支持同样的参数、采样率、通道。一个output对应一个线程thread。一个thread中有一/多个track。播放声音时,声音来源有多个。一个track对应一/多个AudioTrack。

2 Audio 框架系统基本概念

@1 device:比如声卡上的喇叭、耳机还是蓝牙等等,这些称之为device。输出设备device在Java层 AudioSystem定义如下:

public class AudioSystem{//...public static final int DEVICE_OUT_EARPIECE = 0x1; //听筒public static final int DEVICE_OUT_SPEAKER = 0x2; //扬声器public static final int DEVICE_OUT_WIRED_HEADSET = 0x4; //带话筒耳机public static final int DEVICE_OUT_WIRED_HEADPHONE = 0x8; //不带话筒耳机public static final int DEVICE_OUT_BLUETOOTH_SCO = 0x10; //蓝牙,面向 SCO方式,主要用于话音传输public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20; //蓝牙耳机,带话筒public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40; //蓝牙车载设备public static final int DEVICE_OUT_BLUETOOTH_A2DP = 0x80;//蓝牙立体声public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100; //蓝牙立体声耳机public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200; //蓝牙话筒public static final int DEVICE_OUT_AUX_DIGITAL = 0x400;//HDMI相关//...}

@2 output:为了便于管理, 把一个设备上具有相同参数的一组device称为output。它描述一些实际支持的设备(有实际硬件)

@3 module:Android系统里使用hardware module来访问硬件(声卡),module就是一个硬件操作库,一个module能支持哪些output,一个output能支持哪些device,使用配置文件/system/etc/audio_policy.conf来描述

@4 profile:配置,用来描述output,本可以支持哪些设备(仅逻辑上支持,不一定有实际硬件,比如耳机 output是插上耳机久支持,不插耳机就不支持,但profile一直支持)。

@5 out flag : 比如对于某个专业APP, 它只从HDMI播放声音, 这时就可以指定out flag为AUDIO_OUTPUT_FLAG_DIRECT,这会导致最终的声音无需混音即直接输出到对应的device。

@6stream type:app要播放声音, 要指定声音类型,这些声音的类型被称为stream type。它的值在C++层(AudioTrack.cpp)实现如下:

typedef enum {/* These values must kept in sync with* frameworks/base/media/java/android/media/AudioSystem.java*/AUDIO_STREAM_DEFAULT= -1,AUDIO_STREAM_MIN = 0,AUDIO_STREAM_VOICE_CALL = 0,//电话语音AUDIO_STREAM_SYSTEM = 1,//系统声音AUDIO_STREAM_RING = 2,//铃声 声音AUDIO_STREAM_MUSIC = 3,//音乐铃声AUDIO_STREAM_ALARM = 4,//警告音AUDIO_STREAM_NOTIFICATION= 5,//通知音AUDIO_STREAM_BLUETOOTH_SCO = 6,AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user* and must be routed to speaker*/AUDIO_STREAM_DTMF = 8,//DTMF 键盘拨号音AUDIO_STREAM_TTS = 9, /* Transmitted Through Speaker.* Plays over speaker only, silent on other devices.*/AUDIO_STREAM_ACCESSIBILITY = 10, /* For accessibility talk back prompts */AUDIO_STREAM_REROUTING = 11, /* For dynamic policy output mixes */AUDIO_STREAM_PATCH = 12, /* For internal audio flinger tracks. Fixed volume */AUDIO_STREAM_PUBLIC_CNT = AUDIO_STREAM_TTS + 1,AUDIO_STREAM_CNT = AUDIO_STREAM_PATCH + 1,} audio_stream_type_t;

它的值在Java(AudioTrack.java)层实现如下:

public class AudioSystem{/* These values must be kept in sync with system/audio.h *//** If these are modified, please also update Settings.System.VOLUME_SETTINGS* and attrs.xml and AudioManager.java.*//* The default audio stream */public static final int STREAM_DEFAULT = -1;/* The audio stream for phone calls */public static final int STREAM_VOICE_CALL = 0;//电话语音/* The audio stream for system sounds */public static final int STREAM_SYSTEM = 1;//系统声音/* The audio stream for the phone ring and message alerts */public static final int STREAM_RING = 2;//铃声声音/* The audio stream for music playback */public static final int STREAM_MUSIC = 3;//音乐声音/* The audio stream for alarms */public static final int STREAM_ALARM = 4;//警告音/* The audio stream for notifications */public static final int STREAM_NOTIFICATION = 5;//通知音/* @hide The audio stream for phone calls when connected on bluetooth */public static final int STREAM_BLUETOOTH_SCO = 6;/* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */public static final int STREAM_SYSTEM_ENFORCED = 7;/* @hide The audio stream for DTMF tones */public static final int STREAM_DTMF = 8;//DTMF键盘拨号音/* @hide The audio stream for text to speech (TTS) */public static final int STREAM_TTS = 9;/*** @deprecated Use {@link #numStreamTypes() instead}*/public static final int NUM_STREAMS = 5;//...}

@7 strategy:stream type的类型有很多, 看它属于哪一类(策略)用strategy。同时也要根据strategy确定要用什么设备播放,是喇叭、耳机还是蓝牙。根据device设置output。strategy的获取方法实现如下:

AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(AudioSystem::stream_type stream) {// stream to strategy mappingswitch (stream) {case AudioSystem::VOICE_CALL:case AudioSystem::BLUETOOTH_SCO:return STRATEGY_PHONE;case AudioSystem::RING:case AudioSystem::ALARM:return STRATEGY_SONIFICATION;case AudioSystem::NOTIFICATION:return STRATEGY_SONIFICATION_RESPECTFUL;case AudioSystem::DTMF:return STRATEGY_DTMF;default:ALOGE("unknown stream type");case AudioSystem::SYSTEM:// NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs// while key clicks are played produces a poor resultcase AudioSystem::TTS:case AudioSystem::MUSIC:return STRATEGY_MEDIA;case AudioSystem::ENFORCED_AUDIBLE:return STRATEGY_ENFORCED_AUDIBLE;}}

@8 policy:一个stream如何最终选择到一个device,这些stream如何互相影响(一个高优先级的声音会使得其他声音静音),等等等, 统称为policy (策略)。

@9 音频输出设备中的几个常见术语:

headset:表示既有听筒又有MicheadPhone:表示只有听筒,没有MiclineOut: 就是输出模拟信号到音箱设备

3 涉及到的文件简述

上图的代码主要分为3个部分,AudioFlinger、AudioPolicyService、应用部分(Java部分 & C++部分)

AudioFlinger部分相关文件以及目录位置如下:

AudioFlinger.cpp (frameworks/av/services/audioflinger/AudioFlinger.cpp)Threads.cpp(frameworks/av/services/audioflinger/Threads.cpp)Tracks.cpp(frameworks/av/services/audioflinger/Tracks.cpp)audio_hw_hal.cpp (hardware/libhardware_legacy/audio/Audio_hw_hal.cpp)AudioHardware.cpp (device/friendly-arm/common/libaudio/AudioHardware.cpp)

AudioPolicyService部分相关文件以及目录位置 如下:

AudioPolicyService.cpp (frameworks/av/services/audiopolicy/AudioPolicyService.cpp)AudioPolicyClientImpl.cpp (frameworks/av/services/audiopolicy/AudioPolicyClientImpl.cpp)AudioPolicyInterfaceImpl.cpp (frameworks/av/services/audiopolicy/AudioPolicyInterfaceImpl.cpp)AudioPolicyManager.cpp (frameworks/av/services/audiopolicy/AudioPolicyManager.cpp)

应用程序APP相关文件以及目录位置如下:

AudioTrack.java (frameworks/base/media/java/android/media/AudioTrack.java)android_media_AudioTrack.cpp (frameworks/base/core/jni/android_media_AudioTrack.cpp)AudioTrack.cpp (frameworks/av/media/libmedia/AudioTrack.cpp)AudioSystem.cpp (frameworks/av/media/libmedia/AudioSystem.cpp)

如果觉得《Android Framework 音频子系统(02)音频系统框架》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。