Discuz! BBS

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 28|回复: 0

在Android中将字节数组保存为WAV文件

[复制链接]

393

主题

556

帖子

3296

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3296
发表于 7 天前 | 显示全部楼层 |阅读模式
在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格式文件了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-10-25 10:54 , Processed in 0.011329 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表