RK audio 拨号同时输出Speaker和USB音频
reference: [RK3399][Android7.1]修改系统配置同时输出Speaker和USB音频
Android Audio代码分析 - Audio Strategy
一.Android5.1 音频切换
frameworks\av\services\audiopolicy\AudioPolicyManager.cpp
1.1.策略对应的 stream type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy( audio_stream_type_t stream) { ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "getStrategy() called for AUDIO_STREAM_PATCH" ); // stream to strategy mapping switch (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 result case 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; } } |
1.2.其中添加的判断语句意思为:判断声音是否通话 . isCall 直接返回 SPEAKER和USB_DEVICE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache) { uint32_t device = AUDIO_DEVICE_NONE; if (fromCache) { ALOGVV( "getDeviceForStrategy() from cache strategy %d, device %x" , strategy, mDeviceForStrategy[strategy]); return mDeviceForStrategy[strategy]; } audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types(); switch (strategy) { case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; if (!device) { ALOGE( "getDeviceForStrategy() no device found for " \ "STRATEGY_TRANSMITTED_THROUGH_SPEAKER" ); } break ; case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/ ); } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing on a remote device, use the the sonification behavior. // Note that we test this usecase before testing if media is playing because // the isStreamActive() method only informs about the activity of a stream, not // if it's for local playback. Note also that we use the same delay between both tests device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/ ); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing (or has recently played), use the same device device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/ ); } else { // when media is not playing anymore, fall back on the sonification behavior device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/ ); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; } break ; ………………………………………… default : ALOGW( "getDeviceForStrategy() unknown strategy: %d" , strategy); break ; } ALOGVV( "getDeviceForStrategy() strategy %d, device %x" , strategy, device); + if (isInCall()){ + ALOGD( "Gatsby getDeviceForStrategy() strategy \n" ); + return AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_USB_DEVICE; + } return device; } |
二.Android 7.1 音频策略
2.1.media.audio.device_policy media.audio.device_policy 默认音频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy, DeviceVector availableOutputDevices, DeviceVector availableInputDevices, const SwAudioOutputCollection &outputs) const { uint32_t device = AUDIO_DEVICE_NONE; uint32_t availableOutputDevicesType = availableOutputDevices.types(); switch (strategy) { …………………………………… char value[PROPERTY_VALUE_MAX]; property_get( "media.audio.device_policy" , value, "" ); if (value[ 0 ]) { uint32_t new_device = AUDIO_DEVICE_NONE; if (strstr(value, "hdmi" )) { ALOGD( "set audio policy to hdmi, availableOutputDevicesType : 0x%x" , availableOutputDevicesType); if (availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI) { ALOGD( "set audio policy to hdmi succeed" ); new_device |= AUDIO_DEVICE_OUT_HDMI; } } if (strstr(value, "speaker" )) { ALOGD( "set audio policy to speaker, availableOutputDevicesType : 0x%x" , availableOutputDevicesType); if (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER) { ALOGD( "set audio policy to speaker succeed" ); new_device |= AUDIO_DEVICE_OUT_SPEAKER; } } if (strstr(value, "usb" )) { ALOGD( "set audio policy to usb, availableOutputDevicesType : 0x%x" , availableOutputDevicesType); if (availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE) { ALOGD( "set audio policy to usb succeed" ); new_device |= AUDIO_DEVICE_OUT_USB_DEVICE; } } if (strstr(value, "bluetooth" )) { ALOGD( "set audio policy to bluetooth, availableOutputDevicesType : 0x%x" , availableOutputDevicesType); if (availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) new_device |= AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; else if (availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) new_device |= AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; else if (availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) new_device |= AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; } if (new_device != AUDIO_DEVICE_NONE) { device = new_device; } } ALOGVV( "getDeviceForStrategy() strategy %d, device %x" , strategy, device); return device; } |
分类:
RockChip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】