音频记录缓冲区大小
AudioRecord buffer size
我按如下方式初始化 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。是否正确?
谢谢。
I have to read shorts from the buffer because I specified ENCODING_PCM_16BIT
. Is it correct?
你应该,但你不一定必须。您可以将示例读入 byte[]
,但是在将 byte
转换为 short
时,由您来处理字节顺序。
If minimum buffer size in bytes is 1000 I'll have 500 shorts. So if I need 4096 samples I have to set bufferSizeInBytes to 8192. Is it correct?
实际上,没有。
最小缓冲区大小是 AudioRecord
实例可以接受的最小大小。这就像一个门槛。 AudioRecord
constructor documentation 说:
Using values smaller than getMinBufferSize() will result in an initialization failure.
在某些情况下,您可能希望使用比最小值更大的缓冲区大小。 AudioRecord.getMinBufferSize()
documentation` 说:
Note that this size doesn't guarantee a smooth recording under load, and higher values should be chosen according to the expected frequency at which the AudioRecord instance will be polled for new data.
下面是读取 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 实例:
// 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。是否正确?
谢谢。
I have to read shorts from the buffer because I specified
ENCODING_PCM_16BIT
. Is it correct?
你应该,但你不一定必须。您可以将示例读入 byte[]
,但是在将 byte
转换为 short
时,由您来处理字节顺序。
If minimum buffer size in bytes is 1000 I'll have 500 shorts. So if I need 4096 samples I have to set bufferSizeInBytes to 8192. Is it correct?
实际上,没有。
最小缓冲区大小是 AudioRecord
实例可以接受的最小大小。这就像一个门槛。 AudioRecord
constructor documentation 说:
Using values smaller than getMinBufferSize() will result in an initialization failure.
在某些情况下,您可能希望使用比最小值更大的缓冲区大小。 AudioRecord.getMinBufferSize()
documentation` 说:
Note that this size doesn't guarantee a smooth recording under load, and higher values should be chosen according to the expected frequency at which the AudioRecord instance will be polled for new data.
下面是读取 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();