PCM编码与Waveform音频文件(.wav)格式详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PCM编码与Waveform⾳频⽂件(.wav)格式详解 ⼤家好,我是痞⼦衡,是正经搞技术的痞⼦。

今天痞⼦衡给⼤家介绍的是PCM编码及Waveform⾳频⽂件格式。

嵌⼊式⾥有时候也会和⾳频打交道,⽐如最近特别⽕的智能⾳箱产品,离不开前端的⾳频
信号采集、降噪,中间的语⾳识别(ASR)、⾃然语⾔处理(NLP),以及后端的⽂语合成(TTS)、⾳频播放。

⾳频信号采集是处理声⾳的第⼀步,要采集⾳频就离不开PCM编码,⾳
频采集完成⾃然需要保存,waveform格式(.wav)是⼀种最经典的⾳频⽂件格式。

今天痞⼦衡
就给⼤家详细介绍PCM编码以及waveform⽂件格式。

⼀、声⾳基础
众所周知,声⾳是由物体振动产⽣的声波,声⾳通过介质(空⽓或固体、液体)传播并能
被⼈听觉器官所感知。

发⾳物体情况(材料,距离,振动强度等)不同,产⽣的声⾳也不同。

为了区分不同的声⾳,我们主要⽤如下三个参数来描述声⾳的特征:
⾳量:⼈主观上感觉到的声⾳⼤⼩(也叫响度),由“振幅”(amplitude)和⼈离声
源的距离决定。

⾳调:声⾳的⾼低(⾼⾳、低⾳),由“频率”(frequency)决定,频率越⾼⾳调越
⾼。

⾳⾊:⾳⾊是⼀种抽象的东西,波形决定了声⾳的⾳⾊。

声⾳因不同发声物体材料
⽽具有不同特性,波形是把这个抽象特性直观的表现出来。

典型的⾳⾊波形有⽅
波,锯齿波,正弦波,脉冲波等。

三⼤参数⾥除了⾳⾊没有度量单位外(可以认为⾳⾊是声⾳的UID,每种⾳⾊都是独⼀⽆⼆
的),⾳量和⾳调均有度量单位,这意味着⾳量和⾳调是可调整的,也是声⾳之间可对⽐的特
征参数。

1.1 ⾳量单位-分贝(dB)
声波是⼀种机械波(压⼒波)。

声波(空⽓质点)的连续振动,使空⽓分⼦不断交替的压
缩和松弛,使⼤⽓压迅速产⽣起伏,这种⽓压的起伏部分,就称为声压。

声压的振幅表⽰质点
离开平衡位置的距离,反映从波形波峰到波⾕的压⼒变化,以及波所携带的能量的多少。

声压值虽然可以反映⾳量⼤⼩,但⼈们⽇常⽣活中遇到的声⾳,若以声压值表⽰,变化范
围⾮常⼤(达到六个数量级以上),并且⼈体听觉对声信号强弱刺激反应不是线形的,⽽是成
对数⽐例关系。

因此⾳量并不是声压值来计量,⽽是⽤分贝来计量,⾸先来看分贝计算的标准
公式:
NdB = 10 * log10 (Pi / Po)
上述公式中P o为基准声压值,N dB即是声压信号P i对基准声压P o的分贝值。

从公式可以看出
分贝是指两个相同类型物理量(P i、P o)的⽐较结果,它是⽆量纲的。

分贝⼜称为被量度量
P i的'级',它代表被量度量⽐基准量⾼出多少'级'。

下⾯列举常见分贝值:
分贝值⼈⽿感觉
1dB刚能听到的声⾳
1 - 15dB感觉⾮常安静
20 - 40dB⽿语⾳,冰箱的嗡嗡声
40 - 60dB室内正常交谈的声⾳
60 - 70dB⾛在闹市区的感觉,有点吵
70 - 85dB汽车穿梭在马路上,85dB是保护听⼒的⼀般要求
85 - 100dB摩托车启动,装修电钻
100 - 150dB飞机起飞、燃放烟花爆⽵
1.2 ⾳调单位-频率(Hz)
频率是每秒经过⼀给定点的声波周期数量,其单位是Hz,1KHz表⽰每秒经过⼀给定点的声
波有1000个周期。

