数据压缩第三周作业——WAV文件分析

本文深入剖析了WAV音频文件的格式,包括RIFF chunk、format chunk和data chunk的详细结构。WAV文件基于RIFF格式,由RIFF标识、format参数和data数据组成。RIFF格式允许chunk嵌套,每个chunk包含ID、大小和数据。format chunk定义了音频格式,如采样率、声道数和位深。data chunk则存储实际的音频数据。文中通过实例展示了chunk的解析过程,为理解WAV文件格式提供了清晰的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
名称偏移地址说明
chunkId0x00固定为0x5249 4646(表示为RIFF)
Chunksize0x04size为wav文件的长度减去ID和Size的长度
Type0x08固定为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;
名称偏移地址说明
chunkId0x00固定为0x666D7420(表示为fmt)
Chunksize0x04表示该区块的数据大小(不包含ID和size)
AudioFormat0x08音频格式,PCM音频数据的值为1;大于1表示有压缩的编码
NumChannels0x0A声道数,1表示单声道,2表示双声道
SampleRate0x0C表示音频数据的采样率
ByteRate0x10每秒数据字节数(ByteRate = SampleRate * NumChannels * BitsPerSample / 8)
BlockAlign0x14每个采样所需的字节数 (BlockAlign = NumChannels * BitsPerSample / 8)
BitsPerSample0x16表明每个采样存储的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;
名称偏移地址说明
chunkId0x00固定为0x64617461(表示为data)
Chunksize0x04表示整个wav文件的数据大小
Data0x08为具体的音频数据

对于数据部分:特别强调的是:
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 46chunkID固定为0x52494646(大端)表示此块为RIFFchunk
06 80 A1 00chunksize0xA18006=10,584,070D表示整个wav文件块共有10,584,070字节
57 41 56 45type固定为0x57415645(大端)表示为wave文件

在这里插入图片描述
· Format Chunk:

数字名称实际大小说明
66 6D 74 20chunkID固定为0x666D7420(大端)表示此块为format chunk(fmt)
10 00 00 00chunksize0x10=16D表示fmt块共有16字节
01 00Audio Format0x01=1D表示为PCM音频数据
02 00numchannels0x02=2D表示为双声道
44 AC 00 00sampleRate0xAC44=44100D表示音频数据采样率为44.1kHz
10 B1 02 00byteRate0x02B110=176400D表示每秒数据共有176400个字节
04 00blockalign0x04=4D每个采样数据所需4个字节
10 00bitspersample0x10=16D每个采样存储为16bit

· LIST chunk
在这里插入图片描述
我们可以观察到,本例子中的WAV文件夹杂一个LIST chunk(list chunk的格式如前面第一段介绍的,这里我们简单分析下)

数字名称实际大小说明
4C 49 53 54chunkID固定为0x4C495354(大端)表示此块为LISTchunk
1A 00 00 00chunksize0x1A=26D表示list块共有26字节
49 4E 46 4Ftype固定为0x494E464F(大端)表示为LISTchunk(?)
data

经过格式转换后的chunk文件含有list chunk,存储格式转换信息,我们从chunksize开始跳过26字节直接进入data部分分析:
在这里插入图片描述
· Data Chunk:

数字名称实际大小说明
64 61 74 61chunkID固定为0x64617461(大端)表示此块为Data chunk
C0 7F A1 00chunksize0xA17FC0=10584000D表示共有10584000字节数据
data(此文件为双声道16bit量化,参照上面的声道采样表进行分析)

根据分析结果画出实例文件结构:
在这里插入图片描述

实验总结

本次实验通过查阅资料了解了WAV文件格式,利用格式工厂转换mp4文件为wav文件,对转换的wav文件进行了简单分析。具体的实验方法和前几次的文件分析方法一致,本次实验过程中没有遇到太多问题,但遗憾的寻找了很久资料源,都没有找到list chunk数据的具体分析,不过后续如果用到wav文件分析数据,我们可以直接根据chunksize跳过listchunk部分进入data!

软件名称:Monkey's Audio 软件版本:4.06 运行环境:WinALL 汉化类型:汉化安装版 软件性质:免费 官方主页:http://www.monkeysaudio.com ━━━━━━━━━━━━━━━ 软件简介 ━━━━━━━━━━━━━━━ Monkey's Audio(http://www.monkeysaudio.com)是一种无损压缩技术。他并不是由什么大公司发明的,完全是一个个人业余兴趣作品。为了使Monkey's Audio能有更好的发展,现在这个软件已经公开了源代码。   这种压缩格式的特点是无损压缩,也就是说对压缩数据进行还原之后得到的数据与原来的数据是完全相同的。该格式的特点尤其适合那些拥有一对“金耳朵”并且一直对mp3的音质耿耿于怀的音乐发烧友。后者有人会问,要无损压缩,我随便找个压缩软件比如WINRAR都可以达到不错的效果了,还要这种格式干嘛? 所以这里要澄清一个误解:使用普通的压缩软件进行压缩无疑是可以得到不错的压缩效果,有时候甚至更优于使用Monkey's Audio,但是压缩软件生成的压缩包必须要先解压还原之后才能播放里面的内容,而Monkey's Audio这种无损压缩编码得到的文件可以直接使用播放器(比如WinAMP)进行播放。Monkey's Audio的压缩效果大约在2:1左右,也就是说压缩结果是原来的二分之一大小。一张CD大约需要330MB左右的空间存放,相比之下还是比较占空间的。由于这个原因,所以对音质要求不是太高的人通常都选择VBR方式的mp3而不是选择它。   与Monkey's Audio类似的编码格式还包括WavPack、RKAU、Shorten等等。由于相对不是那么出名,又或者在某些方面不够Monkey's Audio做得好,因此获得的关注程度就逊色很多。   Monkey's Audio 软件在Monkey‘s Audio官方网站可以下载,专用于压缩wav文件为ape文件或解压ape文件wav文件   Monkey's Audio 是一种快速且易于操作的数字音乐压缩方案,它所生成的 APE 无损压缩格式,压缩率接近50%,压缩后的品质跟原始声音的品质完全是一样的(据说有人将 Wav 文件生成 APE 格式后,再转换回 Wav 文件,结果对比两个Wav 文件的 MD5 值时,发现居然完全一样)!   APE 无损压缩音频格式已被绝大多数音频播放器如:Winamp、Media Jukebox以及越来越多的应用程序支持。Monkey's Audio 是 APE 的压缩、解压缩、转换操作的平台。   本汉化安装版包括了原版的一切组件,无需原版文件,另外,用于 Winamp的APE插件安装程序也替换为汉化版。 ━━━━━━━━━━━━━━━ 汉化历程 ━━━━━━━━━━━━━━━ 2006.01.11 发布 Monkey's Audio 4.01 b1 汉化版 2006.03.14 发布 Monkey's Audio 4.01 b2 汉化版 2009.02.02 发布 Monkey's Audio 4.03 汉化版 2009.02.03 发布 Monkey's Audio 4.04 汉化版 2009.02.05 发布 Monkey's Audio 4.05 汉化版 2009.03.19 发布 Monkey's Audio 4.06 汉化版
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值