草庐IT

WAV文件解析

qq_45893491 2023-11-06 原文

目录

一、WAV简介

二、WAV文件结构

2.1 首部数据

2.2 Format数据块

2.3 Data数据块

2.4其他数据块

参考资料


一、WAV简介

WAV格式是微软公司开发的一种声音文件格式,也叫波形声音文件,是最早的数字音频格式,被Windows平台及其应用程序广泛支持。WAV格式支持许多压缩算法,支持多种音频位数、采样频率和声道,采用44.1kHz的采样频率,16位量化位数,因此WAV的音质与CD相差无几,但WAV格式对存储空间需求太大不便于交流和传播。

二、WAV文件结构

WAV文件遵循RIFF规则,其内容以区块(chunk)为最小单位进行存储。WAV文件一般由3个区块组成:RIFF chunkFormat chunkData chunk。另外,文件中还可能包含一些可选的区块,如:Fact chunk、Cue points chunk、Playlist chunk、Associated data list chunk等。

下文将通过分析一个wav示例文件来详细介绍WAV文件格式。

图1 wav示例文件

2.1 首部数据

整个WAV都是由RIFF数据块组成,可以将整个WAV文件看作一个完整的RIFF数据块,在这个RIFF数据块中又包含若干的子块存放不同的信息。

对于整个WAV文件而言,其首部结构,也即整个RIFF数据块的头部结构如下。

表1 WAV文件首部的结构

名称

偏移地址

字节数

端序

内容

ID

0x00

4Byte

大端

'RIFF' (0x52494646)

Size

0x04

4Byte

小端

文件大小

Type

0x08

4Byte

大端

'WAVE'(0x57415645)

在UltraEdit软件中打开样例音频文件。

 

WAV首部数据部分在图中用横线画出。

  • 红线部分是ID,52 49 46 46 对应的ASCII字符为RIFF。
  • 黄线部分是Size,代表文件大小,注意该项的端序为小端开始,即从低位向高位读入。该部分的实际值应为 80 B1 45 01 的反向顺序即 01 45 B1 80 换成10进制为21344640字节(20844kB)。
  • 蓝线部分是Type,57 41 56 45对应的ASCII字符为WAVE。

2.2 Format数据块

WAV文件的其中一个重要的子块就是Format数据块,包含WAV音频文件的一些详细属性,具体结构如下。

表2 Format数据块的结构

名称

偏移地址

字节数

端序

内容

ID

0x00

4Byte

大端

'fmt ' (0x666D7420)

Size

0x04

4Byte

小端

16

AudioFormat

0x08

2Byte

小端

音频格式

NumChannels

0x0A

2Byte

小端

声道数

SampleRate

0x0C

4Byte

小端

采样率

ByteRate

0x10

4Byte

小端

每秒数据字节数

BlockAlign

0x14

2Byte

小端

数据块对齐

BitsPerSample

0x16

2Byte

小端

采样位数

继续分析示例文件,可以看到RIFF数据块后即为Format数据块。

红线部分是ID,66 6D 74 20对应的ASCII字符即为fmt 。(20对应的SCII字符为空格)

黄线部分是声道数,02 00 表示该音频文件为双声道。

绿线部分是采样率,同样从小端开始,00 00 AC 44 换成10进制为44100。

2.3 Data数据块

Data数据块是存放实际音频数据的数据块,具体结构如下。

表3 Data数据块的结构

名称

偏移地址

字节数

端序

内容

ID

0x00

4Byte

大端

'data' (0x64617461)

Size

0x04

4Byte

小端

N

Data

0x08

NByte

小端

音频数据

样例文件中红线部分即为Data数据块的ID部分, 64 61 74 61 对应的ASCII字符为data。

蓝线部分为Data数据块的Size部分,代表Data数据块的长度,01 45 B0 BC换成10进制为21344444字节。

蓝线后的部分即为实际的音频数据,对于不同的声道数和采样率,音频数据的布局也不同,具体的布局如下。

8bit 单声道
采样1采样2
数据1数据2
8bit 双声道
采样1采样2
声道1数据1声道2数据1声道1数据2声道2数据2
16bit 单声道
采样1采样2
数据1低字节数据1高字节数据1低字节数据1高字节
16bit 双声道
采样1采样2
声道1数据1低字节声道1数据1高字节声道2数据1低字节声道2数据1高字节声道1数据2低字节声道1数据2高字节声道2数据2低字节声道2数据2高字节

2.4其他数据块

在WAV中还存在其他的数据块,存放不同的辅助信息,这些块都以RIFF数据块格式存储,格式如下。

当ID为“RIFF”或“LIST”时,允许该数据块中包含子块。

"LIST"块的数据域的起始位置也有一个四字节类型码(List Type),用于说明LIST数据域的数据内容。比如,类型码为"INFO"时,其数据域可能包括"ICOP"、"ICRD"块,用于记录文件版权和创建时间信息。

 例如在示例文件中就有“IART”块(红线部分)用于存放音乐家姓名,“INAM”块(黄线部分)用于存放音乐标题;“IPRD”块(蓝线部分)用于存放音乐所属专辑名称。

参考资料

WAV_百度百科 (baidu.com)https://baike.baidu.com/item/WAV/218914?fromtitle=WAV%E6%A0%BC%E5%BC%8F&fromid=291538&fr=aladdin史上全最的WAV格式详解 - 简书 (jianshu.com)https://www.jianshu.com/p/b7cadd3e9c4dWAV文件格式详解_imxiangzi的专栏-CSDN博客_wav格式https://blog.csdn.net/imxiangzi/article/details/80265978

有关WAV文件解析的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  4. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  5. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  6. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  9. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  10. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

随机推荐