根据频率范围,我们将声波分为如下三种:
声波类

频率范围特性与应⽤
次声波低于20Hz部分动物(狗、⼤象)能发出/感知,常⽤于⾃然灾害监测
可闻声20Hz ~
20KHz⼈的听觉感知范围
超声波⾼于20KHz 部分动物(狗、蝙蝠)能发出/感知,常⽤于深海探测(声呐)、医学检查(B超)
关于声波频率特别要提的是,声波可以被分解为不同频率不同强度正弦波的叠加,这种变换(或分解)的过程,称为傅⽴叶变换(Fourier Transform)。

⼆、PCM编码原理
声波是⼀种在时间上和振幅上均连续的模拟量,在嵌⼊式⾥要想研究声波,⾸先需要将声波转换成⼀连串电压变化的模拟电信号,麦克风器件就是⼀种采集声波信号并将其转换成模拟电压信号输出的装置。

有了声波的模拟电压信号,下⼀步需要将模拟信号数字化,即将模拟信号经过模数转换器(A/D)后变成数字信号,说⽩了就是将声⾳数字化。

最常见的声⾳数字化⽅式就是脉冲编码调制PCM(Pulse Code Modulation),PCM是70年代末发展起来的技术,最早应⽤于由飞利浦和索尼公司共同推出的CD上,下图给出了PCM编码全过程:
从上图中我们可以看到PCM编码主要有三个过程:采样、量化、编码,在这过程中主要有4个参数⽤于评价PCM:声道数、采样率、量化位数、编码⽅式。

痞⼦衡会在下⾯逐⼀介绍PCM 编码过程时穿插介绍这4个参数:
2.1 采样
所谓采样,即按⼀定的采样频率将模拟信号变成时间轴上离散的抽样信号的过程。

原则上采样频率越⾼,声⾳的质量也就越好,声⾳的还原也就越真实。

采样率即每秒从模拟信号中提取并组成离散信号的采样个数,⽤赫兹(Hz)来表⽰。

说到采样率有⼀个不得不提的著名定律,即⾹农(Shannon)/奈奎斯特(Nyquist)采样定律,该定律表明采样频率必须⼤于或等于所传输的模拟信号的最⾼频率的2倍,才能不失真地恢复模拟信号。

最常说的“⽆损⾳频”,⼀般都是指传统CD格式中的44.1kHz/16bit的⽂件格式,⽽之
所以称为⽆损压缩,是因为其包含了20Hz-22.05kHz这个完全覆盖⼈⽿可闻范围的
声⾳频率⽽得名。

关于声道数,其实⾮常好理解,就是采集声⾳的通道数,我们知道有单声道(mono),⽴体声(双声道stereo)、杜⽐7.1环绕声,其实就是声⾳采集的通道数有差别,声道越多,越能体现声⾳的空间⽴体效果。

2.2 量化
前⾯采样得到的抽样信号虽然是时间轴上离散的信号,但仍然是模拟信号,其采样值在⼀定的取值范围内,可有⽆限多个值,必须采⽤“四舍五⼊”的⽅法把样值分级“取整”,使⼀定取值范围内的样值由⽆限多个值变为有限个值,这⼀过程称为量化。

量化位数指的是描述数字信号所使⽤的位数。

如麦克风采集的电压范围为0-3.3V,8bit的量化精度为3.3V/256,16bit的量化精度为3.3V/65536。

2.3 编码
量化后的抽样信号就转化为按抽样时序排列的⼀串⼗进制数字码流,即⼗进制数字信号。

简单⾼效的数据系统是⼆进制码系统,因此,应将⼗进制数字码变换成⼆进制编码,这种把量化的抽样信号变换成给定字长(量化位数)的⼆进制码流的过程称为编码。

