【问题标题】:AudioRecord buffer size音频记录缓冲区大小
【发布时间】:2017-07-10 23:52:18
【问题描述】:

我按如下方式初始化我的 AudioRecord 实例:

// TODO: remember to add RECORD_AUDIO permission
int audioSource = MediaRecorder.AudioSource.MIC;

// TODO: I should consider Nyquist frequency and tell the user if her device can correctly detect frequencies in the range of her instrument
int sampleRateInHz = getDeviceSampleRate(context);

int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

// TODO: bufferSizeInBytes should be set according to minimum detectable frequency in order to have at least three periods
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);

AudioRecord audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);

这是我的问题:

  • 我必须从缓冲区中读取短裤,因为我指定了ENCODING_PCM_16BIT。对吗?
  • 如果以字节为单位的最小缓冲区大小为 1000,我将有 500 个短裤。所以如果我需要 4096 个样本,我必须将 bufferSizeInBytes 设置为 8192。是否正确?

谢谢。

【问题讨论】:

    标签: android audiorecord


    【解决方案1】:

    我必须从缓冲区中读取短裤,因为我指定了ENCODING_PCM_16BIT。对吗?

    您应该这样做,但不一定必须这样做。您可以将样本读入byte[],但在将bytes 转换为shorts 时,由您来处理字节顺序。

    如果以字节为单位的最小缓冲区大小为 1000,我将有 500 个短裤。所以如果我需要 4096 个样本,我必须将 bufferSizeInBytes 设置为 8192。是否正确?

    其实没有。

    最小缓冲区大小是AudioRecord 实例将接受的最小大小。这就像一个门槛。 AudioRecord constructor documentation 说:

    使用小于 getMinBufferSize() 的值将导致初始化失败。

    在某些情况下,您可能希望使用大于最小值的缓冲区大小。 AudioRecord.getMinBufferSize() documentation` 说:

    请注意,此大小并不能保证在负载下顺利录制,应根据 AudioRecord 实例轮询新数据的预期频率选择更高的值。

    这是一个读取 4096 个 16 位样本的算法:

    ByteArrayOutputStream mainBuffer = new ByteArrayOutputStream();
    
    int minimumBufferSize = AudioRecord.getMinBufferSize(...);
    
    byte[] readBuffer = new byte[minimumBufferSize];
    
    AudioRecord recorder = new AudioRecord(..., minimumBufferSize);
    
    recorder.startRecording();
    
    while (mainBuffer.size() < 8192) {
    
        // read() is a blocking call
        int bytesRead = recorder.read(readBuffer, 0, minimumBufferSize);
    
        mainBuffer.write(readBuffer, 0, bytesRead);
    }
    
    recorder.stop();
    
    recorder.release();
    

    【讨论】:

    • 感谢您的回复。 “应该从音频硬件中读取小于总记录缓冲区大小的数据块。” (AudioRecord)。因此,如果我需要分析 4096 个样本并且我知道我要阅读短片,我必须使用 8192 个单位的 bufferSizeInBytes 初始化我的 AudioRecord 实例。对吗?
    • 为什么我必须实现你发布的算法?如果我调用AudioRecord#read,操作将阻塞,直到读取所有样本。对吗?
    • @AdrianoDiGiovanni 我认为 8192 对于bufferSizeInBytes 来说太大了。我会创建一个 AudioRecordgetMinBufferSize() 或它的几个倍数
    • 为什么太大了?我不关心延迟和响应:它是一个吉他调音器,录音/分析是在后台任务中执行的。还有其他标准吗?
    • @AdrianoDiGiovanni 当然,算法不是强制性的。是的,read() 是一个阻塞调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 2021-08-16
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    相关资源
    最近更新 更多