当前位置:网站首页>Audio device strategy audio device output and input selection is based on 7.0 code

Audio device strategy audio device output and input selection is based on 7.0 code

2022-07-07 17:36:00 QXXXD

The archive , I don't want to stay here , Not much All in Enginee.cpp It says in the

1. Output selection

Overall process

  1. First, we will get the current collection of devices availableOutputDevices

  2. And then according to the incoming strategty Type to match

  3. Before selecting, it will check whether it is under special circumstances ( If on the phone )

  4. Finally, match the equipment according to priority .

The strategy for audio device selection is defined in AudioPolicyManager Medium getDeviceForStrategy() Method , The most suitable equipment will be selected according to the current equipment status and connected equipment , The concrete realization is frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp in .

The following notes explain clearly , Parameter is strategy and fromCache, If fromCache = true, From mDeviceForStrategy[] choice , Otherwise keep going down .

mDeviceForStrategy[NUM_STRATEGIES] Is an array .

frameworks/av/services/audiopolicy/common/include/RoutingStrategy.h
 enum routing_strategy {
    STRATEGY_MEDIA,
    STRATEGY_PHONE,
    STRATEGY_SONIFICATION,
    STRATEGY_SONIFICATION_RESPECTFUL,
    STRATEGY_DTMF,
    STRATEGY_ENFORCED_AUDIBLE,
    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
    STRATEGY_ACCESSIBILITY,
    STRATEGY_REROUTING,
    NUM_STRATEGIES
}; 

frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.h

virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy,
                                             bool fromCache); 

1.1 AudioPolicyManager.cpp The specific implementation of

frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

The following logic involves getDeviceForStrategy Call to
  • void AudioPolicyManager::setPhoneState(audio_mode_t state)

  • audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream —)

  • status_t AudioPolicyManager::getOutputForAttr

  • status_t AudioPolicyManager::startOutput(

  • status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,int *index audio_devices_t device)

  • audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)

  • void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy, audio_io_handle_t ouptutToSkip)

  • status_t AudioPolicyManager::connectAudioSource(const sp& sourceDesc){

  • void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,audio_io_handle_t ouptutToSkip){

  • void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)

  • audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp& outputDesc, bool fromCache)

  • audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {

  • void AudioPolicyManager::updateDevicesAndOutputs()

  • uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp

  • float AudioPolicyManager::computeVolume(audio_stream_type_t stream,

  • void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,bool starting, bool stateChange)

  • status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,

audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
                                                         bool fromCache) {
    // Routing
    // see if we have an explicit route
    // scan the whole RouteMap, for each entry, convert the stream type to a strategy
    // (getStrategy(stream)).
    // if the strategy from the stream type in the RouteMap is the same as the argument above,
    // and activity count is non-zero
    // the device = the device from the descriptor in the RouteMap, and exit.
    for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
        sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
        routing_strategy routeStrategy = getStrategy(route->mStreamType); // Still call getDeviceForStrategy
        if ((routeStrategy == strategy) && route->isActive()) {
            return route->mDeviceDescriptor->type();
        }
    }

    if (fromCache) {
        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
              strategy, mDeviceForStrategy[strategy]);
        return mDeviceForStrategy[strategy];
    }
    return mEngine->getDeviceForStrategy(strategy);
} 
The concrete realization is Engine.cpp in

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream) {
    // 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;
    }
} 
audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const {
    DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
    DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();

    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();

    return getDeviceForStrategyInt(strategy, availableOutputDevices,
                                   availableInputDevices, outputs);
} 

