Android 音频源码分析——AndroidRecord录音(一)
Android 音频源码分析——AndroidRecord录音(二)
Android 音频源码分析——AndroidRecord音频数据传输流程
Android 音频源码分析——audioserver启动
Android 音频源码分析——AudioFlinger
Android 音频源码分析——AudioTrack设备选择
基于Andorid9.0源码
以AudioTrack为例,梳理下输出设备选择流程。
音频设备选择的影响因素:
- AudioAttributes 声音流类型
- setForceUse 设置
- setPreferredDevice设置 (AudioRecord、AudioTrack、MediaRecorder、MediaPlayer)
- 等。。。。待研究
一、大多数情况输出设备选择
直接从AudioTrack.cpp 开始。
AudioTrack构造器
》AudioTrack::set(){
}
》AudioTrack::createTrack_l()
》audioFlinger->createTrack(input, output, &status);
》AudioFlinger::createTrack()
》AudioSystem::getOutputForAttr()
》AudioPolicyService::getOutputForAttr()
》AudioPolicyManager::getOutputForAttr()
status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
//获取stream type
*stream = streamTypefromAttributesInt(&attributes)
routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes)
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
*output = getOutputForDevice(device, session, *stream, config, flags);
}
- 通过AudioAttribute中的flags和usage获取对应的Stream type;
- AudioAttribute usage属性映射到strategy;
- 通过strategy 选择device类型;
- 选择音频设备、音频通路;
1. 获取stream type
通过flags和usage映射到 stream type
audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
{
// flags to stream type mapping
if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
return AUDIO_STREAM_ENFORCED_AUDIBLE;
}
if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
return AUDIO_STREAM_BLUETOOTH_SCO;
}
if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
return AUDIO_STREAM_TTS;
}
// usage to stream type mapping
switch (attr->usage) {
case AUDIO_USAGE_MEDIA:
case AUDIO_USAGE_GAME:
case AUDIO_USAGE_ASSISTANT:
case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
return AUDIO_STREAM_MUSIC;
case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
return AUDIO_STREAM_ACCESSIBILITY;
case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
return AUDIO_STREAM_SYSTEM;
case AUDIO_USAGE_VOICE_COMMUNICATION:
return AUDIO_STREAM_VOICE_CALL;
case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
return AUDIO_STREAM_DTMF;
case AUDIO_USAGE_ALARM:
return AUDIO_STREAM_ALARM;
case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
return AUDIO_STREAM_RING;
case AUDIO_USAGE_NOTIFICATION:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
case AUDIO_USAGE_NOTIFICATION_EVENT:
return AUDIO_STREAM_NOTIFICATION;
case AUDIO_USAGE_UNKNOWN:
default:
return AUDIO_STREAM_MUSIC;
}
}
2. 获取strategy
getStrategyForAttr会调到Engine的getStrategyForUsage函数
routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
{
// usage to strategy mapping
switch (usage) {
case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
return STRATEGY_ACCESSIBILITY;
case AUDIO_USAGE_MEDIA:
case AUDIO_USAGE_GAME:
case AUDIO_USAGE_ASSISTANT:
case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
return STRATEGY_MEDIA;
case AUDIO_USAGE_VOICE_COMMUNICATION:
return STRATEGY_PHONE;
case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
return STRATEGY_DTMF;
case AUDIO_USAGE_ALARM:
case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
return STRATEGY_SONIFICATION;
case AUDIO_USAGE_NOTIFICATION:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
case AUDIO_USAGE_NOTIFICATION_EVENT:
return STRATEGY_SONIFICATION_RESPECTFUL;
case AUDIO_USAGE_UNKNOWN:
default:
return STRATEGY_MEDIA;
}
}
AudioAttribute usage属性映射到strategy。
3. 获取设备类型
audio_devices_t AudioPolic