wav文件格式作为一种常用的多媒体音频文件格式,其由MS在1991年8月在Windows 3.1上推出,文件扩展名为WAV,是WaveFom的简写。通常存储未压缩的pcm数据,也可存储压缩的pcm数据(G711a/u, G726, ADPCM)。WAV文件格式简称WAV格式,是一种存储声音波形的数字音频格式,是由微软公司和IBM联合设计的,经过了多次修订,可用于Windows,Macintosh,Linix等多种操作系统,详述如下。

波形文件的基础知识

1.1 波形文件的存储过程

声源发出的声波通过话筒被转换成连续变化的电信号,经过放大、抗混叠滤波后,按固定的频率进行采样,每个样本是在一个采样周期内检测到的电信号幅度值;接下来将其由模拟电信号量化为由二进制数值;最后编码并存储为音频流数据。有的应用为了节省存储空间,存储前,还要对采样数据先进行压缩(G711/G726)。其过程如下:

采样->模拟信号->量化->压缩->存储。

1.2 WAV文件的编码

编码包括了两方面内容:一是按一定格式存储数据;二是采用一定的算法压缩数据。WAV格式对音频流的编码没有硬性规定,既支持非压缩的PCM(Puls Code Modulation)脉冲编码调制格式,又支持压缩型的数据,如微软自适应分脉冲编码调制Microsoft ADPCM(Adaptive Differential Puls Code Modulation)、国际电报联盟(International Telegraph Union)制定的语音压缩标准ITUG.711 a-law、ITU G.711 u-law、IMA ADPCM和其它压缩算法。

1.3 WAV文件存储格式

封装格式主要包括三部分:"RIFF" chunk, "fmt " sub-chunk, "data" sub-chunk。

每个chunk的格式如下:

块标识 4Bytes "RIFF"/"fmt "/"data"
块长度 4Bytes 接下来“数据”到文件尾的size
数据 X Bytes 具体内容

其中,对“块长度”进行详细解释,其大小为从接下来“数据”部分开始,一直到文件尾结束,其以字节为单位的大小。但是,"fmt " sub-chunk则有些特别。

例如,"RIFF" chunk,其“块长度”=file_size - 8Bytes,因为要排除“块标识”+本“块长度”的8Bytes。

"fmt " sub-chunk(注意t后面有个空格,必须由4Bytes组成),其大小为该sub-chunk的大小=16Bytes。

"data" sub-chunk,其大小为接下来“数据”部分的size,即pcm数据的大小=file_size - 44Bytes(wav头大小)。

1.4 WAV文件实例分析

通过winhex查看二进制数据如下:

PCM基础知识

(1)采样频率(sample rate):又称取样频率。是单位时间内的采样次数(一秒钟采样多少次信号),决定了数字化音频的质量。采样频率越高,数字化音频的质量越好、声音越真实,当然所占的资源、存储空间也越多。根据奎特采样定理,要从采样中完全恢复原始信号的波形,采样频率要高于声音中最高频率的两倍。人耳可听到的声音的频率范围是在16Hz-20kHz之间。因此,要将听到的原声音真实地还原出来,采样频率必须大于4 0k H z 。常用的采样频率有8 k H z 、1 1 . 02 5 k H z 、22.05kHz、44.1kHz、48kHz等几种。22.05KHz相当于普通FM广播的音质,44.1KHz理论上可达到CD的音质。对于高于48KHz的采样频率人耳很难分辨,没有实际意义。录像设备采集人声时,通常用16kHz采样,使用8kHz的则声音回放时有些闷,使用16k以上时跟16k的分不出区别。而专业录音棚中录制时,则通常使用44.1k/48k/96k的采样率,因为不仅要采集人声,还要采集乐器声。

(2)采样位数(bit width):也叫量化位数(单位:比特),是存储每个采样值所用的二进制位数。采样值反应了声音的波动状态。采样位数决定了量化精度。采样位数越长,量化的精度就越高,还原的波形曲线越真实,产生的量化噪声越小,回放的效果就越逼真。常用的量化位数有4、8、12、16、24。量化位数与声卡的位数和编码有关。如果采用PCM编码时使用16位声卡,可将音频信号幅度划分成了64K个音量等级,取值范围为-32768至32767。网络上音频文件基本上都是16位采样精度。

(3)声道数(channel count):是使用的声音通道的个数,也是采样时所产生的声音波形的个数。我们通常接触到的是单声道(mono)和立体声(stereo)。立体声在采集时,使用两个mic,两个mic处于不同的位置,其采集时所量化到的二进制值有些差别,因此在回放时会感觉到两个耳朵里信号有些差异,给人以立体感。

WAV实例练习

为了学习wav封装格式,特写了一个工具,用于读取/写wav文件,检查sample_rate/channel_cnt/duration。已上传GitHub:https://github.com/Dreaming-in-Gottingen/AudioTools