1.2 in the light of STRATEGY_MEDIA analysis , The priority of playback device is as follows

  • AUDIO_DEVICE_OUT_BLUETOOTH_A2DP
  • AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES( Ordinary Bluetooth headset )
  • AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER( Bluetooth speaker ) // This place belongs to setForceUse Forced queue jumping (if FORCE_SPEAKER)AUDIO_DEVICE_OUT_SPEAKER( The speaker )
  • AUDIO_DEVICE_OUT_WIRED_HEADPHONE( Regular headphones , I can only listen to , Can't manipulate the playback )
  • AUDIO_DEVICE_OUT_LINE
  • AUDIO_DEVICE_OUT_WIRED_HEADSET( Line control earphone )
  • AUDIO_DEVICE_OUT_USB_HEADSET(USB The headset )
case STRATEGY_MEDIA: {
        uint32_t device2 = AUDIO_DEVICE_NONE;

        if (isInCall() && (device == AUDIO_DEVICE_NONE)) {  // For calls 
            // when in call, get the device for Phone strategy
            device = getDeviceForStrategy(STRATEGY_PHONE);
            break;
        }

        if (strategy != STRATEGY_SONIFICATION) {// And tips for special treatment 
            // no sonification on remote submix (e.g. WFD)
            if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                                 String8("0")) != 0) {
                device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
            }
        }
        if (isInCall() && (strategy == STRATEGY_MEDIA)) {
            device = getDeviceForStrategyInt(
                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
            break;
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                (outputs.isA2dpOnPrimary() || (outputs.getA2dpOutput() != 0))) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;   //A2DP
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; // Bluetooth headset 
            }
            if (device2 == AUDIO_DEVICE_NONE) {
                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; // Bluetooth speakers 
            }
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
            (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {// If force speker  The speaker   horn 
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; // Ordinary wired headphones   Without a microphone 
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; // Wired headset with microphone 
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;  //USB equipment  
        }
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
        }
        if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
            && (device2 == AUDIO_DEVICE_NONE)) {
            // no sonification on aux digital (e.g. HDMI)
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
        }
        if ((device2 == AUDIO_DEVICE_NONE) &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)
                && (strategy != STRATEGY_SONIFICATION)) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
        }
#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
        if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
            && (device2 == AUDIO_DEVICE_NONE)) {
            // no sonification on WFD sink
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_PROXY;
        }
#endif
        if (device2 == AUDIO_DEVICE_NONE) {
            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; //  Exorcism   The speaker   horn 
        }
        int device3 = AUDIO_DEVICE_NONE;
        if (strategy == STRATEGY_MEDIA) {/// If arc,spdif,aux_line You can use , Assign a value to device3
            // ARC, SPDIF and AUX_LINE can co-exist with others.
            device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
        }

        device2 |= device3;
        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
        device |= device2;

        // If hdmi system audio mode is on, remove speaker out of output list.
        if ((strategy == STRATEGY_MEDIA) &&
            (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
                AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
            device &= ~AUDIO_DEVICE_OUT_SPEAKER;
        }
        } break; 

2. Input selection

Audio Device Strategy Audio devices Input selection 7.0

1. Input device selection

1.1 MediaRecorder java layer setAudioSource

With MediaRecorder For example , Don't think about anything else .setAudioSource Set input source

 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//  Set up the microphone  

frameworks/base/media/java/android/media/MediaRecorder.java

AudioSource The following categories are defined

/** Default audio source **/
public static final int DEFAULT = 0; // Default 
/** Microphone audio source */
public static final int MIC = 1; // mike 
/** Voice call uplink (Tx) audio source */
public static final int VOICE_UPLINK = 2; // The phone goes up 
/** Voice call downlink (Rx) audio source */
public static final int VOICE_DOWNLINK = 3; // The phone goes down 
/** Voice call uplink + downlink audio source */
public static final int VOICE_CALL = 4;  // Telephone recording 
/** Microphone audio source with same orientation as camera if available, the main
 *  device microphone otherwise */
public static final int CAMCORDER = 5;  // Camera Mike 
public static final int VOICE_RECOGNITION = 6; // speech recognition 
public static final int VOICE_COMMUNICATION = 7;// Internet phone 
public static final int REMOTE_SUBMIX = 8; // For recording 
public static final int UNPROCESSED = 9;  // Raw sound not processed 
@SystemApi
public static final int RADIO_TUNER = 1998; // radio broadcast 
@SystemApi
public static final int HOTWORD = 1999; 

Continue to look at MediaRecorder

public native void setAudioSource(int audio_source)
        throws IllegalStateException; 

adopt JNI Call to mediarecorder.cpp

