问题描述
我正在尝试通过蓝牙设备录制音频流。我正在使用蓝牙 SCO 来获取蓝牙音频和 AudioRecord 类来录制音频。 我正在使用采样率为 16000
的.PCM
通道录制 RAW MONO
文件
我正在像这样计算 BufferSize
private static final int BUFFER_SIZE_FACTOR = 2;
private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE_IN_HZ,CHANNEL_CONFIG,AUDIO_FORMAT) * BUFFER_SIZE_FACTOR;
这就是我目前获取/编写音频的方式,
private class RecordingRunnable implements Runnable {
@Override
public void run() {
setFileNameAndPath();
final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
try (final FileOutputStream outStream = new FileOutputStream(mFilePath)) {
while (recordingInProgress.get()) {
int result = recorder.read(buffer,BUFFER_SIZE);
if (result < 0) {
throw new RuntimeException("Reading of audio buffer failed: " +
getBufferReadFailureReason(result));
}
outStream.write(buffer.array(),BUFFER_SIZE);
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Writing of recorded audio failed",e);
}
}
我做了一点研究,发现裁剪效果可能是由于错误的字节顺序 (LITTLE_ENDIAN or BIG_ENDIAN)
或由于多线程不佳。但是,在当前的实现中,我无法理解字节是如何排序和保存的,以及如何解决剪切/噪声问题。
我正在启动我的录音机,可以像这样运行
recordingThread = new Thread(new RecordingRunnable(),"Recording Thread");
recordingThread.start();
recordingThread.setPriority(Thread.MAX_PRIORITY);
解决方法
我遇到了同样的问题,我用下面的代码解决了这个问题。
private byte[] short2byte(short[] sData,int size) {
int shortArrsize = size;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
......
int bufferSize = AudioRecord.getMinBufferSize(48000,AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT);
short[] buffer = new short[bufferSize];
int source = MediaRecorder.AudioSource.VOICE_RECOGNITION;
mAudioRecorder = new AudioRecord(source,48000,AudioFormat.ENCODING_PCM_16BIT,bufferSize);
int state = mAudioRecorder.getState();
if (state != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG,"Can not support");
return;
}
mAudioRecorder.startRecording();
while (mIsRecording) {
int bufferReadResult = mAudioRecorder.read(buffer,bufferSize);
if (bufferReadResult < 0) {
continue;
}
try {
byte data[] = short2byte(buffer,bufferReadResult);
fos.write(data,bufferReadResult * 2);
} catch (IOException e) {
e.printStackTrace();
}
}