WAV头部组成

WAV 文件是一种音频文件格式,通常基于 Microsoft 的 RIFF(Resource Interchange File Format)结构。它的**头部(Header)**定义了音频的基本信息,如采样率、声道数、位深、数据长度等。

下面是一个标准的 PCM 编码 WAV 文件头部的组成(44 字节)及每一部分所占字节数:


✅ WAV 文件头结构(44 字节)

偏移量字段名长度(字节)内容(ASCII或数值)
0ChunkID4'RIFF'
4ChunkSize4文件总大小 – 8(= 36 + Subchunk2Size)
8Format4'WAVE'
12Subchunk1ID4'fmt '
16Subchunk1Size416(对于 PCM)
20AudioFormat21 表示 PCM,其他为压缩格式
22NumChannels2声道数:1=单声道,2=立体声
24SampleRate4采样率,如 44100
28ByteRate4= SampleRate × NumChannels × BitsPerSample ÷ 8
32BlockAlign2= NumChannels × BitsPerSample ÷ 8
34BitsPerSample2每个样本的位数,如 16
36Subchunk2ID4'data'
40Subchunk2Size4实际音频数据的字节数

🧠 示例:立体声 16bit 44.1kHz 的 WAV 文件头内容说明

假设音频数据 1 秒,立体声(2通道),16 位:

参数计算说明
SampleRate44100每秒采样 44100 次
BitsPerSample16每个采样 16 位(2 字节)
NumChannels2左右两个声道
ByteRate44100 × 2 × 16 ÷ 8 = 176400每秒多少字节
BlockAlign2 × 16 ÷ 8 = 4一个样本块(所有通道)共 4 字节
Subchunk2Size1764001 秒的数据量
ChunkSize36 + Subchunk2Size = 176436总文件大小 – 8 字节

🧾 总结各字段含义及长度

字段名意义占字节
ChunkID固定为 'RIFF'4
ChunkSize整个文件大小减去前8字节4
Format固定为 'WAVE'4
Subchunk1ID固定为 'fmt '4
Subchunk1SizePCM 固定为 164
AudioFormatPCM 为 12
NumChannels声道数量2
SampleRate采样率(单位:Hz)4
ByteRate每秒数据字节数 = SampleRate × Channels × BitsPerSample ÷ 84
BlockAlign一个样本帧的字节数 = Channels × BitsPerSample ÷ 82
BitsPerSample位深(如 8/16/24)2
Subchunk2ID固定为 'data'4
Subchunk2Size实际音频数据的字节长度4

🛠 如何读取/构造 WAV 头部(C# 示例)

csharp复制编辑// 简化例子:构造一个 WAV PCM 头部
public static void WriteWavHeader(Stream stream, int sampleRate, short bitsPerSample, short channels, int dataLength)
{
    using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
    {
        int byteRate = sampleRate * channels * bitsPerSample / 8;
        short blockAlign = (short)(channels * bitsPerSample / 8);

        writer.Write(Encoding.ASCII.GetBytes("RIFF"));
        writer.Write(36 + dataLength); // ChunkSize
        writer.Write(Encoding.ASCII.GetBytes("WAVE"));
        writer.Write(Encoding.ASCII.GetBytes("fmt "));
        writer.Write(16); // Subchunk1Size
        writer.Write((short)1); // PCM format
        writer.Write(channels);
        writer.Write(sampleRate);
        writer.Write(byteRate);
        writer.Write(blockAlign);
        writer.Write(bitsPerSample);
        writer.Write(Encoding.ASCII.GetBytes("data"));
        writer.Write(dataLength); // Subchunk2Size
    }
}
上一篇
下一篇