|
|
在Android中将字节数组保存为WAV文件,需要按照WAV文件格式构造文件头,然后写入音频数据。以下是实现方法:
## WAV文件结构
WAV文件由文件头和音频数据两部分组成:
- **RIFF Header**: 12字节
- **Format Header**: 24字节
- **Data Header**: 8字节
- **音频数据**: 实际音频字节数据
## 实现代码
```java
public class WaveFileWriter {
/**
* 将字节数组保存为WAV文件
* @param audioData 音频字节数据
* @param filePath 保存路径
* @param sampleRate 采样率
* @param channels 声道数(1=单声道, 2=立体声)
* @param bitsPerSample 位深度(如16位)
*/
public static void saveWavFile(byte[] audioData, String filePath,
int sampleRate, int channels, int bitsPerSample) {
try {
FileOutputStream fos = new FileOutputStream(filePath);
writeWavHeader(fos, audioData.length, sampleRate, channels, bitsPerSample);
fos.write(audioData);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写入WAV文件头
*/
private static void writeWavHeader(FileOutputStream fos, int audioDataSize,
int sampleRate, int channels, int bitsPerSample)
throws IOException {
// RIFF header
fos.write("RIFF".getBytes()); // Chunk ID
fos.write(intToByteArray(36 + audioDataSize)); // Chunk Size
fos.write("WAVE".getBytes()); // Format
// Format chunk
fos.write("fmt ".getBytes()); // Subchunk1 ID
fos.write(intToByteArray(16)); // Subchunk1 Size
fos.write(shortToByteArray((short) 1)); // Audio Format (PCM)
fos.write(shortToByteArray((short) channels)); // Number of Channels
fos.write(intToByteArray(sampleRate)); // Sample Rate
fos.write(intToByteArray(sampleRate * channels * bitsPerSample / 8)); // Byte Rate
fos.write(shortToByteArray((short) (channels * bitsPerSample / 8))); // Block Align
fos.write(shortToByteArray((short) bitsPerSample)); // Bits Per Sample
// Data chunk
fos.write("data".getBytes()); // Subchunk2 ID
fos.write(intToByteArray(audioDataSize)); // Subchunk2 Size
}
// 工具方法:将int转换为小端字节数组
private static byte[] intToByteArray(int value) {
return new byte[] {
(byte) (value & 0xFF),
(byte) ((value >> 8) & 0xFF),
(byte) ((value >> 16) & 0xFF),
(byte) ((value >> 24) & 0xFF)
};
}
// 工具方法:将short转换为小端字节数组
private static byte[] shortToByteArray(short value) {
return new byte[] {
(byte) (value & 0xFF),
(byte) ((value >> 8) & 0xFF)
};
}
}
```
## 使用示例
```java
// 假设你有一个音频字节数组
byte[] audioBytes = getAudioData(); // 获取音频数据
// 保存为WAV文件
WaveFileWriter.saveWavFile(
audioBytes, // 音频数据
"/sdcard/recording.wav", // 保存路径
44100, // 采样率 44.1kHz
1, // 单声道
16 // 16位深度
);
```
## 注意事项
1. **权限**: 写入外部存储需要 `WRITE_EXTERNAL_STORAGE` 权限
2. **音频格式**: 确保字节数据格式与参数匹配(采样率、声道数、位深度)
3. **文件路径**: Android 10+建议使用应用专属目录或SAF框架
4. **线程**: 文件I/O操作应在后台线程执行
这样就可以将原始音频字节数据保存为标准的WAV格式文件了。 |
|