1. WAV格式

wav是微软开发的一种音频文件格式,注意,wav文件格式是无损音频文件格式,相对于其他音频格式文件数据是没有经过压缩的,通常文件也相对比较大些。、

支持多种音频数字,取样频率和声道,标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在声音文件质量和CD相差无几! WAV打开工具是WINDOWS的媒体播放器
通常使用三个参数来表示声音量化位数,取样频率和采样点振幅量化位数分为8位,16位,24位三种,声道单声道和立体声之分,单声道振幅数据为n*1矩阵点,立体声为n*2矩阵点,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种,不过尽管音质出色,但在压缩后的文件体积过大!相对其他音频格式而言是一个缺点,其 文件大小的计算方式为:WAV格式文件所占容量(B) = (取样频率 X量化位数X 声道) X 时间 / 8 (字节= 8bit) 每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化

注:专业名词(取样频率、量化位数、声道)解释:https://blog.csdn.net/eric88/article/details/17098603

  • 采样位数:也叫量化位数(单位:比特),是存储每个采样值所用的二进制位数。采样值反应了声音的波动状态。采样位数决定了量化精度。采样位数越长,量化的精度就越高,还原的波形曲线越真实,产生的量化噪声越小,回放的效果就越逼真。常用的量化位数有4、8、12、16、24。量化位数与声卡的位数和编码有关。

  • 采样频率:采样频率是指录音设备在一秒钟内对声音信号的采样次数,采样频率越高声音的还原就越真实越自然。越高所能描述的声波频率就越高。采样率决定声音频率的范围(相当于音调),可以用数字波形表示。以波形表示的频率范围通常被称为带宽。要正确理解音频采样可以分为采样的位数和采样的频率。

  • 声道数:  使用的声音通道的个数,也是采样时所产生的声音波形的个数。播放声音时,单声道的WAV一般使用一个喇叭发声,立体声的WAV可以使两个喇叭发声。记录声音时,单声道,每次产生一个波形的数据,双声道,每次产生两个波形的数据,所占的存储空间增加一倍。
  • WAV格式大小:采样率一般是44.1K,16bit采样精度,存储成WAV格式大小 = 44.1KHz(采样率) X 16bit(采样位数) X 2(双声道) X  播放时间

  • WAV格式是没有压缩无损的,MP3格式是按1:12压缩保存的,所以MP3格式大小等于上式的1/12。

为什么还要用wav来做示例呢?这是因为WAV本质上是无压缩的原始音频文件,而且他的文件结构不算非常复杂,因此可以作为我们初学者的学习示例格式。

2. WAV的二进制格式解析

WAV文件格式分析:https://blog.csdn.net/zhihu008/article/details/7854529

  • 大部分的多媒体文件都依循着一种结构来存放信息,这种结构称为"资源互换文件格式"(Resources lnterchange File Format),简称RIFF。例如声音的WAV文件

  • RIFF:可以看做是一种树状结构,其基本构成单位为chunk,犹如树状结构中的节点,每个chunk由 "辨别码"、"数据大小"及"数据" 所组成。

2.1 WAV文件格式

  • WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是 "fmt" 和 "data",其中 "fmt" 子块由结构PcmWaveFormat所组成,其子块的大小就是sizeof(PcmWaveFormat),数据组成就是PcmWaveFormat结构中的数据。

图三、WAVE文件结构

typedef struct WAV_RIFF {
/* chunk "riff" */
char ChunkID[]; /* "RIFF" */
/* sub-chunk-size */
uint32_t ChunkSize; /* 36 + Subchunk2Size */
/* sub-chunk-data */
char Format[]; /* "WAVE" */
} RIFF_t; typedef struct WAV_FMT {
/* sub-chunk "fmt" */
char Subchunk1ID[]; /* "fmt " */
/* sub-chunk-size */
uint32_t Subchunk1Size; /* 16 for PCM */
/* sub-chunk-data */
uint16_t AudioFormat; /* PCM = 1*/
uint16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */
uint32_t SampleRate; /* 8000, 44100, etc. */
uint32_t ByteRate; /* = SampleRate * NumChannels * BitsPerSample/8 */
uint16_t BlockAlign; /* = NumChannels * BitsPerSample/8 */
uint16_t BitsPerSample; /* 8bits, 16bits, etc. */
} FMT_t; typedef struct WAV_data {
/* sub-chunk "data" */
char Subchunk2ID[]; /* "data" */
/* sub-chunk-size */
uint32_t Subchunk2Size; /* data size */
/* sub-chunk-data */
// Data_block_t block;
} Data_t; //typedef struct WAV_data_block {
//} Data_block_t; typedef struct WAV_fotmat {
RIFF_t riff;
FMT_t fmt;
Data_t data;
} Wav;
  • "data"子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于"fmt"子块中SubchunkID,  SubchunkSize ,AudioFormat 成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:

