音频文件解析(一):WAV格式文件头部解析
简介
WAV 为微软开发的一种声音文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源。
第一节 文件头部格式
文件头(Header)是位于文件开头的一段承担一定任务的数据,通常是对主体数据的描述。
WAV 文件头由哪几部分构成
RIFF块(RIFF-Chunk)
格式化块(Format-Chunk)
附加块(Fact-Chunk)块偏移地址需要根据实际数据变更
数据块(Data-Chunk)块偏移地址需要根据实际数据变更
| 偏移地址 | 字节数 | 数据类型 | 内容 |
| &H00 | 4 | String | 'RIFF'文件标志 |
| &H04 | 4 | UInteger | 文件总长 |
| &H08 | 4 | String | 'WAVE'文件标志 |
表1-1 RIFF块(RIFF-Chunk)
| 偏移地址 | 字节数 | 数据类型 | 内容 |
| &H0C | 4 | String | 'fmt'标志 |
| &H10 | 4 | UInteger | 块长度 |
| &H12 | 2 | UShort | PCM格式类别 |
| &H14 | 2 | UShort | 声道数目 |
| &H18 | 4 | UInteger | 采样率 |
| &H1C | 4 | UInteger | 传输速率 |
| &H1E | 2 | UShort | 数据块对齐 |
| &H20 | 2 | UShort | 每样本bit数 |
| &H22 | 2 | UShort | 可选 |
表1-2 格式化块(Format-Chunk)
| 偏移地址 | 字节数 | 数据类型 | 内容 |
| &H26 | 4 | String | 'fact'标志 |
| &H2A | 4 | UInteger | 块长度 |
| &H2E | 4 | UInteger | 附加信息 |
表1-3 附加块(Fact-Chunk)
| 偏移地址 | 字节数 | 数据类型 | 内容 |
| &H32 | 4 | String | 'data'文件标志 |
| &H36 | 4 | UInteger | 数据块总长 |
表1-4 数据块(Data-Chunk)
第二节 代码实现
1. 构建一个 WaveHeader 结构体
''' <summary>
''' wav音频头部信息
''' </summary>
Public Structure WaveHeader
#Region "RiffChunk"
''' <summary>
''' RIFF标志
''' </summary>
Dim RIFF As String
''' <summary>
''' 文件长度
''' </summary>
Dim FileSize As UInteger
''' <summary>
''' WAVE标志
''' </summary>
Dim WAVE As String
#End Region
#Region "FormatChunk"
''' <summary>
''' FORMAT标志
''' </summary>
Dim FORMAT As String
''' <summary>
''' Format长度
''' </summary>
Dim FormatSize As UInteger
''' <summary>
''' 编码方式
''' </summary>
Dim FilePadding As UShort
''' <summary>
''' 声道数目
''' </summary>
Dim FormatChannels As UShort
''' <summary>
''' 采样频率
''' </summary>
Dim SamplesPerSecond As UInteger
''' <summary>
''' 每秒所需字节数
''' </summary>
Dim AverageBytesPerSecond As UInteger
''' <summary>
''' 数据块对齐单位
''' </summary>
Dim BytesPerSample As UShort
''' <summary>
''' 单个采样所需Bit数
''' </summary>
Dim BitsPerSample As UShort
''' <summary>
''' 附加信息
''' </summary>
Dim FormatExtra As UShort
#End Region
#Region "FactChunk"
''' <summary>
''' FACT标志
''' </summary>
Dim FACT As String
''' <summary>
''' Fact长度
''' </summary>
Dim FactSize As UInteger
''' <summary>
''' Fact信息
''' </summary>
Dim FactInf As UInteger
#End Region
#Region "DataChunk"
''' <summary>
''' DATA标志
''' </summary>
Dim DATA As String
''' <summary>
''' Data长度
''' </summary>
Dim DataSize As UInteger
#End Region
End Structure
VB.NET-WaveHeader
/// <summary>
/// wav音频头部信息
/// </summary>
public struct WaveHeader
{
#region "RiffChunk"
/// <summary>
/// RIFF标志
/// </summary>
public string RIFF;
/// <summary>
/// 文件长度
/// </summary>
public uint FileSize;
/// <summary>
/// WAVE标志
/// </summary>
#endregion
public string WAVE;
#region "FormatChunk"
/// <summary>
/// FORMAT标志
/// </summary>
public string FORMAT;
/// <summary>
/// Format长度
/// </summary>
public uint FormatSize;
/// <summary>
/// 编码方式
/// </summary>
public ushort FilePadding;
/// <summary>
/// 声道数目
/// </summary>
public ushort FormatChannels;
/// <summary>
/// 采样频率
/// </summary>
public uint SamplesPerSecond;
/// <summary>
/// 每秒所需字节数
/// </summary>
public uint AverageBytesPerSecond;
/// <summary>
/// 数据块对齐单位
/// </summary>
public ushort BytesPerSample;
/// <summary>
/// 单个采样所需Bit数
/// </summary>
public ushort BitsPerSample;
/// <summary>
/// 附加信息
/// </summary>
#endregion
public ushort FormatExtra;
#region "FactChunk"
/// <summary>
/// FACT标志
/// </summary>
public string FACT;
/// <summary>
/// Fact长度
/// </summary>
public uint FactSize;
/// <summary>
/// Fact信息
/// </summary>
#endregion
public uint FactInf;
#region "DataChunk"
/// <summary>
/// DATA标志
/// </summary>
public string DATA;
/// <summary>
/// Data长度
/// </summary>
#endregion
public uint DataSize;
}
C#-WaveHeader
2. 打开 *.wav 二进制文件
Dim data() As Byte = My.Computer.FileSystem.ReadAllBytes(wavFileName)
VB.NET-OpenFile
byte[] data = System.IO.File.ReadAllBytes(wavFileName);
C#-OpenFile
3. 文件头部信息解析
''' <summary>
''' 返回指定字节数组包含的Wave头部信息
''' </summary>
Public Function GetWaveHeaderFromBytes(data As Byte()) As WaveHeader
Dim header As New WaveHeader
Dim tempIndex As UShort =
header.RIFF = CType(System.Text.Encoding.ASCII.GetChars(data, , ), String)
header.FileSize = System.BitConverter.ToUInt32(data, )
header.WAVE = CType(System.Text.Encoding.ASCII.GetChars(data, , ), String)
'FormatChunk
header.FORMAT = CType(System.Text.Encoding.ASCII.GetChars(data, , ), String)
header.FormatSize = System.BitConverter.ToUInt32(data, )
header.FilePadding = System.BitConverter.ToUInt16(data, )
header.FormatChannels = System.BitConverter.ToUInt16(data, )
header.SamplesPerSecond = System.BitConverter.ToUInt32(data, )
header.AverageBytesPerSecond = System.BitConverter.ToUInt32(data, )
header.BytesPerSample = System.BitConverter.ToUInt16(data, )
header.BitsPerSample = System.BitConverter.ToUInt16(data, )
If header.FormatSize = Then
header.FormatExtra = System.BitConverter.ToUInt16(data, )
Else
header.FormatExtra =
End If
tempIndex = + header.FormatSize
'FactChunk
header.FACT = CType(System.Text.Encoding.ASCII.GetChars(data, tempIndex, ), String)
If header.FACT = "fact" Then
header.FactSize = System.BitConverter.ToUInt32(data, tempIndex + )
header.FactInf = IIf(header.FactSize = , System.BitConverter.ToUInt16(data, tempIndex + ), System.BitConverter.ToUInt32(data, tempIndex + ))
tempIndex = tempIndex + header.FactSize +
Else
header.FACT = "NULL"
header.FactSize =
header.FactInf =
End If
'DataChunk
header.DATA = CType(System.Text.Encoding.ASCII.GetChars(data, tempIndex, ), String)
header.DataSize = System.BitConverter.ToUInt32(data, tempIndex + )
Return header
End Function
VB.NET-GetWaveHeaderFromBytes
/// <summary>
/// 返回指定字节数组包含的Wave头部信息
/// </summary>
public WaveHeader GetWaveHeaderFromBytes(byte[] data)
{
WaveHeader header = new WaveHeader();
ushort tempIndex = ;
header.RIFF = Convert.ToString(System.Text.Encoding.ASCII.GetChars(data, , ));
header.FileSize = System.BitConverter.ToUInt32(data, );
header.WAVE = Convert.ToString(System.Text.Encoding.ASCII.GetChars(data, , ));
//FormatChunk
header.FORMAT = Convert.ToString(System.Text.Encoding.ASCII.GetChars(data, , ));
header.FormatSize = System.BitConverter.ToUInt32(data, );
header.FilePadding = System.BitConverter.ToUInt16(data, );
header.FormatChannels = System.BitConverter.ToUInt16(data, );
header.SamplesPerSecond = System.BitConverter.ToUInt32(data, );
header.AverageBytesPerSecond = System.BitConverter.ToUInt32(data, );
header.BytesPerSample = System.BitConverter.ToUInt16(data, );
header.BitsPerSample = System.BitConverter.ToUInt16(data, );
if (header.FormatSize == ) {
header.FormatExtra = System.BitConverter.ToUInt16(data, );
} else {
header.FormatExtra = ;
}
tempIndex = + header.FormatSize;
//FactChunk
header.FACT = Convert.ToString(System.Text.Encoding.ASCII.GetChars(data, tempIndex, ));
if (header.FACT == "fact") {
header.FactSize = System.BitConverter.ToUInt32(data, tempIndex + );
header.FactInf = (header.FactSize == ? System.BitConverter.ToUInt16(data, tempIndex + ) : System.BitConverter.ToUInt32(data, tempIndex + ));
tempIndex = tempIndex + header.FactSize + ;
} else {
header.FACT = "NULL";
header.FactSize = ;
header.FactInf = ;
}
//DataChunk
header.DATA = Convert.ToString(System.Text.Encoding.ASCII.GetChars(data, tempIndex, ));
header.DataSize = System.BitConverter.ToUInt32(data, tempIndex + );
return header;
}
C#-GetWaveHeaderFromBytes
附录
SoundPlayer 类 - MSDN
音频文件解析(一):WAV格式文件头部解析的更多相关文章
- Android音频: 怎样使用AudioTrack播放一个WAV格式文件?
翻译 By Long Luo 原文链接:Android Audio: Play a WAV file on an AudioTrack 译者注: 1. 因为这是技术文章,所以有些词句使用原文,表达更准 ...
- WAV格式文件无损合并&帧头数据体解析(python)(原创)
一,百度百科 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频 ...
- 将PCM格式存储成WAV格式文件
将PCM格式存储成WAV格式文件 WAV比PCM多44个字节(在文件头位置多) 摘自:https://blog.csdn.net/u012173922/article/details/78849076 ...
- wav格式文件、pcm数据
wav格式文件是常见的录音文件,是声音波形文件格式之一,wav 文件由文件头和数据体两部分组成. 文件头是我们在做录音保存到文件的时候,要存储的文件的说明信息,播放器要通过文件头的相关信息去读取数据播 ...
- 【转】java将excel文件转换成txt格式文件
在实际应用中,我们难免会遇到解析excel文件入库事情,有时候为了方便,需要将excel文件转成txt格式文件.下面代码里面提供对xls.xlsx两种格式的excel文件解析,并写入到一个新的txt文 ...
- 批量将某一目录下的.py文件改为.txt格式文件
#!/usr/env/python#-*- coding:utf-8 -*-#批量将某一目录下的.py文件改为.txt格式文件import os,os.pathfile_list = os.listd ...
- 使用visual studio把xsd文件转成xml格式文件
使用visual studio把xsd文件转成xml格式文件 最近一段时间都在做Amazon的mws api的对接工作,mws api的描述文件都是使用的xsd文件来进行的,之前确实也没有接触过,也花 ...
- 在linux下,去除^M,将windows格式文件(dos文件)改为unix格式文件
在Windows系统下编辑的文件,换行符回车的格式为'\r\n',在linux系统下,回车的格式为'\n',在Windows下编辑的文本文件在上传至linux服务器时,回车'\r\n'就显示成^M+' ...
- [VB.NET][C#]WAV格式文件头部解析
简介 WAV 为微软开发的一种声音文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源. 第一节 文件头 ...
随机推荐
- CSS3之图片3D翻转效果(网页效果--每日一更)
今天,带来的是纯CSS3的效果--图片3D翻转. 请看效果:亲,请点击这里 这个效果主要还是运用了CSS3的transform变形属性,与上个效果不同的是,这次并不是动画,所以没有采用animatio ...
- ENode 2.0 - 第一个真实案例剖析-一个简易论坛(Forum)
前言 经过不断的坚持和努力,ENode 2.0的第一个真实案例终于出来了.这个案例是一个简易的论坛,开发这个论坛的初衷是为了验证用ENode框架来开发一个真实项目的可行性.目前这个论坛在UI上是使用了 ...
- Entity Framework 5.0系列之Code First数据库迁移
我们知道无论是"Database First"还是"Model First"当模型发生改变了都可以通过Visual Studio设计视图进行更新,那么对于Cod ...
- Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制
一.事件的捕获与冒泡 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监 ...
- NodeJS系列~第二个小例子,解决中文乱码的问题
返回目录 为了使页面支持的字符更多,所以编码使用UTF-8,注意,你的原js文件的编码也要是utf-8的,可以通过记事本进行编码的修改
- [常见问题]Project facet Java versin 1.8 is not support.
发生这个问题的原因是我们的java编译环境(JDK版本),与tomcat运行环境(JDK或JRE版本)不一致导致的. 到eclipse的设置中找到compile项(或右键项目进入),看一下编译环境的J ...
- atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx
atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx 1.1. V3 新特性1 1.2. V2 新特性1 2. Token的归类1 3. Token的用途 ...
- atitit。ocr框架类库大全 attilax总结
atitit.ocr框架类库大全 attilax总结 Tesseract Asprise JavaOCR 闲来无事,发现百度有一个OCR文字识别接口,感觉挺有意思的,拿来研究一下. 百度服务简介:文字 ...
- phpstudy80端口被占用时的解决方案
1.适合人群? 之前笔记本单独安装过Apache.php.mysql环境,但是后期想用集成开发环境phpstudy的,安装完phpstudy后(之前的单独环境依然存在),发现启动时,总是显示80端口被 ...
- 每天一个linux命令(44):top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...