您的位置:首页 > 其它

wav文件格式分析

2012-12-06 10:24 211 查看
一、综述

W***E文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。

RIFF是英文Resource Interchange File Format的缩写,每个W***E文件的头四个

字节便是“RIFF”。

W***E文件是由若干个Chunk组成的。按照在文件中的出现位置包括:RIFF W***E

Chunk, Format Chunk, Fact Chunk(可选), Data Chunk。具体见下图:
------------------------------------------------

| RIFF W***E Chunk |

| ID = 'RIFF' |

| RiffType = 'W***E' |

------------------------------------------------

| Format Chunk |

| ID = 'fmt ' |

------------------------------------------------

| Fact Chunk(optional) |

| ID = 'fact' |

------------------------------------------------

| Data Chunk |

| ID = 'data' |

------------------------------------------------

图1 Wav格式包含Chunk示例

其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位

于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大

小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节

表示数值低位,高字节表示数值高位。下***体介绍各个Chunk内容。

PS:

所有数值表示均为低字节表示低位,高字节表示高位。

用表格说明一下文件的格式:

起始地址

占用空间

本地址数字的含义

00H

4byte

RIFF,资源交换文件标志。

04H

4byte

从下一个地址开始到文件尾的总字节数。高位字节在后面,这里就是001437ECH,换成十进制是1325036byte,算上这之前的8byte就正好1325044byte了。

08H

4byte

W***E,代表wav文件格式。

0CH

4byte

FMT ,波形格式标志

10H

4byte

00000010H,16PCM,我的理解是用16bit的数据表示一个量化结果。

14H

2byte

为1时表示线性PCM编码,大于1时表示有压缩的编码。这里是0001H。

16H

2byte

1为单声道,2为双声道,这里是0001H。

18H

4byte

采样频率,这里是00002B11H,也就是11025Hz。

1CH

4byte

Byte率=采样频率*音频通道数*每次采样得到的样本位数/8,00005622H,也就是22050Byte/s=11025*1*16/2。

20H

2byte

块对齐=通道数*每次采样得到的样本位数/8,0002H,也就是2=1*16/8。

22H

2byte

样本数据位数,0010H即16,一个量化样本占2byte。

24H

4byte

data,一个标志而已。

28H

4byte

Wav文件实际音频数据所占的大小,这里是001437C8H即1325000,再加上2CH就正好是1325044,整个文件的大小。

2CH

不定

量化数据。

#include <iostream>
#include <fstream>
using namespace std;

struct wav_struct
{
    unsigned long file_size;        //文件大小
    unsigned short channel;            //通道数
    unsigned long frequency;        //采样频率
    unsigned long Bps;                //Byte率
    unsigned short sample_num_bit;    //一个样本的位数
    unsigned long data_size;        //数据大小
    unsigned char *data;            //音频数据 ,这里要定义什么就看样本位数了,我这里只是单纯的复制数据

};

int main(int argc,char **argv)
{
    fstream fs;
    wav_struct W***;
    fs.open("B:\\output.wav",ios::binary|ios::in);

//    fs.seekg(0x04);                //从文件数据中获取文件大小
//    fs.read((char*)&W***.file_size,sizeof(W***.file_size));
//    W***.file_size+=8;
    
    fs.seekg(0,ios::end);        //用c++常用方法获得文件大小
    W***.file_size=fs.tellg();

    fs.seekg(0x14);
    fs.read((char*)&W***.channel,sizeof(W***.channel));

    fs.seekg(0x18);
    fs.read((char*)&W***.frequency,sizeof(W***.frequency));

    fs.seekg(0x1c);
    fs.read((char*)&W***.Bps,sizeof(W***.Bps));

    fs.seekg(0x22);
    fs.read((char*)&W***.sample_num_bit,sizeof(W***.sample_num_bit));

    fs.seekg(0x28);
    fs.read((char*)&W***.data_size,sizeof(W***.data_size));

    W***.data=new unsigned char[W***.data_size];

    fs.seekg(0x2c);
    fs.read((char *)W***.data,sizeof(char)*W***.data_size);

    cout<<"文件大小为  :"<<W***.file_size<<endl;
    cout<<"音频通道数  :"<<W***.channel<<endl;
    cout<<"采样频率    :"<<W***.frequency<<endl;
    cout<<"Byte率      :"<<W***.Bps<<endl;
    cout<<"样本位数    :"<<W***.sample_num_bit<<endl;
    cout<<"音频数据大小:"<<W***.data_size<<endl;
    cout<<"最后20个数据:"<<endl;

    for (unsigned long i=W***.data_size-20;i<W***.data_size;i++)
    {
        printf("%x  ",W***.data[i]);
    }
    fs.close();

    delete[] W***.data;
    system("pause");

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