图四、WAVE文件数据采样格式

2.2 C语言解析wav文件

wave.h

//
// Created by douzi on 19-3-26.
// #ifndef RESOLVE_WAV_WAVE_H
#define RESOLVE_WAV_WAVE_H #include <cstdint> typedef struct WAV_RIFF {
/* chunk "riff" */
char ChunkID[]; /* "RIFF" */
/* sub-chunk-size */
uint32_t ChunkSize; /* 36 + Subchunk2Size */
/* sub-chunk-data */
char Format[]; /* "WAVE" */
} RIFF_t; typedef struct WAV_FMT {
/* sub-chunk "fmt" */
char Subchunk1ID[]; /* "fmt " */
/* sub-chunk-size */
uint32_t Subchunk1Size; /* 16 for PCM */
/* sub-chunk-data */
uint16_t AudioFormat; /* PCM = 1*/
uint16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */
uint32_t SampleRate; /* 8000, 44100, etc. */
uint32_t ByteRate; /* = SampleRate * NumChannels * BitsPerSample/8 */
uint16_t BlockAlign; /* = NumChannels * BitsPerSample/8 */
uint16_t BitsPerSample; /* 8bits, 16bits, etc. */
} FMT_t; typedef struct WAV_data {
/* sub-chunk "data" */
char Subchunk2ID[]; /* "data" */
/* sub-chunk-size */
uint32_t Subchunk2Size; /* data size */
/* sub-chunk-data */
// Data_block_t block;
} Data_t; //typedef struct WAV_data_block {
//} Data_block_t; typedef struct WAV_fotmat {
RIFF_t riff;
FMT_t fmt;
Data_t data;
} Wav; #endif //RESOLVE_WAV_WAVE_H
  • uint8_t:  unsigned char

  • uint16_t:unsigned short int

  • uint32_t:unsigned int

  • uint64_t: unsigned long int

wave.cpp

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "wave.h" int main()
{
FILE *fp = NULL; Wav wav;
RIFF_t riff;
FMT_t fmt;
Data_t data; fp = fopen("/home/douzi/Douzi_qdreamer/resolve_wav/mbfio_mic3.wav", "rb");
if (!fp) {
printf("can't open audio file\n");
exit();
} fread(&wav, , sizeof(wav), fp); riff = wav.riff;
fmt = wav.fmt;
data = wav.data; /**
* RIFF
*/
printf("ChunkID \t\t%c%c%c%c\n", riff.ChunkID[], riff.ChunkID[], riff.ChunkID[], riff.ChunkID[]);
printf("ChunkSize \t\t%d\n", riff.ChunkSize);
printf("Format \t\t\t%c%c%c%c\n", riff.Format[], riff.Format[], riff.Format[], riff.Format[]); printf("\n"); /**
* fmt
*/
printf("Subchunk1ID \t%c%c%c%c\n", fmt.Subchunk1ID[], fmt.Subchunk1ID[], fmt.Subchunk1ID[], fmt.Subchunk1ID[]);
printf("Subchunk1Size \t%d\n", fmt.Subchunk1Size);
printf("AudioFormat \t%d\n", fmt.AudioFormat);
printf("NumChannels \t%d\n", fmt.NumChannels);
printf("SampleRate \t\t%d\n", fmt.SampleRate);
printf("ByteRate \t\t%d\n", fmt.ByteRate);
printf("BlockAlign \t\t%d\n", fmt.BlockAlign);
printf("BitsPerSample \t%d\n", fmt.BitsPerSample); printf("\n"); /**
* data
*/
printf("blockID \t\t%c%c%c%c\n", data.Subchunk2ID[], data.Subchunk2ID[], data.Subchunk2ID[], data.Subchunk2ID[]);
printf("blockSize \t\t%d\n", data.Subchunk2Size); printf("\n"); // duration = Subchunk2Size / ByteRate
printf("duration \t\t%d\n", data.Subchunk2Size / fmt.ByteRate); }

