在 Android 自定义 ROM 中修改通话中的语音播放

Posted

技术标签:

【中文标题】在 Android 自定义 ROM 中修改通话中的语音播放【英文标题】:Modifying in-call voice playback in Android custom ROM 【发布时间】:2017-07-04 05:24:30 【问题描述】:

我想修改 android 操作系统(来自 AOSP 的官方图片),为正常的电话播放声音添加预处理。

我已经为应用音频播放实现了这种过滤(通过修改 HALaudioflinger)。

我可以只定位特定设备 (Nexus 5X)。另外,我只需要过滤播放 - 我不关心录制(上行)。

更新 #1:

说清楚 - 我可以修改 Qualcomm 特定的驱动程序,或者任何在 Nexus 5X 上运行的部分,并且可以帮助我修改通话中的播放。

更新 #2:

我正在尝试创建一个 Java 层应用程序,将手机播放实时路由到音乐流。

我已经成功地将它安装为系统应用程序,获得了使用Audiosource.VOICE_DOWNLINK 初始化AudioRecord 的权限。然而,录音给出了空白样本;它不会记录语音通话。

这是我的工作线程中的代码:

// Start recording
int recBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
mRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_DOWNLINK, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, recBufferSize);

// Start playback
int playBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, playBufferSize, AudioTrack.MODE_STREAM);

mRecord.startRecording();;
mTrack.play();

int bufSize = 1024;
short[] buffer = new short[bufSize];
int res;
while (!interrupted())

    // Pull recording buffers and play back
    res = mRecord.read(buffer, 0, bufSize, AudioRecord.READ_NON_BLOCKING);
    mTrack.write(buffer, 0, res, AudioTrack.WRITE_BLOCKING);


// Stop recording
mRecord.stop();
mRecord.release();
mRecord = null;

// Stop playback
mTrack.stop();
mTrack.release();;
mTrack = null;

我在 Nexus 5X、我自己的 AOSP 自定义 ROM、Android 7.1.1 上运行。我需要找到允许通话录音工作的地方——可能在平台代码中hardware/qcom/audio/hal 的某个地方。

我也一直在查看函数 voice_check_and_set_incall_rec_usecase hardware/qcom/audio/hal/voice.c 但是,我无法理解它(如何让它按照我想要的方式工作)。

更新 #3:

我已经打开了a more-specific question 关于使用AudioSource.VOICE_DOWNLINK,这可能会引起正确的注意,最终也将帮助我解决这个问题。

【问题讨论】:

我想这样做。只是让它监控关键字的调用,然后在调用中注入声音。就像我说“高尔夫”,然后在通话中注入了高尔夫拍手声。 我怀疑是否可以在不使用 ndk-jni 的情况下修改标准 i/o 我说的是创建自定义 ROM,而不是普通的应用程序。 IIRC,电话被视为敏感信息,开放软件无法访问它。您将不得不破解被称为“收音机”的闭源固件。可能不可行。 这不是真的。有一个通话录音 API,大量的应用通过各种黑客手段在许多设备上找到了使用它的方法。 【参考方案1】:

我想到了几个可能的问题。空白缓冲区可能表明您选择了错误的源。此外,根据https://developer.android.com/reference/android/media/AudioRecord.html#AudioRecord(int,%20int,%20int,%20int,%20int),即使配置有问题,您也可能不会总是遇到异常,您可能需要确认您的对象是否已正确初始化。如果一切都失败了,你也可以做一个 “mRecord.setPreferredDevice(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);” 将手机的内置听筒直接连接到录音机的输入端。是的,它有点肮脏和hacky,但也许适合目的。

令我困惑的另一件事是,您尝试直接通过其构造函数配置对象,而不是使用构建器类。是否有您不想使用 AudioRecord.Builder 的具体原因(https://developer.android.com/reference/android/media/AudioRecord.Builder.html 甚至有一个很好的例子)?

【讨论】:

你提出的所有点都被检查过了,这个不相关。 Builder 类确实是最新的,但在内部它完全一样(检查 Android 源代码)。 那么插入内置听筒的源的功能也不是一种解决方法? 没有。它与根本问题无关。

以上是关于在 Android 自定义 ROM 中修改通话中的语音播放的主要内容,如果未能解决你的问题,请参考以下文章

Android技术分享| Android 自定义View多人视频通话控件

带有自定义语音 mp3 文件的 Android 通话

用声网 Android UIKit 为实时视频通话应用添加自定义背景丨声网 SDK 教程

安卓4.1怎么调通话音量

手机通话声音小,怎么解决,用了很多软件,不行。

自定义加密 GSM 通话