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

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

前言


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


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


因为这关系到音频焦点分配的问题。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 通话时如何播放声音给对方听

目录
相关文章
|
7天前
|
数据库 Android开发 数据安全/隐私保护
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
51 2
|
9天前
|
Android开发
Android中如何快速的实现RecycleView的拖动重排序功能
使用`ItemTouchHelper`和自定义`Callback`,在`RecyclerView`中实现拖动排序功能。定义`ItemTouchHelperAdapter`接口,`Adapter`实现它以处理`onItemMove`方法。`SimpleItemTouchHelperCallback`设置拖动标志,如`LEFT`或`RIGHT`(水平拖动),并绑定到`RecyclerView`以启用拖动。完成这些步骤后,即可实现拖放排序。关注公众号“AntDream”获取更多内容。
15 3
|
30天前
|
移动开发 监控 Android开发
构建高效Android应用:从内存优化到电池寿命代码之美:从功能实现到艺术创作
【5月更文挑战第28天】 在移动开发领域,特别是针对Android系统,性能优化始终是关键议题之一。本文深入探讨了如何通过细致的内存管理和电池使用策略,提升Android应用的运行效率和用户体验。文章不仅涵盖了现代Android设备上常见的内存泄漏问题,还提出了有效的解决方案,包括代码级优化和使用工具进行诊断。同时,文中也详细阐述了如何通过减少不必要的后台服务、合理管理设备唤醒锁以及优化网络调用等手段延长应用的电池续航时间。这些方法和技术旨在帮助开发者构建更加健壮、高效的Android应用程序。
|
9天前
|
存储 数据库 Android开发
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
13 0
|
1月前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
25 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能
|
1月前
|
机器学习/深度学习 人工智能 TensorFlow
安卓中的人工智能:集成机器学习功能
【4月更文挑战第14天】在数字化时代,人工智能与机器学习正驱动安卓平台的技术革新。谷歌的ML Kit和TensorFlow Lite为开发者提供了便捷的集成工具,使得应用能实现图像识别、文本转换等功能,提升用户体验。尽管面临数据隐私和安全性的挑战,但随着技术进步,更强大的AI功能将预示着移动端的未来,为开发者创造更多创新机遇。
|
1月前
|
Android开发
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
34 0
|
1月前
|
Java Android开发
Android Mediatek 应用层重置USB设备功能
Android Mediatek 应用层重置USB设备功能
20 0
|
1月前
|
Linux Android开发
Android 内核关闭CAN 串口设备回显功能
Android 内核关闭CAN 串口设备回显功能
20 0
|
1月前
|
XML Java Android开发
Android实现发送短信功能
Android实现发送短信功能
46 0