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

79

我想修改Android操作系统(来自AOSP的官方镜像),以添加预处理到普通电话播放声音。

我已经通过修改HAL和audioflinger实现了对应用程序音频播放的过滤。

我只需要针对特定设备(Nexus 5X)进行目标设置。而且,我只需要过滤回放 - 我不关心录制(上行)。

更新#1:

为了清楚起见 - 我可以修改专门的高通驱动程序,或者运行在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

此外,我一直在查看hardware/qcom/audio/hal/voice.c中的voice_check_and_set_incall_rec_usecase函数。然而,我无法理解它(如何使它按照我想要的方式工作)。

更新#3:

我已经提出了一个更具体的问题,关于使用AudioSource.VOICE_DOWNLINK ,这可能会引起正确的注意,并最终帮助我解决这个问题。


我想做那件事。只是让它监视通话关键字,然后将声音注入到通话中。就像我说“高尔夫”,然后在通话中注入一个高尔夫鼓掌的声音。 - danny117
1
我在谈论创建自定义ROM,而不是普通应用程序。 - SirKnigget
这不是真的。有一个通话录音API,以及许多应用程序通过在许多设备上使用各种技巧找到了使用它的方法。 - SirKnigget
我编写了一个类似的应用程序。2年前发布了它。可以记录流,因此我认为过滤它很容易。但是,有些设备在无线电和编码芯片之间没有硬件连接。这是为了确保没有人黑进您的手机并记录您的通话。不知何故,中国便宜的模型总是有效。 - Namphibian
@SirKnigget 我们可以在聊天中讨论一些细节。请告诉我你什么时候有空。我非常愿意帮忙,而且我可能会开源代码。我看到你在胡志明市(我喜欢越南),而我在悉尼,所以我们相差3个小时。请告诉我。 - Namphibian
显示剩余9条评论
1个回答

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源代码)。 - SirKnigget
那么将内置耳机的源插入功能中也不能作为解决方法? - CoolKoon
1
不,这与根本问题无关。 - SirKnigget

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接