说明: 根据应用层设置的声音类型设置属性
framework/av/media/libmedia/AudioTrack.cpp
AudioTrack::setAttributesFromStreamType
2067 void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) {
2068 mAttributes.flags = 0x0;
2069
2070 switch(streamType) {
2071 case AUDIO_STREAM_DEFAULT:
2072 case AUDIO_STREAM_MUSIC:
2073 mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
2074 mAttributes.usage = AUDIO_USAGE_MEDIA;
2075 break;
2076 case AUDIO_STREAM_VOICE_CALL:
2077 mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
2078 mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
2079 break;
2080 case AUDIO_STREAM_ENFORCED_AUDIBLE:
2081 mAttributes.flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
根据streamType设置content_type、usage和flags。
根据声音属性确定它的类别/组
frameworks/av/services/audiopolicy/AudioPolicyManager.cpp
AudioPolicyManager::getStrategyForAttr
3921 uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
3922 // flags to strategy mapping
3923 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
3924 return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
3925 }
3926
3927 // usage to strategy mapping
3928 switch (attr->usage) {
3929 case AUDIO_USAGE_MEDIA:
3930 case AUDIO_USAGE_GAME:
3931 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
3932 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
3933 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
3934 return (uint32_t) STRATEGY_MEDIA;
3935
3936 case AUDIO_USAGE_VOICE_COMMUNICATION:
3937 return (uint32_t) STRATEGY_PHONE;
3938
3939 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
3940 return (uint32_t) STRATEGY_DTMF;
3941
3942 case AUDIO_USAGE_ALARM:
3943 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
3944 return (uint32_t) STRATEGY_SONIFICATION;
3945
3946 case AUDIO_USAGE_NOTIFICATION:
3947 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
3948 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
3949 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
3950 case AUDIO_USAGE_NOTIFICATION_EVENT:
3951 return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL;
3952
3953 case AUDIO_USAGE_UNKNOWN:
3954 default:
3955 return (uint32_t) STRATEGY_MEDIA;
3956 }
3957 }
根据声音类别/组确定播放(耳机/蓝牙/喇叭)
AudioPolicyManager::getDeviceForStrategy
如果在应用层选的是AUDIO_STREAM_VOICE_CALL,对应的strategy是STRATEGY_PHONE,分析下函数策略:
3970 audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
3971 bool fromCache)
3972 {
3973 uint32_t device = AUDIO_DEVICE_NONE;
3974
3975 if (fromCache) {
3976 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
3977 strategy, mDeviceForStrategy[strategy]);
3978 return mDeviceForStrategy[strategy];
3979 }
3980 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
3981 switch (strategy) {
4020 case STRATEGY_PHONE:
4021 // Force use of only devices on primary output if:
4022 // - in call AND
4023 // - cannot route from voice call RX OR
4024 // - audio HAL version is < 3.0 and TX device is on the primary HW module
4025 if (mPhoneState == AUDIO_MODE_IN_CALL) {
4026 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
4027 sp hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
4028 if (((mAvailableInputDevices.types() &
4029 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
4030 (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) &&
4031 (hwOutputDesc->getAudioPort()->mModule->mHalVersion <
4032 AUDIO_DEVICE_API_VERSION_3_0))) {
4033 availableOutputDeviceTypes = availablePrimaryOutputDevices();
4034 }
4035 }
4036 // for phone strategy, we first consider the forced use and then the available devices by order
4037 // of priority
4038 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
4039 case AUDIO_POLICY_FORCE_BT_SCO: //蓝牙
4040 if (!isInCall() || strategy != STRATEGY_DTMF) {
4041 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT//蓝牙车载设备
4042 if (device) break;
4043 }
4044 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; //蓝牙耳机
4045 if (device) break;
4046 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; //
4047 if (device) break;
4048 // if SCO device is requested but no SCO device is available, fall back to default case
4049 // FALL THROUGH
4050
4051 default: // FORCE_NONE
4052 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
4053 if (!isInCall() &&
4054 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
4055 (getA2dpOutput() != 0) && !mA2dpSuspended) {
4056 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; //蓝牙立体声
4057 if (device) break;
4058 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;//蓝牙立体耳机
4059 if (device) break;
4060 }
4061 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;//不带话筒的耳机
4062 if (device) break;
4063 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;//带话筒的耳机
4064 if (device) break;
4065 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
4066 if (device) break;
4067 if (mPhoneState != AUDIO_MODE_IN_CALL) {
4068 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
4069 if (device) break;
4070 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;//
4071 if (device) break;
4072 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
4073 if (device) break;
4074 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;//
4075 if (device) break;
4076 }
4077 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; //听筒
4078 if (device) break;
4079 device = mDefaultOutputDevice->mDeviceType;
4080 if (device == AUDIO_DEVICE_NONE) {
4081 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
4082 }
4083 break;
总结:
安卓手机打电话时:
DefaultKeyedVector > mOutputs;
class AudioOutputDescriptor: public AudioPortConfig
{
..........
const sp mProfile;
.....
}
配置文件格式如下:
27 primary {
28 outputs {
29 primary {
30 sampling_rates 44100
31 channel_masks AUDIO_CHANNEL_OUT_STEREO
32 formats AUDIO_FORMAT_PCM_16_BIT
33 devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL
34 flags AUDIO_OUTPUT_FLAG_PRIMARY
35 }
36 }
解析配置文件函数会把outputs选项中所有output放入到mOutputs中,显然这个配置文件中只有1个output。
每个output所有内容都保存到mProfile中,这样mProfile包括devices也就是该output支持的设备列表。
audio_io_handle_t AudioPolicyManager::getOutputForDevice(
audio_devices_t device,
audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
non_direct_output:
// ignoring channel mask due to downmix capability in mixer
// open a non direct output
// for non direct outputs, only PCM is supported
if (audio_is_linear_pcm(format)) {
// get which output is suitable for the specified stream. The actual
// routing change will happen when startOutput() will be called
SortedVector outputs = getOutputsForDevice(device, mOutputs);
// at this stage we should ignore the DIRECT flag as no direct output could be found earlier
flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
output = selectOutput(outputs, flags, format);
}
ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
"format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
ALOGV("getOutput() returns output %d", output);
return output;
}
getOutputsForDevice(device, mOutputs);传输mOutputs就是配置文件中所有output选项的数组。
SortedVector AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
DefaultKeyedVector > openOutputs)
{
SortedVector outputs;
ALOGVV("getOutputsForDevice() device %04x", device);
for (size_t i = 0; i < openOutputs.size(); i++) {
ALOGVV("output %d isDuplicated=%d device=%04x",
i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
outputs.add(openOutputs.keyAt(i));
}
}
return outputs;
}
就是相应的device,轮询mOutputs所有的output中的device选项,查看每个output支持的device如果支持( if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) ),这把该output加入outputs数组中( outputs.add(openOutputs.keyAt(i)))。返回这个outputs数组。
SortedVector outputs = getOutputsForDevice(device, mOutputs);
// at this stage we should ignore the DIRECT flag as no direct output could be found earlier
flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
output = selectOutput(outputs, flags, format);
在得到outputs数组,也就是device支持的output数组。调用selectOutput函数
audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector& outputs,
audio_output_flags_t flags,
audio_format_t format)
{
// select one output among several that provide a path to a particular device or set of
// devices (the list was previously build by getOutputsForDevice()).
// The priority is as follows:
// 1: the output with the highest number of requested policy flags
// 2: the primary output
// 3: the first output in the list
}
1
a. APP创建AudioTrack时传入flag
b. output对应的profle(/system/etc/audio_policy.conf)中也有flag
c. 使用上述a,b的flag进行比较,取出吻合度最高的output,也就是两个flag中bit吻合度最高的。如果最高吻合的output不止一个执行步骤2。
最高吻合的output中有primary output支持该设备,则选择primary output.
如果最高吻合的output咩有primary output,则选择第一个output。