前言

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

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

因为这关系到音频焦点分配的问题。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(Q) 实现通话中播放音乐/通话背景音(答录机/魔音功能)相关推荐

  1. mt6735 [Audio Speech]如何在通话中播放音乐/通话背景音

    [DESCRIPTION] MT6735默认的架构下,通话过程中不能播放音乐,也没有实现通话背景音,如何实现? [SOLUTION] 1.修改AudioService.java,实现通话中播放音乐 p ...

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

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  3. Android 8.0 开机动画,RK3326 android10.0(Q) 开机logo+开关机动画替换

    RK3326 android10.0(Q) 开机logo+开关机动画替换 2020年08月14日 | 萬仟网移动技术 | 我要评论 开机logouboot和kernel阶段的logo分别为开机显示的第 ...

  4. Android中播放音乐的几种方式

    Android中播放音乐的几种方式 前言 前几天一直在研究RxJava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalye ...

  5. android10.0(Q) root QCOM-SM6125 user版本打开root权限

    推荐两个性能优化学习地址: Blog androidperformance MTK 6735/6739/6755/6763 android8.1 user版本打开root权限(adb root权限和 ...

  6. android10.0(Q) android11(R) 时区相关问题

    一.默认关闭自动更新时区 将自动更新时区开关 def_auto_time_zone 的值设置为 false. 文件路径:platform/frameworks/base/packages/Settin ...

  7. 华为1999元起的智能眼镜,能通话能播放音乐,预售就抢疯了!

    今年三月,华为正式发布与韩国时尚品牌GENTLE MONSTER联合打造的GENTLE MONSTER X HUAWEI Eyewear智能眼镜.这款智能眼镜8月21日,也就是昨日,已开启线上平台限量 ...

  8. 在c语言程序中播放音乐,在C语言控制台程序中播放MP3音乐

    游戏没有声音多单调. 这里做一个简单的范例,用 mciSendString 函数播放 MP3 格式的音乐,先看看代码吧:// 编译该范例前,请把 background.mp3 放在项目文件夹中 // ...

  9. android10.0(Q) root MTK 6765 user版本打开root权限(adb root权限和 apk root权限)

    前言 everybody,好久不见,我胡汉三又回来了,android10.0 root 安排!!! 相比较 Android8.1.9.0 而言,Q 版本 的 root变得相当麻烦,10.0 中引入了动 ...

最新文章

  1. python实现简单的http服务器_Python实现简单HTTP服务器(二)
  2. 慢动作频闪怎么解决_Vlog的视频解决方案——索尼A6400
  3. Runtime's DiskExplorer手工填写分区表
  4. Cordova实战培训
  5. oracle查数据存入数组,如何在SQL查询中使用Oracle关联数组
  6. WebSocket实现实时通信
  7. java切片_ java中一个极其强悍的新特性Stream详解(非常实用)
  8. 批量修改栏目名_Endnote中英文混排批量修改小技巧
  9. 【zookeeper系列】centos7安装zookeeper
  10. 启动时不自动打开一个空文档
  11. 三人表决器程序c语言,“三人表决器”逻辑功能PLC程序设计(有梯形图 指令表)...
  12. esxi6.5虚拟机迁移
  13. c# - - - 使用Chloe框架连接PostgreSQL数据库
  14. 华为云迁移工具推荐最佳实践:物理服务器迁移到华为云
  15. 球定位实景导航 iOS实用应用周排行
  16. S5P4418 Android实时时钟框架介绍
  17. 手机翻书效果html,移动端实现翻书效果
  18. “指尖上的中华”非遗国技互动展亮相上海徐家汇站
  19. 完美世界手游服务器维护时间表,完美世界手游开服时间表 新区开服时间总览[多图]...
  20. 亚马逊、Lazada、shopee、eBay、wish、速卖通、沃尔玛、独立站、美客多、敦煌、阿里国际、mercari、newegg、Tiktok测评(补单)如何规避风控?应该选择哪些站点?

热门文章

  1. 用python画一个简单卡通人物_Python绘制可爱的卡通人物 | 【turtle使用】-Go语言中文社区...
  2. Java设计模式--外观模式
  3. FD镜像文件生成过程分析
  4. CVPR2020 Oral | 动态多尺度图表达3D人体骨架运动,实现精准预测效果超SOTA
  5. Attribute 'items' must be an array, a Collection or a Map错误解决!
  6. 百家号大鱼号头条号企鹅号的自媒体视频从哪里来?
  7. 牛客简单模拟 奇怪的计算器
  8. 写好一篇论文的几个“五项原则”
  9. 用java编写在界面中画圆_用java语言编写画随机的圆 十万火急 求大神帮忙!!!...
  10. mysql中毒_2020-10-15 MYSQL中勒索病毒解密 .help 病毒解密恢复 数据库中.help 解密恢复 服务器被加密解密恢复...