web-dev-qa-db-ja.com

Android custom ROMで通話中の音声再生を変更する

Android OS(AOSPの公式画像)を変更して、通常の通話再生音に前処理を追加したいと思います。

アプリのオーディオ再生用にこのフィルタリングを既に達成しています([〜#〜] hal [〜#〜]およびaudioflinger)。

特定のデバイス(Nexus 5X)のみをターゲットに設定しても問題ありません。また、再生をフィルタリングするだけで済みます-録音(アップリンク)は気にしません。

更新#1:

明確にするために-Qualcomm固有のドライバー、またはNexus 5Xで実行され、通話中の再生を変更するのに役立つ部分を変更してもかまいません。

更新#2:

電話の再生をリアルタイムで音楽ストリームにルーティングするJavaレイヤーアプリを作成しようとしています。

システムアプリとしてのインストールに成功し、AudioRecordを_AudioSource.VOICE_DOWNLINK_で初期化する権限を取得しました。ただし、録音では空白のサンプルが提供されます。音声通話は録音されません。

これは、ワーカースレッド内のコードです。

_// 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:

より具体的な質問 _AudioSource.VOICE_DOWNLINK_の使用について開きました。これは正しい注意を引く可能性があり、最終的にはこの質問の問題の解決にも役立ちます。

75
SirKnigget

私の頭に浮かぶ可能性のある問題がいくつかあります。空白のバッファは、間違ったソースが選択されていることを示している場合があります。 https://developer.Android.com/reference/Android/media/AudioRecord.html#AudioRecord(int、%20int、%20int、%20int、%20int) に従っていないため構成に問題がある場合でも常に例外を受け取ります。オブジェクトが適切に初期化されているかどうかを確認することをお勧めします。他のすべてが失敗した場合、「mRecord.setPreferredDevice(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);」も実行できます。電話機の内蔵イヤホンをレコーダーの入力に直接ルーティングします。ええ、それはちょっと汚くてハッキーですが、おそらく目的に合っています。

もう1つ、私を困惑させたのは、ビルダークラスを使用する代わりに、コンストラクターを介してオブジェクトを直接構成しようとしたことです。 AudioRecord.Builderを使用したくない特定の理由があります( https://developer.Android.com/reference/Android/media/AudioRecord.Builder.html に素敵な例さえあります)= =)代わりに?

1
CoolKoon