编码⽅式种类⾮常多,其对⽐可见 Comparison of audio coding formats,PCM⾳频格式编码常见有四种:PCM(Linear PCM)、ADPCM(Adaptive differential PCM)、 A-law(A律13折线码)、µ-law(µ律15折线码),最简单的当然是下图所⽰的LPCM(⽰例为4bit),这是⼀种均匀量化编码,⼴泛⽤于 Audio CD, AES3, WAV, AIFF, AU, M2TS, VOB中。

除LPCM外,A-law和µ-law是两种不得不提的⾮均匀量化编码,这两种⾮均匀量化编码是为了提⾼⼩信号的信噪⽐,其基本思想是在量化之前先让信号经过⼀次处理,对⼤信号进⾏压缩⽽对⼩信号进⾏较⼤的放⼤,这⼀处理过程通常也称为“压缩量化”。

压缩量化的实质是“压⼤补⼩”,使⼩信号在整个动态范围内的信噪⽐基本⼀致。

下⾯是这两种编码与LPCM的对⽐图。

三、Waveform⽂件格式解析
前⾯讲的PCM编码后的声⾳数据是需要保存的,WAVE⽂件常常⽤来保存PCM编码数据。

WAVE⽂件是微软公司(Microsoft)开发的⼀种声⾳⽂件格式,⽤于保存Windows平台的⾳频信息资源,被Windows平台及其应⽤程序所⼴泛⽀持,WAVE⽂件默认打开⼯具是WINDOWS 的媒体播放器。

3.1 RIFF⽂件格式标准
WAVE⽂件是以微软RIFF格式为标准的,RIFF全称为资源互换⽂件格式(Resources Interchange File Format),是Windows下⼤部分多媒体⽂件遵循的⼀种⽂件结构。

RIFF⽂件所包含的数据类型由该⽂件的扩展名来标识,能以RIFF格式存储的数据有很多:⾳频视频交错格式数据(.AVI)、波形格式数据(.WAV)、位图数据格式(.RDI)、MIDI格式数据
(.RMI)、调⾊板格式(.PAL)、多媒体电影(.RMN)、动画光标(.ANI)等。

如下代码所⽰的CK结构体是RIFF⽂件的基本单元,该基本单元也称 Chunk。

其中ckID⽤于标识块中所包含的数据类型,其取值可有'RIFF'、'LIST'、'fmt '、'data'等;ckSize表⽰存储在ckData域中的数据长度(不包含ckID和ckSize的⼤⼩);ckData存储数据,数据以字节为单位存放,如果数据长度为奇数,则最后添加⼀个空字节。

由于RIFF⽂件结构最初是由Microsoft和IBM为PC机所定义,RIFF⽂件是按照⼩端
little-endian字节顺序写⼊的。

typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef DWORD FOURCC; // Four-character code
typedef struct {
FOURCC ckID; // The unique chunk identifier
DWORD ckSize; // The size of field <ckData>
BYTE ckData[ckSize]; // The actual data of the chunk
} CK;
Chunk是可以嵌套的,但是只有ckID为'RIFF'或者'LIST'的Chunk才能包含其他的Chunk。

标志为'RIFF'的Chunk是⽐较特殊的,每⼀个RIFF⽂件⾸先存放的必须是⼀个'RIFF' Chunk,并且只能有这⼀个标志为'RIFF'的Chunk。

更多RIFF的知识详见这个⽹站链接 RIFF (Resource Interchange File Format),链接⾥收集了很多介绍RIFF的资源。

3.2 WAVE⽂件结构
WAVE是Microsoft开发的⼀种⾳频⽂件格式,它符合上⾯提到的RIFF⽂件格式标准,可以看作是RIFF⽂件的⼀个具体实例。

既然WAVE符合RIFF规范,其基本的组成单元也是Chunk。

