用audiorecord录制一个wav音频文件
时间: 2024-03-14 17:47:40 浏览: 183
好的,以下是用 Android 的 AudioRecord 类录制 wav 音频文件的代码示例:
```java
private void startRecording() {
// 设置音频录制参数
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes);
// 开始录制音频
audioRecord.startRecording();
byte[] audioData = new byte[bufferSizeInBytes];
// 创建 wav 文件
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.wav";
try {
FileOutputStream fos = new FileOutputStream(filePath);
// 写入 wav 文件头
writeWaveFileHeader(fos, audioData.length);
while (isRecording) {
// 读取录制的音频数据
int readSize = audioRecord.read(audioData, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readSize) {
// 写入 wav 文件
fos.write(audioData, 0, readSize);
}
}
// 关闭文件流
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
// 停止录制音频
audioRecord.stop();
audioRecord.release();
}
private void writeWaveFileHeader(FileOutputStream fos, int audioDataLength) throws IOException {
// 音频数据大小
long dataSize = audioDataLength;
// 文件大小
long fileSize = 36 + dataSize;
// 采样率
int sampleRate = 44100;
// 声道数
int numChannels = 1;
// 位深度
int bitsPerSample = 16;
byte[] header = new byte[44];
// ChunkID
header[0] = 'R';
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
// ChunkSize
header[4] = (byte) (fileSize & 0xff);
header[5] = (byte) ((fileSize >> 8) & 0xff);
header[6] = (byte) ((fileSize >> 16) & 0xff);
header[7] = (byte) ((fileSize >> 24) & 0xff);
// Format
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
// Subchunk1ID
header[12] = 'f';
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
// Subchunk1Size
header[16] = 16;
header[17] = 0;
header[18] = 0;
header[19] = 0;
// AudioFormat
header[20] = 1;
header[21] = 0;
// NumChannels
header[22] = (byte) numChannels;
header[23] = 0;
// SampleRate
header[24] = (byte) (sampleRate & 0xff);
header[25] = (byte) ((sampleRate >> 8) & 0xff);
header[26] = (byte) ((sampleRate >> 16) & 0xff);
header[27] = (byte) ((sampleRate >> 24) & 0xff);
// ByteRate
int byteRate = sampleRate * numChannels * bitsPerSample / 8;
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
// BlockAlign
int blockAlign = numChannels * bitsPerSample / 8;
header[32] = (byte) (blockAlign & 0xff);
header[33] = (byte) ((blockAlign >> 8) & 0xff);
// BitsPerSample
header[34] = (byte) bitsPerSample;
header[35] = 0;
// Subchunk2ID
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
// Subchunk2Size
header[40] = (byte) (dataSize & 0xff);
header[41] = (byte) ((dataSize >> 8) & 0xff);
header[42] = (byte) ((dataSize >> 16) & 0xff);
header[43] = (byte) ((dataSize >> 24) & 0xff);
fos.write(header, 0, 44);
}
```
以上代码中,我们首先设置了音频录制的参数:音频源为麦克风,采样率为 44100 Hz,声道数为单声道,位深度为 16 位。然后通过 AudioRecord.getMinBufferSize() 方法获取音频数据缓冲区的大小,并创建 AudioRecord 实例。
接着,我们开始录制音频,并创建一个 FileOutputStream 实例来写入 wav 文件。在录制过程中,我们不断读取录制的音频数据,并将其写入 wav 文件。最后,我们在停止录制音频之前,关闭文件流,并释放 AudioRecord 实例。
在写入 wav 文件之前,我们需要先写入 wav 文件头。wav 文件头的格式如下:
| 字段 | 长度 | 说明 |
| --- | --- | --- |
| ChunkID | 4 | 固定值 "RIFF" |
| ChunkSize | 4 | 文件大小(不包括 ChunkID 和 ChunkSize)|
| Format | 4 | 固定值 "WAVE" |
| Subchunk1ID | 4 | 固定值 "fmt " |
| Subchunk1Size | 4 | 16(表示 Subchunk1 的大小)|
| AudioFormat | 2 | 音频格式(1 表示 PCM)|
| NumChannels | 2 | 声道数 |
| SampleRate | 4 | 采样率 |
| ByteRate | 4 | 每秒传输的字节数 |
| BlockAlign | 2 | 每个采样点占用的字节数 |
| BitsPerSample | 2 | 位深度 |
| Subchunk2ID | 4 | 固定值 "data" |
| Subchunk2Size | 4 | 音频数据大小 |
我们可以通过 writeWaveFileHeader() 方法来写入 wav 文件头。在该方法中,我们需要传入 wav 文件的 FileOutputStream 对象和音频数据的长度,然后按照上述格式写入 wav 文件头。最后,我们在 wav 文件头的末尾写入音频数据大小即可。
希望以上代码能够帮助到你!
阅读全文
相关推荐
![java](https://img-home.csdnimg.cn/images/20250102104920.png)
![java](https://img-home.csdnimg.cn/images/20250102104920.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://img-home.csdnimg.cn/images/20241231044901.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)