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
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
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 默认音频
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;
}

浙公网安备 33010602011771号