frameworks/base/media/jni/android_media_MediaRecorder.cpp

static void
android_media_MediaRecorder_setVideoSource(JNIEnv *env, jobject thiz, jint vs) {
    sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
} 

frameworks/av/media/libmedia/mediarecorder.cpp

status_t MediaRecorder::setAudioSource(int as){
 status_t ret = mMediaRecorder->setAudioSource(as);
} 

1.2 mMediaRecorder Who is it?

Looking at mMediaRecorder example , It's a IMediaPlayerService Of service object , Called createMediaRecorder()

MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL)
{
    const sp<IMediaPlayerService> service(getMediaPlayerService());
    if (service != NULL) {
        mMediaRecorder = service->createMediaRecorder(opPackageName);
    }
} 

frameworks/av/media/libmedia/IMediaPlayerService.cpp

Here is the obvious binder operation ,BnMediaPlayerService It is defined as follows

virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) {
    Parcel data, reply;
    data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
    data.writeString16(opPackageName);
    remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
    return interface_cast<IMediaRecorder>(reply.readStrongBinder());
} 

MediaPlayerService Inherit BnMediaPlayerService

frameworks/av/media/libmediaplayerservice/MediaPlayerService.h

class MediaPlayerService : public BnMediaPlayerService 

This is through binder Arrived MediaRecorderClient, You know recorder Object is MediaRecorderClient

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName){
    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);
    return recorder;
} 

1.3 MediaRecorderClient.cpp Of setAudioSource

Here you can continue to see setAudioSource 了

frameworks/av/media/libmediaplayerservice/MediaRecorderClient.cpp

status_t MediaRecorderClient::setAudioSource(int as) {
    return mRecorder->setAudioSource((audio_source_t)as);
}
MediaRecorderBase      *mRecorder; 

mRecorder by MediaRecorderBase example ,StagefrightRecorder Inherited from MediaRecorderBase, Here we continue to see StagefrightRecorder

frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp

struct StagefrightRecorder : public MediaRecorderBase {
status_t StagefrightRecorder::setAudioSource(audio_source_t as) {
   
    if (as == AUDIO_SOURCE_DEFAULT) {
        mAudioSource = AUDIO_SOURCE_MIC;
    } else {
        mAudioSource = as;
    }
}
} 

StagefrightRecorder According to mAudioSource To create audioSource……

sp<MediaCodecSource> StagefrightRecorder::createAudioSource() {
 
sp<AudioSource> audioSource = AVFactory::get()->createAudioSource(           
} 

frameworks/av/media/libavextensions/stagefright/AVFactory.cpp

AudioSource* AVFactory::createAudioSource(
    return new AudioSource(inputSource, opPackageName, sampleRate,
                            channels, outSampleRate, clientUid, clientPid);
} 

AudioSource Has created AudioRecord

frameworks/av/media/libstagefright/AudioSource.cpp

mRecord = new AudioRecord(inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, 

The following code is AudioRecord In the construction method of ,inputsource It's the parameter we passed in above .

frameworks/av/media/libmedia/AudioRecord.cpp

mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
        notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
        uid, pid, pAttributes);
 //set Method        
set(){
 if (pAttributes == NULL) {
        mAttributes.source = inputSource;
    } 
} 

mAttributes Apply to openRecord_l In the method , You can see AudioSystem Called getInputForAttr

status_t AudioRecord::openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName) {
status = AudioSystem::getInputForAttr(&mAttributes, &input,mSessionId,mClientPid,mClientUid,mSampleRate, mFormat, mChannelMask,
                                        mFlags, mSelectedDeviceId);
} 

frameworks/av/media/libmedia/AudioSystem.cpp

status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,) {
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return NO_INIT;
    return aps->getInputForAttr(
            attr, input, session, pid, uid,
            samplingRate, format, channelMask, flags, selectedDeviceId);
} 

frameworks/av/media/libmedia/IAudioPolicyService.cpp

Focus on aps, yes IAudioPolicyService. Click in and find it again binder

virtual status_t getInputForAttr(const audio_attributes_t *attr,){
  status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);

} 

frameworks/av/services/audiopolicy/service/AudioPolicyService.h

