リアルタイムで再生/プレビュー処理中にAndroidでマイク入力を記録する方法はありますか?AudioRecord
とAudioTrackを使用してこれを実行しようとしましたが、問題はデバイスが実際には、任意のAndroidプレーヤーアプリケーションは録音されたオーディオファイルを再生できません。
一方、Media.Recorderを使用して録音すると、適切な録音済みオーディオファイルが生成され、任意のプレーヤーアプリケーションで再生できます。しかし、問題は、マイク入力をリアルタイムで記録している間、プレビュー/ペイバックを作成できないことです。
(ほぼ)リアルタイムでオーディオを録音および再生するには、別のスレッドを開始し、AudioRecord
とAudioTrack
を使用します。
フィードバックには注意してください。お使いのデバイスでスピーカーの音量が十分に大きくなると、フィードバックは非常に不快になります。
/*
* Thread to manage live recording/playback of voice input from the device's microphone.
*/
private class Audio extends Thread
{
private boolean stopped = false;
/**
* Give the thread high priority so that it's not canceled unexpectedly, and start it
*/
private Audio()
{
Android.os.Process.setThreadPriority(Android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
start();
}
@Override
public void run()
{
Log.i("Audio", "Running Audio Thread");
AudioRecord recorder = null;
AudioTrack track = null;
short[][] buffers = new short[256][160];
int ix = 0;
/*
* Initialize buffer to hold continuously recorded audio data, start recording, and start
* playback.
*/
try
{
int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10);
track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM);
recorder.startRecording();
track.play();
/*
* Loops until something outside of this thread stops it.
* Reads the data from the recorder and writes it to the audio track for playback.
*/
while(!stopped)
{
Log.i("Map", "Writing new data to buffer");
short[] buffer = buffers[ix++ % buffers.length];
N = recorder.read(buffer,0,buffer.length);
track.write(buffer, 0, buffer.length);
}
}
catch(Throwable x)
{
Log.w("Audio", "Error reading voice audio", x);
}
/*
* Frees the thread's resources after the loop completes so that it can be run again
*/
finally
{
recorder.stop();
recorder.release();
track.stop();
track.release();
}
}
/**
* Called from outside of the thread in order to stop the recording/playback loop
*/
private void close()
{
stopped = true;
}
}
[〜#〜] edit [〜#〜]
オーディオは実際にはファイルに録音されていません。 AudioRecord
オブジェクトは、オーディオを 16ビットPCMデータ としてエンコードし、バッファーに配置します。次に、AudioTrack
オブジェクトがそのバッファーからデータを読み取り、スピーカーで再生します。 SDカードには、後でアクセスできるファイルはありません。
リアルタイムで再生/プレビューを取得するために、SDカードからファイルを同時に読み書きすることはできないため、バッファを使用する必要があります。
マニフェストで次の許可が適切に機能するために必要です。
<uses-permission Android:name="Android.permission.RECORD_AUDIO" ></uses-permission>
また、2Dバッファー配列は必要ありません。コードのロジックは、次のようにバッファが1つだけでも有効です。
short[] buffer = new short[160];
while (!stopped) {
//Log.i("Map", "Writing new data to buffer");
int n = recorder.read(buffer, 0, buffer.length);
track.write(buffer, 0, n);
}