标签:mst type 变形 numpy 不能 创建 sub dia str
#本文PDF版下载
#本文代码下载
#本文实例音频文件night.wav下载
音频文件下载 (石进-夜的钢琴曲)
在现在繁忙的生活中,我们经常会听些歌来放松一下自己,我们经常会从各种播放软件中听自己喜欢的歌,并且往往我们会下载一部分歌曲,而现在音频的种类也相当繁多,像是Wav,Mp3,FLAC,AAC等等很多格式,最近由于需要做一个能够分析Wav格式音频的波形来取得一些数据比如获取人录音时是否说完等等用途.本周先对解析Wav并用Python绘制其波形进行了一些探索.
我们先来看看wikipedia上对于wav音频格式的解释:
「Waveform Audio File Format(WAVE,又或者是因为扩展名而被大众所知的WAV),是微软与IBM公司所开发在个人电脑存储音频流的编码格式,在Windows平台的应用软件受到广泛的支持,地位上类似于麦金塔电脑里的AIFF.此格式属于资源交换档案格式(RIFF)的应用之一,通常会将采用脉冲编码调制的音频资存储在区块中。也是其音乐发烧友中常用的指定规格之一.由于此音频格式未经过压缩,所以在音质方面不会出现失真的情况,但档案的体积因而在众多音频格式中较为大.」
我们可以看到上面提到了两个个关键词RIFF和脉冲编码调制.所以我们接下来先解释一下 RIFF「资源交换档案格式」是什么.
我们同样的来看一下wikipedia对RIFF的解释
「 Resource Interchange File Format(简称RIFF),资源交换文件格式,是一种按照标记区块存储数据(tagged chunks)的通用文件存储格式,多用于存储音频、视频等多媒体数据.Microsoft在windows下的AVI、ANI 、WAV等都是基于RIFF实现的.
RIFF是由Microsoft和IBM于1991年,在windows 3.1中引入的,作为windows 3.1默认的多媒体文件格式。RIFF是参考Interchange File Format来的,二者主要的区别是字节序大端、小端的问题.在基于IBM的80x86系列主机下,RIFF的字节序是小端的;而在IFF原有的格式中是按照大端存储整型数据的.」
RIFF是由chunk构成的,chunk是RIFF组成的基本单位,每个CHUNK可看作存贮了视频的一帧数据或者是音频的一帧数据,所以下面我们来讨论一下chunk的结构是怎么样的.
CHUNK总共由三个部分组成:
结构示意图如下:
CHUNK的结构
下面是一个包含了子CHUNK的结构示意图:
包含了SUBCHUNK的结构示意图
Form Type结构示意图如下:
包含了Form Type的结构示意图
我们先来看看百度百科对它的解释:
「PCM 脉冲编码调制是Pulse Code Modulation的缩写,脉冲编码调制是数字通信的编码方式之一.主要过程是将话音、图像等模拟信号每隔一定时间进行取样,使其离散化,同时将抽样值按分层单位四舍五入取整量化,同时将抽样值按一组二进制码来表示抽样脉冲的幅值.」
我们从上面的介绍可以理解为:
通过三个过程-抽样、量化和编码讲音频的模拟信号转化为数字信号.
抽样是由于模拟信号是连续的,通过一定频率对模拟信号进行取样,近似得到,如下面的图中灰色框中就是取了一定频率进行抽样的示意图:
抽样过程示意图
抽样信号离散的模拟信号,其取样的值在一定的取值范围内,由无限多种值可能性存在.为了实现以数字码表示样值,我们采用“四舍五入”的方法把样值分级“取整”,使一定取值范围内的样值由无限多个值变为有限个值.
量化后的抽样信号在一定的取值范围内仅有有限个可取的样值,且信号正、负幅度分布的对称性使正、负样值的个数相等,正、负向的量化级对称分布
WAVE文件是由若干个CHUNK组成的.按照文件中CHUNK的出现顺序分别为:RIFF Chunk, Format Chunk, Fact Chunk, Data Chunk,其中的Fact CHUNK为非必要部分,结构具体如下图所示:
WAV文件头文件的CHUNK组成
RIFF是头CHUNK,而Format CHUNK里面记录了WAV的各种参数信息,详细参数信息如下:
而FACT CHUNK的作用是因为有些并没有使用PCM格式,所以需要一个FACT CHUNK记录数据解压缩数据大小.
最后的DATA块中装的是真正的声音数据.一般按照WAVE_FORMAT_PCM的数据格式存贮,即脉冲编码调制PCM.
DATA块内的信息是根据format chunk内的信息而决定的.由量化位数/声道数/采样率共同决定,下图为四种情况下DATA区域存储信息的格式:
DATA CHUNK的格式
在python中,我们可以直接通过许多音频的库对wav文件进行操作,比如自带的标准库wave库,还有如eyeD3,PyAudio,Audacity等等.我们先不介绍这种方式,我们先通过传统的文件操作以二进制的形式读取Wav文件,来分析一下它的头文件来验证一下我们前面有关CHUNK所学的知识.通过二进制操作音频文件并取得前四个字节的代码如下:(我们的测试音频是night.wav,已放在github中,通过我的博客园右上角的绿色图标可以链接到我的github界面,找到lab102下的w8目录即可获取该资源,或者找到本文博客园最上方资源):
#读取wav前四个字节内容 -xlxw
file = open("night.wav", "rb")
s = file.read(4)
print(s)
程序运行截图:
我们可以看到最前面的字节和我们认为的没错,是RIFF,那我们来读取44个字节来看看其中的信息是怎么样的:
#读取wav前44个字节内容 -xlxw
file = open("night.wav", "rb")
s = file.read(44)
print(s)
程序运行截图:
我们可以看到RIFF后面的字符串为WAVE的Form Type,以及fmt,data这几个FOURCC,而其他用十六进制表示的就是数据大小/数据了.所以我们通过二进制读取的WAV文件的信息和我们前面学习的CHUNK中的内容是一致的.
在我们前面中的介绍可以知道wav文件的存储方式,并且能够简单的提取其中的信息了,而我们知道wav文件最重要的就是声音信息的存贮,这一部分我们也可以通过对CHUNK的DATA 进行分析,不过我们在python中有更加简单的获得声音的方式,那就是利用python自带的wave库,我们下面就来介绍一下wave库的一些方法,为后文做铺垫.
import wave
打开一个声音文件,使用方法wave.open(声音文件地址,模式)
其中声音文件地址就是wav文件位置,模式和文件读写差不多,如“wb”-只写;“rb”-只读方式 b代表以二进制模式打开.
关闭声音文件
获取wav文件的参数(以tuple形式输出),依次为(声道数,采样精度,采样率,帧数,......)
如下图为本文例子night.wav的getparams()的信息:
得到每一帧的声音数据,返回的值是二进制数据,在python中用字符串表示二进制数据,如下图,所以我们后面要进行转化.
得到的night.wav的前10帧的数据如下图所示:
上面就基本上是wave库的常用方法了.下面会对此进行应用了.
我们经常在许多声音软件,比如CoolEdit,Audition等软件中能看到声音文件的波形,所以我们在这里利用Python以及前面介绍的wave库,辅以numpy,Matplotlib来尝试绘制night.wav文件的波形.
下面我们来简单讲述一下绘制波形的步骤:(以night.wav为例子)
我们来对这些步骤中的一些部分详细说一下:
因为night.wav是一个双声道的WAV 文件,我们从上文对DATA区域格式的介绍可以知道储存形式是左声道/右声道的形式存贮数据,所以在这里我们要对提取出的数据进行处理,这里numpy库为我们提供了很好的解决方法,我们主要用到了改变形状的Shape方法以及T转置方法,我们在这里来举一个例子:
我们创建一个数组[1,2,3,4,5,6,7,8]里面有8个元素,这时候根据我们的分离方法,应该分为左声道[1,3,5,7]和右[2,4,6,8],我们可以通过shape先改变矩阵的形状使数据变为两列分别为左右声道,再通过转置得到最终数据,我们的例子可以用如下图所示理解:
将数据分为左右声道的例子
这里我们要绘出波形,所以用matplotlib库大大减少我们的绘图难度,我们主要用到plt.subplot和plt.plot这两个方法,所以我们对这两个方法进行解释.
这是用于matplotlib绘制多个子图的方法,因为我们这里音频文件要分为两个部分(左声道/右声道)
即分成2X1的形式,所以我们的第一个绘图和第二个绘图分别用
plt.subplot(211)和plt.subplot(212)来表示,如下图所示:
matplotlib子图
plt.plot()是用于绘制线条的方法,我们用到了其中的三个参数
(X坐标,y坐标,颜色)
就能用plot画出最终的波形图了
用于绘制出wav文件波形的代码如下(这里我们还是以night.wav作为例子)
#wave data -xlxw
#import
import wave as we
import numpy as np
import matplotlib.pyplot as plt
def wavread(path):
wavfile = we.open(path,"rb")
params = wavfile.getparams()
framesra,frameswav= params[2],params[3]
datawav = wavfile.readframes(frameswav)
wavfile.close()
datause = np.fromstring(datawav,dtype = np.short)
datause.shape = -1,2
datause = datause.T
time = np.arange(0, frameswav) * (1.0/framesra)
return datause,time
def main():
path = input("The Path is:")
wavdata,wavtime = wavread(path)
plt.title("Night.wav‘s Frames")
plt.subplot(211)
plt.plot(wavtime, wavdata[0],color = ‘green‘)
plt.subplot(212)
plt.plot(wavtime, wavdata[1])
plt.show()
main()
程序绘制出的波形图的截图:
night.wav声音文件的双声道波形
在本周我学到了wav文件的存贮格式以及怎么用python读取wav文件信息并且绘制出波形图.其中在绘制了波形图后,我们可以对波形多透露出的信息进行分析,比如:
等等用途,可以用于许多方面,如声音识别,断句(音频分割)等等许多的场景.这里在以后我也会继续进行探索.
标签:mst type 变形 numpy 不能 创建 sub dia str
原文地址:http://www.cnblogs.com/lzxwalex/p/6922099.html