AudioRecord和AudioTrack延迟

我试图开发一个应用程序,如android的iRig,所以第一步是捕捉麦克风input,并在同一时间播放它。

我有它,但问题是,我得到一些延迟,使这种无法使用,如果我开始处理缓冲区,我怕它会得到完全无法使用。

我使用这样的audiorecordaudiotrack:

new Thread(new Runnable() { public void run() { while(mRunning){ mRecorder.read(mBuffer, 0, mBufferSize); //Todo: Apply filters here into the buffer and then play it modified mPlayer.write(mBuffer, 0, mBufferSize); //Log.v("MY AMP","ARA"); } 

而通过这种方式:

 // ==================== INITIALIZE ========================= // public void initialize(){ mBufferSize = AudioRecord.getMinBufferSize(mHz, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); mBufferSize2 = AudioTrack.getMinBufferSize(mHz, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); mBuffer = new byte[mBufferSize]; Log.v("MY AMP","Buffer size:" + mBufferSize); mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, mHz, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, mBufferSize); mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, mHz, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, mBufferSize2, AudioTrack.MODE_STREAM); } 

你知道如何获得更快的反应? 谢谢!

Solutions Collecting From Web of "AudioRecord和AudioTrack延迟"

由于最小的缓冲区大小,Android的AudioTrack \ AudioRecord类具有较高的延迟。 这些缓冲区大小的原因是根据谷歌GC(这是一个错误的决定,在我看来,你可以优化自己的内存pipe理)时发生GC降低最小化。

你想要做的是使用OpenSL,它可以从2.3获得。 它包含stream式audio的本机API。 这里有一些文档: http : //mobilepearls.com/labs/native-android-api/opensles/index.html

只是一个想法,但不应该阅读<mBufferSize

我的第一个build议是build议将AudioTrack设置为静态模式而不是stream模式,因为静态模式具有明显较小的延迟。 但是,静态模式更适合于完全适合内存的短音,而不是从其他地方捕捉的声音。 但正如疯狂猜测,如果您将AudioTrack设置为静态模式,并将其inputaudio的离散块?

如果你想对audio进行更严格的控制,我build议看一看Android的OpenSL ES 。 学习曲线会变得更陡峭,但是您可以获得更细致的控制和更低的延迟。

正如mSparks指出的那样,stream式传输应该使用较小的读取大小:您不需要读取完整的缓冲区来传输数据!

 int read = mRecorder.read(mBuffer, 0, 256); /* Or any other magic number */ if (read>0) { mPlayer.write(mBuffer, 0, read); } 

这将大大降低您的延迟。 如果mHz是44100,而你的MONOconfiguration是256,你的延时不会小于那么1000 * 256/44100毫秒=〜5.8毫秒。 256/44100是从采样到秒的转换,所以乘以1000会得到毫秒。 问题在于玩家的内部实现。 你没有从java的控制。 希望这可以帮助别人:)