Android でリアルタイム ノイズ リダクション プログラムを構築しようとしてい
ます。 AudioRecord を使用して生の入力サウンド データを取得し、AudioTrack を使用してそれを再生します。
Audiorecordの初期化中に、コードを使用します
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
再生するときは、コードを使用します
track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
これらの設定は、Nexus 7 タブレット (電話ではない) ではうまく機能しますが、LG Optimus (または他の携帯電話) で実行しようとすると、ハードウェアの最大値でも出力音量が非常に低くなります。AudioManager.MODE_IN_COMMUNICATION を他の値に変更すると、出力がまったくない場合や、プログラムを初めて実行したときに出力が大きくなり、その後の実行で出力がない場合があります。この問題は、Nexus 7 では見られません (一部のオプションでは、Nexus 7 でもサウンド出力が発生しません)。
(生のオーディオ データに対して FFT を実行し、ノイズ リダクション アルゴリズム関数を実行して、FFT 後の各周波数成分のゲイン値を計算し、最終出力にこのゲイン値を掛けます。通常、これらのゲイン値が NaN の値になるためですが、それは別の問題です)。
Audiomanager
私が知りたいのは、 などで定義されているさまざまなタイプのオーディオ出力ソースAudioManager.MODE_IN_COMMUNICATION
と のオーディオ入力ソースの違いは何MediaRecorder.AudioSource
ですか? 一部のオプションがタブレットと電話で異なる動作を引き起こすのはなぜですか?
--- 編集 ---
最近、電話で、このプログラムを実行した後、電話の出力が小さく聞こえ、プログラムを終了した後、電話の通常の操作での音が残り続けると言われましたその小さなボリュームで。プログラムが終了したら、すべてのサウンド関連 (または電話のその他のリソース) を元の設定に戻すにはどうすればよいですか?
--- EDIT 2 ---
古い初期化コード:
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ORIGINAL AudioManager.MODE_IN_COMMUNICATION
--- EDIT 3 ---
現在の初期化スキーム
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // ADDED LATER: DELETE THIS LINE IF IT CAUSES PROBLEMS
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
--- 編集 4 ---
onResume() のコード
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
currentAudioManagerMode = am.getMode();
... // (function with initialization code from EDIT 3)
onPause() のコード
am.setMode(currentAudioManagerMode);