AudioRecord在启动后返回一些空数据

时间:2017-08-20 20:44:11

标签: android buffer audiorecord

我写了一个标准代码,用于通过AudioRecord从麦克风接收数据。这是我的代码:

AudioReceiver() {
    int minHardwareBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
            CHANNEL_CONFIG, AUDIO_FORMAT);
    Log.d(TAG, "minHardwareBufferSize = " + minHardwareBufferSize);
    int bufferSizeBytes = (minHardwareBufferSize > MIN_BUFFER_SIZE_BYTES) ?
            minHardwareBufferSize : MIN_BUFFER_SIZE_BYTES;
    bufferSizeShorts = bufferSizeBytes / 2;

    //резервируем буфер с запасом в 2 раза
    audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSizeBytes * 2);

    testStack = new short[bufferSizeShorts * 4];
    Arrays.fill(testStack, (short) 2000);
}


boolean startReceive() {
    audioRecorder.startRecording();
    isReceiving = true;
    int recordingState = audioRecorder.getRecordingState();
    Log.d(TAG, "recordingState = " + recordingState);
    new Thread(receivingRunnable).start();
    return (recordingState == AudioRecord.RECORDSTATE_RECORDING);
}


boolean stopReceive() {
    isReceiving = false;
    audioRecorder.stop();
    int recordingState = audioRecorder.getRecordingState();
    Log.d(TAG, "recordingState = " + recordingState);
    return (recordingState == AudioRecord.RECORDSTATE_STOPPED);
}


private Runnable receivingRunnable = new Runnable() {
    @Override
    public void run() {
        int readCount = 0;
        short[] dataBuffer = new short[bufferSizeShorts];
        while (isReceiving) {
            testBusy = true;
            for (int j = 0; j < 4; j++) {
                readCount = audioRecorder.read(dataBuffer, 0, dataBuffer.length);
                Log.d(TAG, "receive " + readCount + " bytes");
                System.arraycopy(dataBuffer, 0, testStack, bufferSizeShorts * j, readCount);
            }
            isReceiving = false;
            testBusy = false;
        }
    }
};

但是我注意到在startReceive函数第一次启动后,在testStack缓冲区的开头,有空数据(Nexus 4上大约1000个样本,见数据图)。

Data graph

在AudioReceiver的初始化和startReceive的启动之间需要很长时间。可能是问题的原因是什么?

1 个答案:

答案 0 :(得分:1)

当OS需要时间重新采样数据时,似乎会导致延迟,并且很难为所有设备提供一个采样率。 other posts也提到了。所以,我改为将音频记录逻辑移动到活动onCreate。当我不需要音频或暂停时,我只是扔掉了数据。

我总是在录音时没有观察到电池严重耗尽。虽然这可能不是解决此问题的最佳方法,但这绝对是我可接受的解决方法。