Android支持多个应用同时录音

Android支持多个应用同时录音

Android 7.x和Android 8.1版本修改

共两个修改点:
(1) 修改函数:audio_io_handle_t AudioPolicyManager::getInputForDevice()
需要在mpClientInterface->openInput前添加如下代码:

#ifdef ANDROIDN_SUPPORT_MULIT_CHANNEL_RECORDING
	for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
		sp<AudioInputDescriptor> desc;
		desc = mInputs.valueAt(input_index);
	    if (desc->mProfile == profile) {
			audioSession->changeActiveCount(1); 
			desc->addAudioSession(session, audioSession);
			return desc->mIoHandle;
		} 
	}
#endif

(2)修改函数:status_t AudioPolicyManager::startInput()
注释掉以下代码段

#ifndef ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
    // virtual input devices are compatible with other input devices
    if (!is_virtual_input_device(inputDesc->mDevice)) {

        // for a non-virtual input device, check if there is another (non-virtual) active input
        audio_io_handle_t activeInput = mInputs.getActiveInput();
        if (activeInput != 0 && activeInput != input) {

            // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
            // otherwise the active input continues and the new input cannot be started.
            sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
            if ((activeDesc->inputSource() == AUDIO_SOURCE_HOTWORD) &&
                    !activeDesc->hasPreemptedSession(session)) {
                ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
                //FIXME: consider all active sessions
                AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
                audio_session_t activeSession = activeSessions.keyAt(0);
                SortedVector<audio_session_t> sessions =
                                           activeDesc->getPreemptedSessions();
                sessions.add(activeSession);
                inputDesc->setPreemptedSessions(sessions);
                stopInput(activeInput, activeSession);
                releaseInput(activeInput, activeSession);
            } else {
                ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
                return INVALID_OPERATION;
            }
        }

        // Do not allow capture if an active voice call is using a software patch and
        // the call TX source device is on the same HW module.
        // FIXME: would be better to refine to only inputs whose profile connects to the
        // call TX device but this information is not in the audio patch
        if (mCallTxPatch != 0 &&
            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
            return INVALID_OPERATION;
        }
    }
#endif

补丁如下:

Date:   Thu Oct 27 13:41:11 2022 +0800

    add support multi audio recorder.

diff --git a/android/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/android/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 00fd05a6c1..dcc521712a 100755
--- a/android/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/android/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -24,6 +24,7 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
+#define ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
 #define AUDIO_POLICY_XML_CONFIG_FILE "/system/etc/audio_policy_configuration.xml"
 
 #include <inttypes.h>
@@ -1518,12 +1519,12 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
                                                               policyMix, mpClientInterface);
 // TODO enable input reuse
+#ifdef ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
+	// Modify YMF 20221027: check wether have an AudioInputDescriptor Use the same profile
+	for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
+		sp<AudioInputDescriptor> desc = mInputs.valueAt(input_index);
+		if (desc->mProfile == profile) {
+			audioSession->changeActiveCount(1);    // reference count add
+			desc->addAudioSession(session, audioSession);
+			return desc->mIoHandle;
+		}
+	}
+#endif
 
@@ -1603,6 +1613,9 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
         return BAD_VALUE;
     }
 
+    // TODO enable input reuse
+    // Modify YMF 20221027
+#ifndef ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
     // virtual input devices are compatible with other input devices
     if (!is_virtual_input_device(inputDesc->mDevice)) {
 
@@ -1640,7 +1653,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
             return INVALID_OPERATION;
         }
     }
-
+#endif
     // Routing?
     mInputRoutes.incRouteActivity(session);

补丁优化(修复百度语音识别可以出现崩溃的情况)

共两个修改点:
(1) 修改函数:audio_io_handle_t AudioPolicyManager::getInputForDevice()
需要在mpClientInterface->openInput前添加如下代码:
// TODO enable input reuse
#ifdef ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
    // reuse an open input if possible
    for (size_t i = 0; i < mInputs.size(); i++) {
        sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
        // reuse input if it shares the same profile and same sound trigger attribute
        if (profile == desc->mProfile &&
            isSoundTrigger == desc->isSoundTrigger()) {
            sp<AudioSession> as = desc->getAudioSession(session);
            if (as != 0) {
                // do not allow unmatching properties on same session
                if (as->matches(audioSession)) {
                    as->changeOpenCount(1);
                } else {
                    ALOGW("getInputForDevice() record with different attributes"
                          " exists for session %d", session);
                    return input;
                }
            } else {
                desc->addAudioSession(session, audioSession);
            }
            ALOGV("getInputForDevice() reusing input %d", mInputs.keyAt(i));
            return mInputs.keyAt(i);
        }
    }
#endif

(2)修改函数:status_t AudioPolicyManager::startInput()

    // TODO enable input reuse
    // Modify YMF 20221027
    // virtual input devices are compatible with other input devices
    if (!is_virtual_input_device(inputDesc->mDevice)) {

        // for a non-virtual input device, check if there is another (non-virtual) active input
        audio_io_handle_t activeInput = mInputs.getActiveInput();
        if (activeInput != 0 && activeInput != input) {

            // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
            // otherwise the active input continues and the new input cannot be started.
            sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
#ifndef ANDROIDN_SUPPORT_MULTI_CHANNEL_RECORDING
            if ((activeDesc->inputSource() == AUDIO_SOURCE_HOTWORD) &&
                    !activeDesc->hasPreemptedSession(session)) {
                ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
                //FIXME: consider all active sessions
                AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
                audio_session_t activeSession = activeSessions.keyAt(0);
                SortedVector<audio_session_t> sessions =
                                           activeDesc->getPreemptedSessions();
                sessions.add(activeSession);
                inputDesc->setPreemptedSessions(sessions);
                stopInput(activeInput, activeSession);
                releaseInput(activeInput, activeSession);
            } else {
                ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
                return INVALID_OPERATION;
            }
#else
            ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
            //FIXME: consider all active sessions
    	    AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
    	    audio_session_t activeSession = activeSessions.keyAt(0);
    	    SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
    	    sessions.add(activeSession);
    	    inputDesc->setPreemptedSessions(sessions);
    	    stopInput(activeInput, activeSession);
    	    releaseInput(activeInput, activeSession);
#endif
        }

        // Do not allow capture if an active voice call is using a software patch and
        // the call TX source device is on the same HW module.
        // FIXME: would be better to refine to only inputs whose profile connects to the
        // call TX device but this information is not in the audio patch
        if (mCallTxPatch != 0 &&
            inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
            return INVALID_OPERATION;
        }
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值