ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android10.0(Q) 实现通话中播放音乐/通话背景音(答录机/魔音功能)

2021-02-16 18:58:26  阅读:1156  来源: 互联网

标签:答录机 Android10.0 driver 通话 speech common cpp audio define


前言

这个功能大体意思类似机器人交互的效果,一般多应用到客服接听场景中,电话接通自动播放一段录音给

对方听,根据选项操作录音解析等完成一整个流程。这里面电话接通播放声音给对方听普通应用是做不到的,

因为这关系到音频焦点分配的问题。Android 电话拨入音频焦点(Audio Focus)

谷歌默认的策略,当电话响铃或接通后,电话的音频焦点使用优先级是最高的,其它应用是无法抢占的。

但我们有源码啊,可以跳过这个地方,但是尝试后你会发现依旧不行。因为这还关系到 audio 驱动部分的上下行。

修改方案

frameworks/base/services/core/java/com/android/server/audio/MediaFocusControl.java
vendor/mediatek/proprietary/hardware/audio/common/speech_driver/SpeechPcmMixerBGSPlayer.cpp
vendor/mediatek/proprietary/hardware/audio/common/speech_driver/SpeechPcmMixerTelephonyTx.cpp
vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioALSAVolumeController.h
vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioMTKGainController.h

frameworks/base/services/core/java/com/android/server/audio/MediaFocusControl.java

canReassignAudioFocus 直接放回 true,其实最终发现改不改这里无所谓,主要是 audio 的上下行

     private boolean canReassignAudioFocus() {
         // focus requests are rejected during a phone call or when the phone is ringing
         // this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
        /*if (!mFocusStack.isEmpty() && isLockedFocusOwner(mFocusStack.peek())) {
             return false;
         }*/
        return true;
     }

audio driver 部分需要修改 mPcmMixerDlGain 和 mPcmMixerUlGain 默认初始值

其中 mPcmMixerDlGain 表示下行 gain 值,影响的是本端听到的声音大小

mPcmMixerUlGain 表示上行 gain 值,影响的是对方听到的声音大小,默认值是 0x00,

所以对方听不到,只要将 mPcmMixerUlGain 改为非 0 值即可,最大值 0xFF

vendor/mediatek/proprietary/hardware/audio/common/speech_driver/SpeechPcmMixerBGSPlayer.cpp

 uint8_t SpeechPcmMixerBGSPlayer::mPcmMixerDlGain = 0xFF;
-uint8_t SpeechPcmMixerBGSPlayer::mPcmMixerUlGain = 0x0;
+uint8_t SpeechPcmMixerBGSPlayer::mPcmMixerUlGain = 0xFF;



