AudioTrack过程

AudioTrack流程

应用层设置声音类型

设置属性

说明: 根据应用层设置的声音类型设置属性
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 } 

确定播放设备

根据声音类别/组确定播放(耳机/蓝牙/喇叭)
AudioTrack过程_第1张图片
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;   

总结:
安卓手机打电话时:

  1. 如果使用强制设备来播放声音,比如扬声器和蓝牙。
  2. 如果没有使用强制设备来播放
    2.1 如果连接上蓝牙车载导航,优先使用车载导航播放声音
    2.2 连上耳机 ,使用耳机播放声音
    2.3 如果蓝牙,耳机都没有连接,则使用扬声器来播放声音。

确定outputs

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数组。

从outputs 选择output

        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。

后续

  1. 确定了output也就确定了playbackThread
    2)在playbackThread中创建了对应的track
    3)APP的AudioTrack和playbackThread的mTracks中的track之间建立共享内存。

你可能感兴趣的:(音频)