⼀个 WAVE⽂件通常有三个Chunk以及⼀个可选Chunk,其在⽂件中的排列⽅式依次是:RIFF Chunk,Format Chunk,Fact Chunk(附加块,可选),Data Chunk,如下图所⽰:
根据上⾯的WAVE⽂件结构图,可以定义如下44bytes的wave_head_t⽤来描述WAVE⽂件的头。

如果你曾经接触过Windows的⾳频接⼝API,你会发现wave_fmt_t中的部分结构与标准MSDN⾥的 WAVEFORMAT 是⼀致的。

typedef char int8_t; //有符号8位整数
typedef short int16_t; //有符号16位整数
typedef int int32_t; //有符号32位整数
struct _wave_tag{
int8_t riff[4]; //'RIFF',资源交换⽂件标志
int32_t filesize; //⽂件⼤⼩(从下个地址开始到⽂件尾的总字节数)
int8_t wave[4]; //'WAVE',⽂件标志
} wave_tag_t;
struct _wave_format{
int8_t fmt[4]; //'fmt ',波形格式标志
int32_t chunksize; //⽂件内部Chunk信息⼤⼩
int16_t wFormatTag; //⾳频数据编码⽅式
int16_t wChanles; //声道数
int32_t nSamplesPerSec; //采样率
int32_t nAvgBytesPerSec; //波形数据传输速率(每秒平均字节数)
int16_t nBlockAlign; //数据的调整数(按字节计算)
int16_t wBitsPerSample; //样本数据位数
} wave_fmt_t;
struct _wave_data{
int8_t data[4]; //'data',数据标志符
int32_t datasize; //采样数据总长度
} wave_dat_t;
struct _wave_head{
wave_tag_t waveTag;
wave_fmt_t waveFmt;
wave_dat_t waveDat;
} wave_head_t;
wave_head_t结构体内除了wFormatTag成员之外,其他都可以根据字⾯上的意思来理解。

关于wFormatTag的具体定义,可见Windows SDK⾥的 mmreg.h⽂件,下⾯列举了⼏个最常见Format的Tag值定义:
当WAVE⽂件的头被解析成功后,下⼀步便是获取WAVE⽂件⾥的声⾳源数据,我们知道声⾳⽂件有单声道和多声道之分,对于单声道⽂件很好理解,声⾳数据就是按序排放,⽽如果是⽴体声(2声道)⽂件,那么左右声道的声⾳数据到底是怎么排放的呢?下⾯以⼀个⽰例⽴体声⽂件数据(仅分析前72bytes)进⾏解释:
offset(h)
00000000: 52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20
00000010: 10 00 00 00 01 00 02 00 22 56 00 00 88 58 01 00
00000020: 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00
00000030: 24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6
00000040: 3c f2 24 f2 11 ce 1a 0d
下图是这个72bytes数据解析图,从图中可以看到,左右声道的声⾳数据是按块(nBlockAlign指定)交替排放的。

更多WAVE的知识详见这两个⽹站链接 WAVE Audio File Format 和 Audio File Format Specifications,链接⾥收集了很多介绍WAVE的资源。

3.3 WAVE⽂件实例分析
WAVE⽂件格式我们都了解透彻了,下⾯我们尝试分析⼀个经典的WAVE⽂件:'Windows XP 启动.wav',这个⽂件可以说是最知名的WAVE⽂件了,痞⼦衡特别喜欢这段music,让我们直接⽤⼆进制编辑器HxD打开它:
按wave_head_t解析WAVE头可知,这段wave是44.1kHz/16bit双声道线性PCM码⾳频,实际⾳频数据总长度为
1361076bytes(1361076(datasize)/176400(nAvgBytesPerSec)=7.7158秒),最后再⽤Adobe Audition(原Cool Edit)打开查看其波形图:
⾄此,PCM编码及Waveform⾳频⽂件格式痞⼦衡便介绍完毕了,掌声在哪⾥~~~。

相关文档
最新文档