3. WAV文件语音数据的组织结构

参考:https://www.cnblogs.com/ranson7zop/p/7657874.html

WAV文件的声音数据保存在数据块中。块标识符为“data”, 块长度值为声音数据的长度

从数据块的第9个字符开始是声音波形采样数据。每个样本按采样的时间先后顺序写入。样本的字节数取决于采样位数。对于多字节样本, 低位字节数据 放在低地址单元,相邻的高位字节数据放在高地址单元。多声道样本数据采用交替方式存储。例如: 立体声(双声道)采样值的存储顺序为:

  • 通道1第1采样值, 通道2第1采样值;通道1第2采样值, 通道2第2采样值;以此类推。基于PCM编码的样本数据排列方式。

(1)“52 49 46 46”这个是Ascii字符“RIFF”,这部分是固定格式,表明这是一个WAVE文件头。
(2)“22 60 28 00”,这个是我这个WAV文件的数据大小,这个大小包括除了前面4个字节的所有字节,也就等于文件总字节数减去8。16进制的“22 60 28 00”对应是十进制的“2646050”。
(3)“57 41 56 45 66 6D 74 20”,也是Ascii字符“WAVEfmt”,这部分是固定格式。
以后是PCMWAVEFORMAT部分

(4)“12 00 00 00”,这是一个DWORD,对应数字18,这个对应定义中的PCMWAVEFORMAT部分的大小,可以看到后面的这个段内容正好是18个字节。一般情况下大小为16,此时最后附加信息没有,上面这个文件多了两个字节的附加信息。
(5)“01 00”,这是一个WORD,对应定义为编码格式(WAVE_FORMAT_PCM格式一般用的是这个)。
(6)“01 00”,这是一个WORD,对应数字1,表示声道数为1,是个单声道Wav。
(7)“22 56 00 00”对应数字22050,代表的是采样频率22050,采样率(每秒样本数),表示每个通道的播放速度
(8)“44 AC 00 00”对应数字44100,代表的是每秒的数据量,波形音频数据传送速率,其值为:通道数×每秒样本数×每样本的数据位数/8(1*22050*16/8。播放软件利用此值可以估计缓冲区的大小。
(9)“02 00”对应数字是2,表示块对齐的内容。数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整。
(10)“10 00”数值为16,采样大小为16Bits,每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都一样。
(11)“00 00”此处为附加信息(可选),和(4)中的size对应。

(12)“66 61 73 74” Fact是可选字段,一般当wav文件由某些软件转化而成,则包含该项,“04 00 00 00”Fact字段的大小为4字节,“F8 2F 14 00”是fact数据。

(13)“64 61 74 61”,这个是Ascii字符“data”,标示头结束,开始数据区域。
(14)“F0 5F 28 00”十六进制数是“0x285ff0”,对应十进制2646000,是数据区的开头,以后数据总数,看一下前面正好可以看到,文件大小是2646050,从(2)到(13)包括(13)正好是2646050-2646000=50字节。

4. 总结

对WAV格式影响最大的参数是编码格式。采用不同的编码的WAV格式是不同的,PCM是最常见的编码格式,其它的为压缩编码格式,一般很少使用,有的已经废弃。随着人们认识的进步可能还会有新的编码格式出现。今后对WAV文件格式的更多的研究是压缩编码格式。

wav音频文件格式解析【个人笔记】(自用)的更多相关文章

  1. Windows Phone 8初学者开发—第20部分:录制Wav音频文件

    原文 Windows Phone 8初学者开发—第20部分:录制Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Develop ...

  2. RIFF和WAVE音频文件格式

    RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...

  3. 音频文件解析(一):WAV格式文件头部解析

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

  4. C语言解析WAV音频文件

    C语言解析WAV音频文件 代码地址: Github : https://github.com/CasterWx/c-wave-master 目录 前言 了解WAV音频文件 什么是二进制文件 WAV的二 ...

  5. 解析WAV音频文件----》生成WAV音频文件头

    前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i WAV音频文件介绍: WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows3.1操作系统 ...

  6. WAV文件格式解析及处理

    RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...

  7. WAVE文件格式解析

    WAVE 文件作为Windows多媒体中使用的声音波形文件格式之一,它是以RIFF(Resource Interchange File Format)格式为标准的.这里不针对RIFF文件格式做介绍,不 ...

  8. S3C2416裸机开发系列19_Fatfs播放录像wav音频文件

    S3C2416裸机开发系列19 Fatfs播放录像wav音频文件 国际象棋男孩    1048272975 多媒体资源,一般都是以文件的形式存储在固化存储器中.Fatfs所支持的fat32为windo ...

  9. 用 Qt 的 QAudioOutput 类播放 WAV 音频文件

    用 Qt 的 QAudioOutput 类播放 WAV 音频文件 最近有一个项目,需要同时控制 4 个声卡播放不同的声音,声音文件很简单就是没有任何压缩的 wav 文件. 如果只是播放 wav 文件, ...

随机推荐

  1. 【BZOJ3669】【NOI2014】魔法森林 LCT

    题目描述 给你一个\(n\)个点\(m\)条边的图,每条边有两个边权\(a,b\).请你找出从\(1\)到\(n\)一条路径,使得这条路径上边权\(a\)的最大值\(+\)边权\(b\)的最大值最小. ...

  2. IDEA修改module的名字

    首先右键module名,选择[Refactor]-[Rename...] 然后选择[Rename module] 只修改这些对于当前开发是没有问题了 但是刚开始把module添加成maven项目的时候 ...

  3. 在VS中安装nuget离线包nupkg文件

    1.下载 nupkg文件 2.打开VS,工具,选项,如下图,复制右侧圈圈地址,把下载文件复制丢进去 3.管理当前解决方案的nuget包 n 4.左侧选择你下载的包名,在右侧选择需要安装在哪一层项目,点 ...

  4. 【BZOJ 1701】Cow School(斜率优化/动态凸包/分治优化)

    原题题解和数据下载 Usaco2007 Jan 题意 小牛参加了n个测试,第i个测试满分是\(p_i\),它的得分是\(t_i\).老师去掉\(t_i/p_i\)最小的d个测试,将剩下的总得分/总满分 ...

  5. 【CodeForces 730H】Delete Them

    BUPT 2017 summer training (for 16) #1E 题意 找到匹配要删除的文件名们但不匹配其它文件名们的表达式.其中?匹配所有字符,其它字符匹配本身. 题解 如果某个位置出现 ...

  6. django从零开始-模型

    1.设置统计表 配置models.py from django.db import models # Create your models here. # 发布会 class Event(models ...

  7. 浏览器在DPI缩放时变化问题

    在高分辨笔记本电脑上,如果使用了"放大".那么原来在笔记本上很小的字和图就看起来大很多了.看起来舒服. 这个笔记本电脑是 1920 1080 装W10,系统推荐说125%佳.于是设 ...

  8. 外围功能电路控制 LET′S TRY“嵌入式编程”: 4 of 6

    外围功能电路控制 LET′S TRY“嵌入式编程”: 4 of 6 本连载讲解作为嵌入式系统开发技术人员所必需具备的单片机的基础知识. 在<单片机入门(1)-(3)>中,我们一起学习了单片 ...

  9. Centos 6.x/7.x yum安装php5.6.X

    鉴于Centos 默认yum源的php版本太低了,手动编译安装又有点一些麻烦,那么如何采用Yum安装的方案安装最新版呢.那么,今天我们就来学习下如何用yum安装php最新版. 1.检查当前安装的PHP ...

  10. 蓝桥杯 错误票据 (stringstream的使用)

    题目链接:http://lx.lanqiao.cn/problem.page?gpid=T28 问题描述 某涉密单位下发了某种票据,并要在年终全部收回. 每张票据有唯一的ID号.全年所有票据的ID号是 ...