wav_utils文件生成libwav_ops.so库文件,tests用于测试libwav_ops.so中对wav读/写的实现,CStdWavGenerator用于生成标准的音频文件(如正弦波,方波,三角波)。

码了这么多字,实在太费时间了,朋友们可以下载下来测试一下。有问题,欢迎留言。

以后有时间了,再整一篇文章介绍一下关于pcm增益、采样率、频率等问题。

wav封装格式的更多相关文章

  1. iOS音频学习笔记一:常见音频封装格式及编码格式

    (1) pcm格式    pcm是经过话筒录音后直接得到的未经压缩的数据流    数据大小=采样频率*采样位数*声道*秒数/8     采样频率一般是22k或者44k,位数一般是8位或者16位,声道一 ...

  2. FLV封装格式及分析器工具

    http://blog.csdn.net/leixiaohua1020/article/details/17934487 FLV封装原理 FLV格式的封装原理,贴上来辅助学习之用.     FLV(F ...

  3. 最简单的基于FFMPEG的封装格式转换器(无编解码)

    本文介绍一个基于FFMPEG的封装格式转换器.所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(相应.avi,.flv,.mkv,.mp4文件).须要注意的是,本程序并不进行视 ...

  4. 【视频编解码·学习笔记】4. H.264的码流封装格式

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  5. 最简单的基于FFmpeg的封装格式处理:视音频复用器(muxer)

    ===================================================== 最简单的基于FFmpeg的封装格式处理系列文章列表: 最简单的基于FFmpeg的封装格式处理 ...

  6. 最简单的基于FFmpeg的封装格式处理:视音频分离器(demuxer)

    ===================================================== 最简单的基于FFmpeg的封装格式处理系列文章列表: 最简单的基于FFmpeg的封装格式处理 ...

  7. 最简单的基于FFmpeg的封装格式处理:视音频分离器简化版(demuxer-simple)

    ===================================================== 最简单的基于FFmpeg的封装格式处理系列文章列表: 最简单的基于FFmpeg的封装格式处理 ...

  8. 视音频编解码学习工程:TS封装格式分析器

    =====================================================视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习工 ...

  9. 视音频编解码学习工程:FLV封装格式分析器

    ===================================================== 视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习 ...

随机推荐

  1. c语言进阶12-线性表之顺序表

    一.  线性表的定义 为什么要学习线性表呢? 因为我们日常生活中存在种数据关系,计算机程序是为了解决日常生活的数据关系,因此我们要学习线性表. 线性表是什么呢? 线性表是由n个元素组成的有限序列. 需 ...

  2. c语言进阶8-数据结构

    一.  数据结构的起源: 1.        为什么要学习数据结构 阿基米德说过:“给我一个支点,我就能翘起地球”.那么给我一个程序,我就能用好程序,给我一个结构,我就能把内容填充完成.打个比方,一个 ...

  3. 使用canvas来完成线性渐变和径向渐变的功能

    fillStyle的第二种使用情况就是渐变色的填充.渐变色就分为线性渐变色和径向渐变色.   线性渐变:大致分为两步 这里又会使用到canvas的两个新的函数.   第一步 : 使用一个新的函数cre ...

  4. 【git】15分钟学会使用Git和远程代码库

    Git是个了不起但却复杂的源代码管理系统.它能支持复杂的任务,却因此经常被认为太过复杂而不适用于简单的日常工作.让我们诚实一记吧:Git是复杂的,我们不要装作它不是.但我仍然会试图教会你用(我的)基本 ...

  5. 【TensorFlow 1】操作变量

    打印 在tf中直接打印只是输出变量格式,如: #代码 data1 = tf.constant(2,dtype=tf.int32) #浮点数据 data2 = tf.Variable(10,name=' ...

  6. 私有网络(VPC)概述

    1 什么是私有网络(VPC) 私有网络是一块可用户自定义的网络空间,您可以在私有网络内部署云主机.负载均衡.数据库.Nosql快存储等云服务资源.您可自由划分网段.制定路由策略.私有网络可以配置公网网 ...

  7. PageHelper分页实战(SSM整合)

    步骤一:引入SSM相关的jar包,包列表如下: 步骤二:创建或修改配置文件,配置文件清单如下: applicationContext.xml <?xml version="1.0&qu ...

  8. SQL语句中的as

  9. Drools规则引擎-如果判断某个对象中的集合是否包含指定的值

    规则引擎集合相关处理 在实际生产过程中,有很多关于集合的处理场景,比如一个Fact对象中包含有一个集合,而需要判断该集合是否包含某个值.而Drools规则引擎也提供了多种处理方式,比如通过from.c ...

  10. 【Android Studio】查看源码时提示“throw new RuntimeException("Stub!")”

    如题-- 详细问题及解决方法: http://blog.csdn.net/u010917495/article/details/51234179