class AudioPolicyService :
    public BinderService<AudioPolicyService>,
    public BnAudioPolicyService, 

AudioPolicyService Inherit BnAudioPolicyService,BnAudioPolicyService To achieve in AudioPolicyInterface,AudioPolicyManager Inherit again AudioPolicyInterface. Finally came AudioPolicyManager.cpp

1.4 AudioPolicyManager.cpp Strategy in

frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

device = getDeviceAndMixForInputSource(inputSource, &policyMix); 
*input = getInputForDevice(device, address, session, uid, inputSource,
                               samplingRate, format, channelMask, flags,
                               policyMix); 

audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) {
    for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
         sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
         if (inputSource == route->mSource && route->isActive()) {
             return route->mDeviceDescriptor->type();
         }
     }

     return mEngine->getDeviceForInputSource(inputSource);
} 

Here are the specific strategies

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const {
    const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
    const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
    audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;

    uint32_t device = AUDIO_DEVICE_NONE;

    switch (inputSource) {
    case AUDIO_SOURCE_VOICE_UPLINK:
      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
          device = AUDIO_DEVICE_IN_VOICE_CALL;
          break;
      }
      break;

    case AUDIO_SOURCE_DEFAULT:
    case AUDIO_SOURCE_MIC:
    if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {  //A2DP
        device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
    } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) && // If Bluetooth is forced   Priority Bluetooth headset 
        (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
        device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {// Wired Bluetooth 
        device = AUDIO_DEVICE_IN_WIRED_HEADSET;
    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {//usb
        device = AUDIO_DEVICE_IN_USB_DEVICE;
    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { // Mobile phone comes with mic
        device = AUDIO_DEVICE_IN_BUILTIN_MIC;
    }
    break;

    case AUDIO_SOURCE_VOICE_COMMUNICATION:
        // Allow only use of devices on primary input if in call and HAL does not support routing
        // to voice call path.
        if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
                (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
            availableDeviceTypes =
                    availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
                    & ~AUDIO_DEVICE_BIT_IN;
        }

        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
        case AUDIO_POLICY_FORCE_BT_SCO:
            // if SCO device is requested but no SCO device is available, fall back to default case
            if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
                device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
                break;
            }
            // FALL THROUGH

        default:    // FORCE_NONE
            if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                device = AUDIO_DEVICE_IN_WIRED_HEADSET;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
                device = AUDIO_DEVICE_IN_USB_DEVICE;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
            }
            break;

        case AUDIO_POLICY_FORCE_SPEAKER:
            if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
                device = AUDIO_DEVICE_IN_BACK_MIC;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
            }
            break;
        }
        break;

    case AUDIO_SOURCE_VOICE_RECOGNITION:
    case AUDIO_SOURCE_UNPROCESSED:
    case AUDIO_SOURCE_HOTWORD:
        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
                availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
            device = AUDIO_DEVICE_IN_USB_DEVICE;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
        }
        break;
    case AUDIO_SOURCE_CAMCORDER:
        if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
            device = AUDIO_DEVICE_IN_BACK_MIC;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
        }
        break;
    case AUDIO_SOURCE_VOICE_DOWNLINK:
    case AUDIO_SOURCE_VOICE_CALL:
        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
            device = AUDIO_DEVICE_IN_VOICE_CALL;
        }
        break;
    case AUDIO_SOURCE_REMOTE_SUBMIX:
        if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
        }
        break;
     case AUDIO_SOURCE_FM_TUNER:
        if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
            device = AUDIO_DEVICE_IN_FM_TUNER;
        }
        break;
    default:
        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
        break;
    }
    if (device == AUDIO_DEVICE_NONE) {
        ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
        if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
            device = AUDIO_DEVICE_IN_STUB;
        }
        ALOGE_IF(device == AUDIO_DEVICE_NONE,
                 "getDeviceForInputSource() no default device defined");
    }
    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
    return device;
} 


Android-MediaRecorder And setAudioSource

[Android Two ways to change the audio output / How to enter the equipment

=

原网站

版权声明
本文为[QXXXD]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071528182549.html