概述
WAV图片格式分析
- WAV文件概述
- 文件组成
- RIFF格式
- RIFF chunk
- WAV文件格式
- RIFFchunk
- Format chunk
- Data Chunk
- 图片实例讲解
- 实验总结
WAV文件概述
WAVE(Waveform Audio File Format):是微软与IBM公司所开发在个人电脑存储音频流的编码格式。其采用RIFF(Resource Interchange File Format)文件格式结构(资源互换文件格式),通常用来保存PCM格式的原始音频数据,不对原有文件进行压缩,所以在音质方面无失真情况。
通常可以用于保存AVI(视音频交错数据)、WAV(波形格式)、RDI(位图数据)等格式的数据。
文件组成
WAV文件主要由以下三部分组成:
- RIFF Chunk:文件标识符,WAV身份判断
- FORMAT Chunk:文件参数模块
- DATA Chunk:实际数据块
此外,文件中还可能包含一些可选的区块,如:Fack Chunk、Cue Points Chunk等,只有通过某些软件进行转化的过程中可能会加入该子块,其主要存储一些关于该文件的重要信息(如压缩编码信息等)
WAVE文件是以RIFF(Resource Interchange File Format, 资源交互文件格式)格式来组织内部结构的,在了解WAV文件之前,我们首先对RIFF格式进行简单了解。
RIFF格式
RIFF格式是一种包含多个嵌套的二进制文件格式,其基本构成单元是chunk。
chunk表示数据的一个基本逻辑单元,例如视频的一帧数据、音频的一帧数据等等。每个RIFF块的基本结构如下:
typedef struct Chunk
{
DWORD ChunkId; // 用于表示块的类型(chunkID)
DWORD ChunkSize; // 用于表明数据域的长度,注意是数据域
BYTE ChunkData[ChunkSize]; // 数据部分
} Chunk;
ChunkId:四字节,用于标识块的类型,例如RIFF、LIST、AVI等。(一般是四个字符,用FOURCC表示,如果少于四个字符,用补空格填满四个字节)
ChunkSize:四字节,用于块中数据长度(不包括填充添加的0,也不包括开头的基本信息情况)
ChunkData:n字节,存储数据。注意必须是偶数。如果实际数据是奇数(字节),则在数据末尾补0。
值得注意的是,RIFF格式允许chunk嵌套,一个chunk中的chunk被称之为子块(subchunk),但只有ID为“RIFF”(RIFF块)或者“LIST”(列表块)的chunk允许拥有子块,其它的块不允许嵌套,仅仅只包含数据。
我们重点对RIFF块进行分析:
RIFF chunk
ChunkId为RIFF的块是RIFF块,根据规定,RIFF文件第一个chunk开头标识符必须为RIFF,并且一个RIFF文件只能有这一个标志位RIFF的块。
以实例讲解作为分析,如下图所示RIFFchunk展示。
- RIFF块,头部ID固定为RIFF,size为数据域的长度,后面部分为数据域。在数据域开头有一个FOURCC(四字节码),用于标识子块的数据类型,接下来是子块部分。
- 图中的子块为LISTchunk,ID即为LIST,size为列表块数据域的长度,后面为数据域。在数据里又包含多个子块。
WAV文件格式
WAV文件遵循RIFF规则,内容以chunk为最小单位存储,一般由RIFF chunk、format chunk和datachunk组成。此外,文件中还可能包含其余chunk,例如Fact chunk、Associated data list chunk等。
接下来分别对RIFFchunk、format chunk、datachunk进行介绍:
RIFFchunk
typedef struct chunk
{
DWORD ChunkId; // 块标志
DWORD size; // 块大小
DWORD Type; // 后续跟块介绍
}chunk;
名称 | 偏移地址 | 说明 |
---|---|---|
chunkId | 0x00 | 固定为0x5249 4646(表示为RIFF) |
Chunksize | 0x04 | size为wav文件的长度减去ID和Size的长度 |
Type | 0x08 | 固定为0x5741 5645(表示WAVE) |
Format chunk
typedef struct Format chunk
{
DWORD ChunkId; // 块标志
DWORD size; // 块大小
WORD AudioFormat; // 表明音频格式
WORD NumChannels;//表明声道数
DWORD SampleRate;//采样率
DWORD ByteRate;//每秒字节数
WORD BlockAlign;//数据块对齐
WORD BitsPerSample;//采样位数
}Format chunk;
名称 | 偏移地址 | 说明 |
---|---|---|
chunkId | 0x00 | 固定为0x666D7420(表示为fmt) |
Chunksize | 0x04 | 表示该区块的数据大小(不包含ID和size) |
AudioFormat | 0x08 | 音频格式,PCM音频数据的值为1;大于1表示有压缩的编码 |
NumChannels | 0x0A | 声道数,1表示单声道,2表示双声道 |
SampleRate | 0x0C | 表示音频数据的采样率 |
ByteRate | 0x10 | 每秒数据字节数(ByteRate = SampleRate * NumChannels * BitsPerSample / 8) |
BlockAlign | 0x14 | 每个采样所需的字节数 (BlockAlign = NumChannels * BitsPerSample / 8) |
BitsPerSample | 0x16 | 表明每个采样存储的bit数,8:8bit,16:16bit,32:32bit,值越大,声音还原越好 |
注意:只有'RIFF','LIST'chunk有Type
Data Chunk
typedef struct Data Chunk
{
DWORD ChunkId; // 块标志(以data为标识)
DWORD size; // 数据块的长度
nByte Data; // 具体数据
}Data Chunk;
名称 | 偏移地址 | 说明 |
---|---|---|
chunkId | 0x00 | 固定为0x64617461(表示为data) |
Chunksize | 0x04 | 表示整个wav文件的数据大小 |
Data | 0x08 | 为具体的音频数据 |
对于数据部分:特别强调的是:
8bit单声道:
采样1(8bit) | 采样2(8bit) |
---|---|
数据1 | 数据2 |
8bit双声道:
采样1(8bit) | 采样2(8bit) | ||
---|---|---|---|
数据1左声道(4bit) | 数据1右声道(4bit) | 数据2左声道(4bit) | 数据2右声道(4bit) |
16bit单声道相同:
采样1(16bit) | 采样2(16bit) | ||
---|---|---|---|
数据1低字节(8bit) | 数据1高字节(8bit) | 数据2低字节(8bit) | 数据2高字节(8bit) |
16bit双声道:
采样1(16bit) | |||
---|---|---|---|
左声道(8bit) | 右声道(8bit) | ||
低字节(4bit) | 高字节(4bit) | 低字节(4bit) | 高字节(4bit) |
图片实例讲解
选取时长为1分钟的part1.wav文件进行分析:
利用二进制编辑器打开进行具体分析:
· RIFF chunk:
数字 | 名称 | 实际大小 | 说明 |
---|---|---|---|
52 49 46 46 | chunkID | 固定为0x52494646(大端) | 表示此块为RIFFchunk |
06 80 A1 00 | chunksize | 0xA18006=10,584,070D | 表示整个wav文件块共有10,584,070字节 |
57 41 56 45 | type | 固定为0x57415645(大端) | 表示为wave文件 |
· Format Chunk:
数字 | 名称 | 实际大小 | 说明 |
---|---|---|---|
66 6D 74 20 | chunkID | 固定为0x666D7420(大端) | 表示此块为format chunk(fmt) |
10 00 00 00 | chunksize | 0x10=16D | 表示fmt块共有16字节 |
01 00 | Audio Format | 0x01=1D | 表示为PCM音频数据 |
02 00 | numchannels | 0x02=2D | 表示为双声道 |
44 AC 00 00 | sampleRate | 0xAC44=44100D | 表示音频数据采样率为44.1kHz |
10 B1 02 00 | byteRate | 0x02B110=176400D | 表示每秒数据共有176400个字节 |
04 00 | blockalign | 0x04=4D | 每个采样数据所需4个字节 |
10 00 | bitspersample | 0x10=16D | 每个采样存储为16bit |
· LIST chunk
我们可以观察到,本例子中的WAV文件夹杂一个LIST chunk(list chunk的格式如前面第一段介绍的,这里我们简单分析下)
数字 | 名称 | 实际大小 | 说明 |
---|---|---|---|
4C 49 53 54 | chunkID | 固定为0x4C495354(大端) | 表示此块为LISTchunk |
1A 00 00 00 | chunksize | 0x1A=26D | 表示list块共有26字节 |
49 4E 46 4F | type | 固定为0x494E464F(大端) | 表示为LISTchunk(?) |
… | data | … | … |
经过格式转换后的chunk文件含有list chunk,存储格式转换信息,我们从chunksize开始跳过26字节直接进入data部分分析:
· Data Chunk:
数字 | 名称 | 实际大小 | 说明 |
---|---|---|---|
64 61 74 61 | chunkID | 固定为0x64617461(大端) | 表示此块为Data chunk |
C0 7F A1 00 | chunksize | 0xA17FC0=10584000D | 表示共有10584000字节数据 |
… | data | … | (此文件为双声道16bit量化,参照上面的声道采样表进行分析) |
根据分析结果画出实例文件结构:
实验总结
本次实验通过查阅资料了解了WAV文件格式,利用格式工厂转换mp4文件为wav文件,对转换的wav文件进行了简单分析。具体的实验方法和前几次的文件分析方法一致,本次实验过程中没有遇到太多问题,但遗憾的寻找了很久资料源,都没有找到list chunk数据的具体分析,不过后续如果用到wav文件分析数据,我们可以直接根据chunksize跳过listchunk部分进入data!
最后
以上就是苗条蓝天为你收集整理的数据压缩第三周作业——WAV文件分析WAV文件概述的全部内容,希望文章能够帮你解决数据压缩第三周作业——WAV文件分析WAV文件概述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复