存档,不想留本地了,没啥含量 都在Enginee.cpp里写着呢
1. 输出选择
整体流程
-
首先我们会获取当前存在的设备集合availableOutputDevices
-
然后根据传入的strategty类型进行匹配选择
-
在选择之前会先检测是否处于特殊情况下(如通话中)
-
最后按照优先级匹配设备。
关于音频设备选择的策略定义在AudioPolicyManager中的getDeviceForStrategy()方法,会根据当时设备的状态和连接设备选择最合适的设备,具体实现在frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp中。
以下注释解释很清楚,参数为strategy和fromCache,如果fromCache = true,则从mDeviceForStrategy[]选择,否则继续往下走。
mDeviceForStrategy[NUM_STRATEGIES] 是一个数组。
frameworks/av/services/audiopolicy/common/include/RoutingStrategy.henum 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中的具体实现
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
以下逻辑均涉及getDeviceForStrategy的调用
-
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); //仍旧调用getDeviceForStrategyif ((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);
}
具体实现在Engine.cpp中
frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream) {// stream to strategy mappingswitch (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 resultcase 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 针对STRATEGY_MEDIA分析,播放设备优先级如下
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES(普通蓝牙耳机)
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER(蓝牙小音箱) //此处属于setForceUse的强制插队 (if FORCE_SPEAKER)AUDIO_DEVICE_OUT_SPEAKER(扬声器)
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE(普通耳机,只能听,不能操控播放)
- AUDIO_DEVICE_OUT_LINE
- AUDIO_DEVICE_OUT_WIRED_HEADSET(线控耳机)
- AUDIO_DEVICE_OUT_USB_HEADSET(USB耳机)
case STRATEGY_MEDIA: {uint32_t device2 = AUDIO_DEVICE_NONE;if (isInCall() && (device == AUDIO_DEVICE_NONE)) { //针对通话// when in call, get the device for Phone strategydevice = getDeviceForStrategy(STRATEGY_PHONE);break;}if (strategy != STRATEGY_SONIFICATION) {//和提示做特别处理// 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; //A2DPif (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; //蓝牙耳机}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; //蓝牙音箱}}if ((device2 == AUDIO_DEVICE_NONE) &&(mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {//如果force speker 扬声器 喇叭device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; //普通有线耳机 不带麦克风}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;}if (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; //带麦克风的有线耳机}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设备 }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_ENABLEDif ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)&& (device2 == AUDIO_DEVICE_NONE)) {// no sonification on WFD sinkdevice2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_PROXY;}
#endifif (device2 == AUDIO_DEVICE_NONE) {device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; // 外放 扬声器 喇叭}int device3 = AUDIO_DEVICE_NONE;if (strategy == STRATEGY_MEDIA) {///如果arc,spdif,aux_line可用,赋值给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 otherwisedevice |= 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.输入选择
Audio Device Strategy 音频设备 输入选择 7.0
1.输入设备选择
1.1 MediaRecorder java层setAudioSource
以MediaRecorder为例,不考虑其他。setAudioSource设置输入源
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
frameworks/base/media/java/android/media/MediaRecorder.java
AudioSource共定义以下几种
/** Default audio source **/
public static final int DEFAULT = 0; //默认
/** Microphone audio source */
public static final int MIC = 1; //麦克
/** Voice call uplink (Tx) audio source */
public static final int VOICE_UPLINK = 2; //电话上行
/** Voice call downlink (Rx) audio source */
public static final int VOICE_DOWNLINK = 3; //电话下行
/** Voice call uplink + downlink audio source */
public static final int VOICE_CALL = 4; //电话录音
/** Microphone audio source with same orientation as camera if available, the main* device microphone otherwise */
public static final int CAMCORDER = 5; //摄像头麦克
public static final int VOICE_RECOGNITION = 6; //语音识别
public static final int VOICE_COMMUNICATION = 7;//网络电话
public static final int REMOTE_SUBMIX = 8; //用于内录
public static final int UNPROCESSED = 9; //未处理原始声音
@SystemApi
public static final int RADIO_TUNER = 1998; //广播
@SystemApi
public static final int HOTWORD = 1999;
继续看MediaRecorder
public native void setAudioSource(int audio_source)throws IllegalStateException;
通过JNI调用到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是谁
在看mMediaRecorder实例,是一个IMediaPlayerService 的service对象,调用了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
下面就是明显的binder操作,BnMediaPlayerService 定义了如下
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继承BnMediaPlayerService
frameworks/av/media/libmediaplayerservice/MediaPlayerService.h
class MediaPlayerService : public BnMediaPlayerService
这就通过binder来到了MediaRecorderClient,可知recorder对象就是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的setAudioSource
到这里可以继续看setAudioSource了
frameworks/av/media/libmediaplayerservice/MediaRecorderClient.cpp
status_t MediaRecorderClient::setAudioSource(int as) {return mRecorder->setAudioSource((audio_source_t)as);
}
MediaRecorderBase *mRecorder;
mRecorder为MediaRecorderBase实例,StagefrightRecorder继承于MediaRecorderBase,这里继续看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中会根据mAudioSource去创建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中有创建了AudioRecord
frameworks/av/media/libstagefright/AudioSource.cpp
mRecord = new AudioRecord(inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
以下代码在AudioRecord的构造方法中,inputsource是我们上边传入的参数。
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方法
set(){if (pAttributes == NULL) {mAttributes.source = inputSource;}
}
mAttributes应用在openRecord_l方法中,可以看到AudioSystem调用了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
重点关注aps,是IAudioPolicyService。点进去发现又是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 继承 BnAudioPolicyService,BnAudioPolicyService实现于 AudioPolicyInterface,AudioPolicyManager又继承AudioPolicyInterface。终于来到了AudioPolicyManager.cpp
1.4 AudioPolicyManager.cpp中的策略
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);
}
以下为具体策略
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) { //A2DPdevice = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;} else 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) {//usbdevice = AUDIO_DEVICE_IN_USB_DEVICE;} else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { //手机自带micdevice = 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 caseif (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;break;}// FALL THROUGHdefault: // FORCE_NONEif (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之setAudioSource
[Android两种改变音频输出/入设备的方式
=