Android の OpenSL ES 実装を使用したリアルタイム通信アプリケーション (SIP ライク、Skype ライクなど) を作成しようとしています。
問題は、通信を介して WAV オーディオ ファイルを再生する必要があることです (Java の MediaPlayer でこれを行っています)。
もちろん、OpenSL ES が実行されていない場合、mediaplayer は問題なく動作します。しかし、そうなると、すべての地獄が解き放たれます.結果はデバイス間で非常に一貫性がありません.
- Nexus 7 (4.2.2) の場合: wav は正常に再生されます
- Nexus 4 (4.2.2) および Galaxy S3 (4.1.2) の場合: wav は非常に低く再生されます (音量を最大に設定しても)
- Galaxy S4 (4.2.2) の場合: wav は非常に大きく飽和して再生されます (音量を最小に設定しても)
その問題を示すサンプル プロジェクトを作成しました。エンジンを始動する前にサウンド (ピーエット ボタン) を再生すると、動作します。後で再生する場合は、デバイスによって異なります。
ここに私の観察があります:
- OpenSL ES では、プレーヤーまたはレコーダーのみが機能する場合、すべてが期待どおりに機能します。バグを発生させるのは、プレーヤーとレコーダーの組み合わせです (MainActivity.java で、StartPlayer() [l.47] または StartRecorder() [l.48] をコメントするだけで確認できます)。
- プレーヤーのエンキュー (Audio.cpp で、コメント (*playerBufferQueue)->エンキュー [l.78-80]) を無効にすると、すべてが期待どおりに機能します。
- 音声ストリームで再生するように OpenSL ES を設定しない場合 (Audio.cpp で、コメント (*playerConfig)->SetConfiguration [l.146-187])、すべてが期待どおりに機能します。
もちろん、私が必要とするので、上記のものは解決策ではありません...
- OpenSL ES からの音声通信としての録音
- 音声ストリームで OpenSL ES から再生
- メディア ストリームの MediaPlayer から再生する
...すべて同時に。
最後に、Galaxy S4 では、ネットワークから受信したフレームをキューに入れると、OpenSL ES がそれを大音量で飽和させて再生するため、アプリケーションが使用できないことを指摘しておく必要があります。したがって、問題は MediaPlayer Java 側にあるとは思いません。