Android AudioRecord类-快速处理现场麦克风音频,设置回调功能

2019年4月8日 25点热度 0条评论

我想录制来自麦克风的音频,并访问它以便以近乎实时的方式播放。我不确定如何使用Android AudioRecord类录制一些麦克风音频并快速访问它。

对于AudioRecord类,官方网站说“应用程序会及时轮询AudioRecord对象”,并且“缓冲区的大小决定了在超出未读数据之前记录的时间长度”。稍后建议在较少轮询时应使用较大的缓冲区。他们从不实际在代码中显示示例。

我在书中看到的一个示例使用AudioRecord类连续读取新填充了现场麦克风音频的缓冲区,然后该应用将该数据写入SD文件。伪代码看起来像-

set up AudioRecord object with buffer size and recording format info
set up a file and an output stream
myAudioRecord.startRecording();
while(isRecording)
{
    // myBuffer is being filled with fresh audio
    read audio data into myBuffer
    send contents of myBuffer to SD file
}
myAudioRecord.stop();

该代码如何将其读数与记录速率进行同步尚不清楚- bool(boolean) “isRecording”是否在其他位置正确地打开和关闭?根据读取和写入所花费的时间,此代码似乎要么读取得太频繁,要么读取得太少。

站点文档还说AudioRecord类有一个名为OnRecordPositionUpdateListener的嵌套类,该类定义为接口(interface)。该信息建议您以某种方式指定要通知录制进度的时间段以及事件处理程序的名称,并以指定的频率自动调用事件处理程序。我认为伪代码的结构应该是这样的-

set target of period update message = myListener
set period to be about every 250 ms
other code

myListener()
{
    if(record button was recently tapped)
        handle message that another 250 ms of fresh audio is available
        ie, read it and send it somewhere
)

我需要找到一些特定的代码,使我能够以小于500毫秒的延迟捕获和处理麦克风音频。 Android提供了另一个称为MediaRecorder的类,但它不支持流传输,我可能希望通过Wi-Fi网络以近乎实时的方式流传输现场麦克风音频。在哪里可以找到一些具体示例?

解决方案如下:

在对通知和大量其他技术进行了大量试验之后,我决定编写以下代码:

private class AudioIn extends Thread { 
     private boolean stopped    = false;

     private AudioIn() { 

             start();
          }

     @Override
     public void run() { 
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
            AudioRecord recorder = null;
            short[][]   buffers  = new short[256][160];
            int         ix       = 0;

            try { // ... initialise

                  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);

                   recorder.startRecording();

                   // ... loop

                   while(!stopped) { 
                      short[] buffer = buffers[ix++ % buffers.length];

                      N = recorder.read(buffer,0,buffer.length);
                      //process is what you will do with the data...not defined here
                      process(buffer);
                  }
             } catch(Throwable x) { 
               Log.w(TAG,"Error reading voice audio",x);
             } finally { 
               close();
             }
         }

      private void close() { 
          stopped = true;
        }

    }

到目前为止,在我尝试过的六款Android手机上,它的运行情况都非常好。