$ find -name "*.cpp" | xargs grep "setPcmMixerDlMute"
./common/speech_driver/SpeechPcmMixerBGSPlayer.cpp:uint8_t SpeechPcmMixerBGSPlayer::mPcmMixerDlGain = 0xFF;
./common/speech_driver/SpeechPcmMixerBGSPlayer.cpp:    pSpeechDriver->BGSoundConfig(mPcmMixerUlGain, mPcmMixerDlGain);
./common/speech_driver/SpeechPcmMixerBGSPlayer.cpp:        mPcmMixerDlGain = 0x0;
./common/speech_driver/SpeechPcmMixerBGSPlayer.cpp:        mPcmMixerDlGain = 0xFF;
./common/speech_driver/SpeechPcmMixerTelephonyTx.cpp:uint8_t SpeechPcmMixerTelephonyTx::mPcmMixerDlGain = 0x0;
./common/speech_driver/SpeechPcmMixerTelephonyTx.cpp:    pSpeechDriver->TelephonyTxConfig(mPcmMixerUlGain, mPcmMixerDlGain);
./common/speech_driver/SpeechPcmMixerTelephonyTx.cpp:        mPcmMixerDlGain = 0x0;
./common/speech_driver/SpeechPcmMixerTelephonyTx.cpp:        mPcmMixerDlGain = 0xFF;
$ find -name "*.cpp" | xargs grep "setPcmMixerDlMute("
./common/speech_driver/SpeechPcmMixerBGSPlayer.cpp:void SpeechPcmMixerBGSPlayer::setPcmMixerDlMute(const bool mute_on) {
./common/speech_driver/SpeechPcmMixerTelephonyTx.cpp:void SpeechPcmMixerTelephonyTx::setPcmMixerDlMute(const bool mute_on) {
./common/V3/aud_drv/AudioALSAHardware.cpp:        SpeechPcmMixerBGSPlayer::setPcmMixerDlMute((bool)value);

AndroidO 版本修改方法

frameworks/base/media/java/android/media/AudioAttributes.java
frameworks/base/services/core/java/com/android/server/audio/MediaFocusControl.java
vendor/mediatek/proprietary/hardware/audio/common/V3/aud_drv/AudioALSAStreamManager.cpp
vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioALSAVolumeController.h
vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioMTKGainController.h

frameworks/base/media/java/android/media/AudioAttributes.java

         public Builder setCapturePreset(int preset) {
             switch (preset) {
+            	case MediaRecorder.AudioSource.VOICE_UPLINK:
+            	case MediaRecorder.AudioSource.VOICE_DOWNLINK:
+            	case MediaRecorder.AudioSource.VOICE_CALL:
+            	case MediaRecorder.AudioSource.REMOTE_SUBMIX:
                 case MediaRecorder.AudioSource.DEFAULT:
                 case MediaRecorder.AudioSource.MIC:

frameworks/base/services/core/java/com/android/server/audio/MediaFocusControl.java

     private boolean canReassignAudioFocus() {
         // focus requests are rejected during a phone call or when the phone is ringing
         // this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
        /*if (!mFocusStack.isEmpty() && isLockedFocusOwner(mFocusStack.peek())) {
             return false;
         }*/
-        return true;
     }

vendor/mediatek/proprietary/hardware/audio/common/V3/aud_drv/AudioALSAStreamManager.cpp

AudioALSAStreamManager::AudioALSAStreamManager() :
     mForceDisableVoiceWakeUpForSetMode(false),
     mBypassPostProcessDL(false),
     mBGSDlGain(0xFF),
-    mBGSUlGain(0),
+    //mBGSUlGain(0),
+    mBGSUlGain(0xFF),
     mBypassDualMICProcessUL(false),

vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioALSAVolumeController.h

 #define HW_DIGITAL_GAIN_MAX (252)
 #define HW_DIGITAL_GAIN_STEP (4)   // 2==> 0.5 dB ,4==>1dB
 
-#define AUDIO_SYSTEM_UL_GAIN_MAX            (45)
+#define AUDIO_SYSTEM_UL_GAIN_MAX            (160)
 #define MIN_PGA_GAIN                                         (0)
 #define MAX_PGA_GAIN_RANGE                          (30)
 #define AUDIO_UL_PGA_STEP

vendor/mediatek/proprietary/hardware/audio/mt6735/include/AudioMTKGainController.h

 #define HW_DIGITAL_GAIN_MAX (252)
 #define HW_DIGITAL_GAIN_STEP (4)   // 2==> 0.5 dB ,4==>1dB
 
-#define AUDIO_SYSTEM_UL_GAIN_MAX            (45)
+#define AUDIO_SYSTEM_UL_GAIN_MAX            (160)
 #define MIN_PGA_GAIN                                         (2)
 #define MAX_PGA_GAIN_RANGE                          (30)
 #define AUDIO_UL_PGA_STEP  

其它问题收录

1、使用答录机的时候会听到连续的啪的声音

主要原因在于 AFE 不断去重新设置 uplink 的 AGC 那个寄存器。修正方法是当 mic volume

不变的时候不再重复设置 AGC 的那个寄存器。

Patch id: MAUI_02602310

2、答录机中进入远程访问之后,直接开始播放所有未读留言,此时用户输入 DTMF 无效

主要原因是函数 mmi_autoam_key_detection_callback 中没有把 MMI_AUTOAM_STATE_REMOTE_PRE_PLAY_UNREAD

这种 case 考虑进去,导致无法相对应的 DTMF 输入,修改方法是将这种 case 加进去

Patch id: MAUI_02029196

3、实现第三方的魔音功能的时候要修改 wav.c

添加第三方的魔音功能的时候,常常会要求开发 wav.c,因为要改到这里面的某些函数。出于策略,从 09A0924 之后,wav.c 等相关文件都被封装到 lib 中了,这部分将不会再重新开放出来。事实上,要实现魔音功能,其实不开放
wav.c 也是可以完成的,基本上只需要修改函数 wavADPCMPutData 和 wavDviADPCMPutDataMono,可以在 code
中对 ihdl->wav.Wav_PutData 进行赋值的地方进行相应的修改,赋值成自行修改之后的函数
wavADPCMPutData_modified 和 wavDviADPCMPutDataMono_modified 即可。

4、在通话中,播放背景音时,如何屏蔽掉按键音

如果是本地产生的按键音,可以利用 BGSND 的接口,把整个 speech 关闭。

修改 aud_snd_play_req 和 aud_snd_set_volume_req_hdlr:

SND_ConfigULMixer(snd_handle, KAL_TRUE, volume);

改为

SND_ConfigULMixer(snd_handle, KAL_FALSE, volume);

如果是因为按键产生 DTMF 发送到对方触发对方手机产生的声音,只能通过屏蔽本地产生 DTMF 处理。

方法是在通话时进入 option 选择其中的 DTMF 菜单并设成 off 或者直接在代码里设置

g_ucm_p->call_miss.is_dtmf=false 来实现。

5、来电时播放一段声音对对方听,自己这边不放出声来,同时本地的声音对方也听不见。然后在播放结束之后进入正常通话状态

修改文件 Am.c 中的函数 AM_SpeechOn()

在改函数内部加上判断条件,如果处于播放背景音的应用则不调用

AFE_TurnOnSpeaker(L1SP_SPEECH);

AFE_TurnOnMicrophone(L1SP_SPEECH);

在播放背景音的 callback 中调用函数

AFE_TurnOnSpeaker(L1SP_SPEECH);

AFE_TurnOnMicrophone(L1SP_SPEECH); 即可进入正常通话状态

参考

Android10.0AudioFocus之源码分析(二)

Android 电话拨入音频焦点(Audio Focus)

Android ALSA音频系统架构分析(1)----从Loopback了解Audio

Android 如何在通话中播放音乐/通话背景音

mt6735 Audio Common 通话时如何播放声音给对方听

标签:答录机,Android10.0,driver,通话,speech,common,cpp,audio,define
来源: https://blog.csdn.net/u012932409/article/details/113827212

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有