一、在 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 音频路由相关推荐

  1. Android Audio音频通路(七)

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

  2. <一>Android Audio音频框架

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

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

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

  4. Android Audio子系统路由策略(三十六)

    AP(Application Processor主处理器)<-->DSP(Codec)<-->BP(Baseband Processor基带处理器,猫)一.AudioTrack ...

  5. 【Android】Audio音频输出通道切换 - 蓝牙bluetooth、外放

    参考: [Android]Audio音频输出通道切换 - 蓝牙.外放 Android Audio 音频输出通道切换 为什么 iOS 或 Android 设备连接蓝牙设备后不能通过蓝牙设备接电话? xq ...

  6. Android Audio - 支持多个APK同时录音

    Android Audio - 支持多个APK同时录音 原理说明 Android4.4 修改方法 Android5.1 & 6.0 修改方法 Android8.1 修改方法 Android9. ...

  7. Android Audio - 支持多应用同时录音_Android8.1修改方法

    支持多应用同时录音_Android8.1修改方法 修改方法 与之相关 修改方法 源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\ ...

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

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

  9. Android 9 Audio系统笔记:音频路由实现——从AudioTrack到audiohal

    目录 一.动态路由的初始化 1.获取路由策略 2.向AudioPolicyManager注册路由策略 二.动态路由的路由流程,以AudioTrack创建为例 创建AudioTrack的路由选择 如何定 ...

最新文章

  1. 洛谷:P3950 部落冲突
  2. 从科学简历看研究方法——爱因斯坦探索性的演绎法
  3. labelme标注需要精确标注吗_国内需要一个数据标注平台
  4. 等参元八节点matlab,四边形八节点等参元matlab程序
  5. PPIO创始人王闻宇:从PPTV到PPIO,创业路上的挑战与思考
  6. charles 手机证书下载安装
  7. 【机器学习】sklearn数据特征预处理:归一化和标准化
  8. 基于用户滚动应用CSS
  9. CSS中的contenteditable属性
  10. TM2008预览版试用 速度快完美兼容Vista
  11. 【云原生】还不会使用linux?快看这里,在window快速安装centos系统
  12. 时间--cd //lastyear
  13. python中的and_PYTHON中的“and”是什么意思
  14. (网络视频监控)面试题12
  15. 从苏宁电器到卡巴斯基第27篇:难忘的三年硕士时光 III
  16. 华亭一中2021年高考成绩查询,华亭一中2019高考又传佳讯!
  17. 为什么使用HashMap需要重写hashcode和equals方法_最通俗易懂搞定HashMap的底层原理...
  18. 【Kaggle从入门到放弃】(01):竞赛类型
  19. 【组件-工具】小程序ui组件Color UI快速入门
  20. java实现7天未收货则自动收货

热门文章

  1. java实现简易计算器,实现加减乘除,括号,算式查错,
  2. 【工具】1063- 前端40+精选VSCode插件,总有几个你未拥有!
  3. 六位不重复房间ID生成器,不使用Redis和额外数据结构
  4. 同步已有数据库到Django框架报错
  5. 如何用Python从海量文本抽取主题?【转载:王树义】
  6. python拼音数字输出接口_python: 拼音处理模块
  7. 13种内存卡复活方法
  8. Zblog的控制面板代码
  9. 关于微信的APP支付、公众号(服务号)支付,商户问题
  10. 修改Mac默认设置使Mac支持NTFS硬盘的读写