您的位置:首页 > 移动开发 > Android开发

Android AudioRecord PCM数据解析

2018-08-26 22:46 387 查看
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u011387593/article/details/82085443

最近上手开发APP,在使用录音接口(AudioRecord)发现使用AudioRecord.read直接在dump出来的缓冲区数据保存为文本后,并不能在Matlab上正确播放声音,发现audiodata的格式受到音频数据格式(AudioFormat)影响。

缓冲区的基本单元是byte,当设置音频数据格式为ENCODING_PCM_8BIT(8位,单声道)时,刚好一个byte能够容纳一个采样点,这样的dump不存在问题;当设置音频数据格式为ENCODING_PCM_16BIT(16位,单声道)时,一个采样点需要2byte才够;当设置音频数据格式为ENCODING_PCM_16BIT(16位,双声道)时,一个采样点需要4byte才够,具体编码方法如下图:

在我的实验中用到了16位单声道,配置如下:

[code]    private int audioSource = MediaRecorder.AudioSource.MIC;
// 设置音频采样率,44100是目前的标准,某些设备仍然支持22050,16000,11025
private static int sampleRateInHz = 16000;
// 设置音频的录制的声道CHANNEL_IN_MONO为单声道
private static int channelConfig = AudioFormat.CHANNEL_IN_MONO;
// 音频数据格式:PCM 16位每个样本。保证设备支持。
private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

写入方法如下:

[code]    /**
* 将数据写入文件。
*/
private void writeDateTOFile(String AudioName) {
// new一个byte数组用来存一些字节数据,大小为缓冲区大小
String mFileName = "/sdcard/Android/data/com.example.gosleep/cache/audio.raw";
byte[] audiodata = new byte[bufferSizeInBytes];
FileOutputStream fos = null;
FileOutputStream fos1 = null;
OutputStreamWriter writer = null;
int readsize = 0;
int audiodata_len = 0;
byte bytes[] = new byte[2];
try {
File file = new File(AudioName);
if (file.exists()) {
file.delete();
}
fos = new FileOutputStream(file);// 建立一个可存取字节的文件

File file1 = new File(mFileName);
fos1 = new FileOutputStream(file1);
writer = new OutputStreamWriter(fos1, "utf-8");

} catch (Exception e) {
e.printStackTrace();
}
while (isRecord == true) {
readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {
try {
audiodata_len = audiodata.length;
for (int i = 0; i < audiodata_len; i += 2) {
bytes[0] = audiodata[i];
bytes[1] = audiodata[i + 1];
writer.write(byte4ToShortInt(bytes, 0) + ",");
}
fos.write(audiodata);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
writer.close();
fos1.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();// 关闭写入流
} catch (IOException e) {
e.printStackTrace();
}
}

byte数组转短整数方法如下:

[code]    /**
* byte数组转换为short int整数
*
* @param bytes byte数组
* @param off   开始位置
* @return int整数
*/
private short byte4ToShortInt(byte[] bytes, int off) {
short s = 0;
short b0 = (short) (bytes[off] & 0xff);
short b1 = (short) (bytes[off + 1] & 0xff);
b1 <<= 8;
s = (short) (b0 | b1);
return s;
}

参考博客:

1、https://www.geek-share.com/detail/2699949308.html

2、https://www.geek-share.com/detail/2562217945.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: