简介

  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格式文件头部解析的更多相关文章

  1. Android音频: 怎样使用AudioTrack播放一个WAV格式文件?

    翻译 By Long Luo 原文链接:Android Audio: Play a WAV file on an AudioTrack 译者注: 1. 因为这是技术文章,所以有些词句使用原文,表达更准 ...

  2. WAV格式文件无损合并&帧头数据体解析(python)(原创)

    一,百度百科 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频 ...

  3. 将PCM格式存储成WAV格式文件

    将PCM格式存储成WAV格式文件 WAV比PCM多44个字节(在文件头位置多) 摘自:https://blog.csdn.net/u012173922/article/details/78849076 ...

  4. wav格式文件、pcm数据

    wav格式文件是常见的录音文件,是声音波形文件格式之一,wav 文件由文件头和数据体两部分组成. 文件头是我们在做录音保存到文件的时候,要存储的文件的说明信息,播放器要通过文件头的相关信息去读取数据播 ...

  5. 【转】java将excel文件转换成txt格式文件

    在实际应用中,我们难免会遇到解析excel文件入库事情,有时候为了方便,需要将excel文件转成txt格式文件.下面代码里面提供对xls.xlsx两种格式的excel文件解析,并写入到一个新的txt文 ...

  6. 批量将某一目录下的.py文件改为.txt格式文件

    #!/usr/env/python#-*- coding:utf-8 -*-#批量将某一目录下的.py文件改为.txt格式文件import os,os.pathfile_list = os.listd ...

  7. 使用visual studio把xsd文件转成xml格式文件

    使用visual studio把xsd文件转成xml格式文件 最近一段时间都在做Amazon的mws api的对接工作,mws api的描述文件都是使用的xsd文件来进行的,之前确实也没有接触过,也花 ...

  8. 在linux下,去除^M,将windows格式文件(dos文件)改为unix格式文件

    在Windows系统下编辑的文件,换行符回车的格式为'\r\n',在linux系统下,回车的格式为'\n',在Windows下编辑的文本文件在上传至linux服务器时,回车'\r\n'就显示成^M+' ...

  9. [VB.NET][C#]WAV格式文件头部解析

    简介 WAV 为微软开发的一种声音文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源. 第一节 文件头 ...

随机推荐

  1. 用c#开发微信 系列汇总

    网上开发微信开发的教程很多,但c#相对较少.这里列出了我所有c#开发微信的文章,方便自己随时查阅.   一.基础知识 用c#开发微信(1)服务号的服务器配置和企业号的回调模式 - url接入 (源码下 ...

  2. Java设计模式2:简单工厂模式

    简单工厂模式 简单工厂模式是类的创建模式,又叫做静态工厂方法模式.简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例. 为什么要使用简单工厂模式 原因很简单:解耦. A对象如果要调用B对象,最简单 ...

  3. 人人都是 DBA(II)SQL Server 元数据

    SQL Server 中维护了一组表用于存储 SQL Server 中所有的对象.数据类型.约束条件.配置选项.可用资源等信息,这些信息称为元数据信息(Metadata),而这些表称为系统基础表(Sy ...

  4. Aoite 系列(04) - 强劲的 CommandModel 开发模式(上篇)

    Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.CommandModel 是一种开发模式,我把它成为"命令模型",这是一 ...

  5. Sql Server对象管理器的使用

    VS提供了很多便捷的工具,Sql Server对象管理器可以直接在VS里面访问数据库,不用再打开一个Management Studio.这里记录下Sql Server对象管理器的使用. 1.先在视图里 ...

  6. 为jQuery的$.ajax设置超时时间

    jQuery的ajax模块封装了非常强大的功能,有时候我们在发送一个ajax请求的时候希望能有一个超时的时间,想让程序在一段时间请求不到数据时做出一些反馈.幸运的是jQuery为我们提供了这样的参数: ...

  7. Linux cat命令

    200 ? "200px" : this.width)!important;} --> 介绍 cat命令经常会用来查看一个文件的内容,并且结合它本身的一些参数经常可以用来做一 ...

  8. 使用FiddlerCore来测试WebAPI

    大家在调试Web相关的API时,经常会用Fiddler来查看相关的请求,以及返回结果.当然你也可以尝试修改或者重复你的请求信息.本文主要介绍如何使用代码来实现fiddler的功能. Fiddler C ...

  9. 据说每个大牛、小牛都应该有自己的库——DOM处理

    这几天整理了一下思路,本来觉得DOM部分会有很多东西,但是忽然发现频繁使用的其实并不太多 class class处理部分主要有四个 hasClass:检查元素是否包含某个class addClass: ...

  10. cocoapods 更新

    sudo gem update --system sudo gem install cocoapods pod setup pod --version