Android Audio 音频路由
一、在 AudioPolicyService 中,选择音频路由时会从当前音频流的类型获取音频的路由策略:
/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");return mEngine->getStrategyForStream(stream);
}
/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{// stream to strategy mappingswitch (stream) {case AUDIO_STREAM_VOICE_CALL:case AUDIO_STREAM_BLUETOOTH_SCO:return STRATEGY_PHONE;case AUDIO_STREAM_RING:case AUDIO_STREAM_ALARM:return STRATEGY_SONIFICATION;case AUDIO_STREAM_NOTIFICATION:return STRATEGY_SONIFICATION_RESPECTFUL;case AUDIO_STREAM_DTMF:return STRATEGY_DTMF;default:ALOGE("unknown stream type %d", stream);case AUDIO_STREAM_SYSTEM:// NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs// while key clicks are played produces a poor resultcase AUDIO_STREAM_MUSIC:return STRATEGY_MEDIA;case AUDIO_STREAM_ENFORCED_AUDIBLE:return STRATEGY_ENFORCED_AUDIBLE;case AUDIO_STREAM_TTS:return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;case AUDIO_STREAM_ACCESSIBILITY:return STRATEGY_ACCESSIBILITY;case AUDIO_STREAM_REROUTING:return STRATEGY_REROUTING;}
}
音频策略枚举:
enum routing_strategy {STRATEGY_MEDIA, // 媒体策略STRATEGY_PHONE, // 电话策略STRATEGY_SONIFICATION, // 通知策略STRATEGY_SONIFICATION_RESPECTFUL,STRATEGY_DTMF, // DTMF 策略STRATEGY_ENFORCED_AUDIBLE, // 强制输出策略STRATEGY_TRANSMITTED_THROUGH_SPEAKER,STRATEGY_ACCESSIBILITY,STRATEGY_REROUTING,NUM_STRATEGIES
};
二、获取到音频路由策略类型后,通过调用 getDeviceForStrategy() 选择最终的输出设备
/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
{DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();return getDeviceForStrategyInt(strategy, availableOutputDevices,availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
}
audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,DeviceVector availableOutputDevices,DeviceVector availableInputDevices,const SwAudioOutputCollection &outputs,uint32_t outputDeviceTypesToIgnore) const
{uint32_t device = AUDIO_DEVICE_NONE;uint32_t availableOutputDevicesType =availableOutputDevices.types() & ~outputDeviceTypesToIgnore;switch (strategy) {... ...case STRATEGY_MEDIA: {uint32_t device2 = AUDIO_DEVICE_NONE;if (strategy != STRATEGY_SONIFICATION) {// no sonification on remote submix (e.g. WFD)if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,String8("0")) != 0) {device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;}}if (isInCall() && (strategy == STRATEGY_MEDIA)) {device = getDeviceForStrategyInt(STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,outputDeviceTypesToIgnore);break;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;}if ((device2 == AUDIO_DEVICE_NONE) &&(mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&outputs.isA2dpSupported()) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;}}if ((device2 == AUDIO_DEVICE_NONE) &&(mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;}if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {// no sonification on aux digital (e.g. HDMI)device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;}if ((device2 == AUDIO_DEVICE_NONE) &&(mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;}int device3 = AUDIO_DEVICE_NONE;if (strategy == STRATEGY_MEDIA) {// ARC, SPDIF and AUX_LINE can co-exist with others.device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);}device2 |= device3;// device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or// STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwisedevice |= device2;// If hdmi system audio mode is on, remove speaker out of output list.if ((strategy == STRATEGY_MEDIA) &&(mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {device &= ~AUDIO_DEVICE_OUT_SPEAKER;}// for STRATEGY_SONIFICATION:// if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE insteadif ((strategy == STRATEGY_SONIFICATION) &&(device & AUDIO_DEVICE_OUT_SPEAKER) &&(availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;device &= ~AUDIO_DEVICE_OUT_SPEAKER;}} break;... ...
}
通过判断音频设备是否连接,及相关优先级进行添加设备或移除设备,这里可以通过自定义去完成音频输出的优先级。
常见设备的定义:
/system/media/audio/include/system/audio-base.h
enum {AUDIO_DEVICE_NONE = 0x0u,AUDIO_DEVICE_BIT_IN = 0x80000000u,AUDIO_DEVICE_BIT_DEFAULT = 0x40000000u,AUDIO_DEVICE_OUT_EARPIECE = 0x1u,AUDIO_DEVICE_OUT_SPEAKER = 0x2u,AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4u,AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8u,AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10u,AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20u,AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40u,AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80u,AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100u,AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200u,AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400u,AUDIO_DEVICE_OUT_HDMI = 0x400u, // OUT_AUX_DIGITALAUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800u,AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000u,AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000u,AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000u,AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000u,AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000u,AUDIO_DEVICE_OUT_LINE = 0x20000u,AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000u,AUDIO_DEVICE_OUT_SPDIF = 0x80000u,AUDIO_DEVICE_OUT_FM = 0x100000u,AUDIO_DEVICE_OUT_AUX_LINE = 0x200000u,AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000u,AUDIO_DEVICE_OUT_IP = 0x800000u,AUDIO_DEVICE_OUT_BUS = 0x1000000u,AUDIO_DEVICE_OUT_PROXY = 0x2000000u,AUDIO_DEVICE_OUT_USB_HEADSET = 0x4000000u,AUDIO_DEVICE_OUT_HEARING_AID = 0x8000000u,AUDIO_DEVICE_OUT_ECHO_CANCELLER = 0x10000000u,AUDIO_DEVICE_OUT_DEFAULT = 0x40000000u, // BIT_DEFAULTAUDIO_DEVICE_IN_COMMUNICATION = 0x80000001u, // BIT_IN | 0x1AUDIO_DEVICE_IN_AMBIENT = 0x80000002u, // BIT_IN | 0x2AUDIO_DEVICE_IN_BUILTIN_MIC = 0x80000004u, // BIT_IN | 0x4AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000008u, // BIT_IN | 0x8AUDIO_DEVICE_IN_WIRED_HEADSET = 0x80000010u, // BIT_IN | 0x10AUDIO_DEVICE_IN_AUX_DIGITAL = 0x80000020u, // BIT_IN | 0x20AUDIO_DEVICE_IN_HDMI = 0x80000020u, // IN_AUX_DIGITALAUDIO_DEVICE_IN_VOICE_CALL = 0x80000040u, // BIT_IN | 0x40AUDIO_DEVICE_IN_TELEPHONY_RX = 0x80000040u, // IN_VOICE_CALLAUDIO_DEVICE_IN_BACK_MIC = 0x80000080u, // BIT_IN | 0x80AUDIO_DEVICE_IN_REMOTE_SUBMIX = 0x80000100u, // BIT_IN | 0x100AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = 0x80000200u, // BIT_IN | 0x200AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = 0x80000400u, // BIT_IN | 0x400AUDIO_DEVICE_IN_USB_ACCESSORY = 0x80000800u, // BIT_IN | 0x800AUDIO_DEVICE_IN_USB_DEVICE = 0x80001000u, // BIT_IN | 0x1000AUDIO_DEVICE_IN_FM_TUNER = 0x80002000u, // BIT_IN | 0x2000AUDIO_DEVICE_IN_TV_TUNER = 0x80004000u, // BIT_IN | 0x4000AUDIO_DEVICE_IN_LINE = 0x80008000u, // BIT_IN | 0x8000AUDIO_DEVICE_IN_SPDIF = 0x80010000u, // BIT_IN | 0x10000AUDIO_DEVICE_IN_BLUETOOTH_A2DP = 0x80020000u, // BIT_IN | 0x20000AUDIO_DEVICE_IN_LOOPBACK = 0x80040000u, // BIT_IN | 0x40000AUDIO_DEVICE_IN_IP = 0x80080000u, // BIT_IN | 0x80000AUDIO_DEVICE_IN_BUS = 0x80100000u, // BIT_IN | 0x100000AUDIO_DEVICE_IN_PROXY = 0x81000000u, // BIT_IN | 0x1000000AUDIO_DEVICE_IN_USB_HEADSET = 0x82000000u, // BIT_IN | 0x2000000AUDIO_DEVICE_IN_BLUETOOTH_BLE = 0x84000000u, // BIT_IN | 0x4000000AUDIO_DEVICE_IN_DEFAULT = 0xC0000000u, // BIT_IN | BIT_DEFAULT
};
音频输入类似,Android 9.0源码为例,不同版本会存在差异
Android Audio 音频路由相关推荐
- Android Audio音频通路(七)
android audio 生产者与消费者 简介 全面接触生产者/消费者问题是在操作系统原理中,并发性原理讨论的问题 生产者/消费者问题.最近的工作偏向音频,接着上一篇文章,用生产者,消费者模型来理解 ...
- <一>Android Audio音频框架
目录 1.0 设备驱动 2.0 android hal层 3.0 选择设备的暗箱策略AudioPolicy 4.0 软件层面的混音,AudioFlinger 5.0 完整的对外接口 AudioS ...
- Android Audio 音频输出设备切换
扬声器输出和耳机输出是音频系统最基本的音频输出通路,实际应用中用户可根据自己需要随意切换,具体表现是通过插入耳机选择耳机输出,拔出耳机选择默认的扬声器输出. 如图5-13所示,扬声器与耳机输出切换的实 ...
- Android Audio子系统路由策略(三十六)
AP(Application Processor主处理器)<-->DSP(Codec)<-->BP(Baseband Processor基带处理器,猫)一.AudioTrack ...
- 【Android】Audio音频输出通道切换 - 蓝牙bluetooth、外放
参考: [Android]Audio音频输出通道切换 - 蓝牙.外放 Android Audio 音频输出通道切换 为什么 iOS 或 Android 设备连接蓝牙设备后不能通过蓝牙设备接电话? xq ...
- Android Audio - 支持多个APK同时录音
Android Audio - 支持多个APK同时录音 原理说明 Android4.4 修改方法 Android5.1 & 6.0 修改方法 Android8.1 修改方法 Android9. ...
- Android Audio - 支持多应用同时录音_Android8.1修改方法
支持多应用同时录音_Android8.1修改方法 修改方法 与之相关 修改方法 源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\ ...
- Android audio音频流数据异常问题分析
一.背景 在 Android 系统的开发过程当中,音频异常问题通常有如下几类,无声,调节不了声音,爆音,声音卡顿,声音效果异常(忽大忽小,低音缺失等)等.尤其声音效果这部分问题通常从日志上信息量较少, ...
- Android 9 Audio系统笔记:音频路由实现——从AudioTrack到audiohal
目录 一.动态路由的初始化 1.获取路由策略 2.向AudioPolicyManager注册路由策略 二.动态路由的路由流程,以AudioTrack创建为例 创建AudioTrack的路由选择 如何定 ...
最新文章
- 洛谷:P3950 部落冲突
- 从科学简历看研究方法——爱因斯坦探索性的演绎法
- labelme标注需要精确标注吗_国内需要一个数据标注平台
- 等参元八节点matlab,四边形八节点等参元matlab程序
- PPIO创始人王闻宇:从PPTV到PPIO,创业路上的挑战与思考
- charles 手机证书下载安装
- 【机器学习】sklearn数据特征预处理:归一化和标准化
- 基于用户滚动应用CSS
- CSS中的contenteditable属性
- TM2008预览版试用 速度快完美兼容Vista
- 【云原生】还不会使用linux?快看这里,在window快速安装centos系统
- 时间--cd //lastyear
- python中的and_PYTHON中的“and”是什么意思
- (网络视频监控)面试题12
- 从苏宁电器到卡巴斯基第27篇:难忘的三年硕士时光 III
- 华亭一中2021年高考成绩查询,华亭一中2019高考又传佳讯!
- 为什么使用HashMap需要重写hashcode和equals方法_最通俗易懂搞定HashMap的底层原理...
- 【Kaggle从入门到放弃】(01):竞赛类型
- 【组件-工具】小程序ui组件Color UI快速入门
- java实现7天未收货则自动收货