怎样用python画wav文件的时频分析图

Python017

怎样用python画wav文件的时频分析图,第1张

这是python的matplotlib里的一个画wav文件的时频分析(specgram)的函数。和matlab里的那个差不多。使用超级方便,自动就做好了短时傅立叶变换(short

time fourier

transform)~函数用法具体可参照http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.specgram

关于短时傅立叶变换的具体内容可google之~下面介绍程序。

#首先import各种library。wave和struct都是安装python2.6自带的。scipy可以在

#http://www.scipy.org/Download下载。pylab可在http://matplotlib.sourceforge.net/下载。都是非常#强大的包包啊~~

import wave

import struct

from scipy import *

from pylab import *

#读取wav文件,我这儿读了个自己用python写的音阶的wav

filename = '/Users/rongjin/Desktop/scale.wav'

wavefile = wave.open(filename, 'r') # open for writing

#读取wav文件的四种信息的函数。期中numframes表示一共读取了几个frames,在后面要用到滴。

nchannels = wavefile.getnchannels()

sample_width = wavefile.getsampwidth()

framerate = wavefile.getframerate()

numframes = wavefile.getnframes()

#建一个y的数列,用来保存后面读的每个frame的amplitude。

y = zeros(numframes)

#for循环,readframe(1)每次读一个frame,取其前两位,是左声道的信息。右声道就是后两位啦。

#unpack是struct里的一个函数,用法详见http://docs.python.org/library/struct.html。简单说来

就是把#packed的string转换成原来的数据,无论是什么样的数据都返回一个tuple。这里返回的是长度为一的一个

#tuple,所以我们取它的第零位。

for i in range(numframes):

val =

wavefile.readframes(1)

left =

val[0:2]

#right = val[2:4]

v =

struct.unpack('h', left )[0]

y[i] =

v

#framerate就是44100,文件初读取的值。然后本程序最关键的一步!specgram!实在太简单了。。。

Fs = framerate

specgram(y, NFFT=1024, Fs=Fs, noverlap=900)

show()

耶~好看的specgram就画好了~~x轴是时间,y轴是频率~

1.读取wav文件

# -*- coding: utf-8 -*-

import wave

import pylab as pl

import numpy as np

# 打开WAV文档

f = wave.open(r"c:\WINDOWS\Media\ding.wav", "rb")

# 读取格式信息

# (nchannels, sampwidth, framerate, nframes, comptype, compname)

params = f.getparams()

nchannels, sampwidth, framerate, nframes = params[:4]

# 读取波形数据

str_data = f.readframes(nframes)

f.close()

#将波形数据转换为数组

wave_data = np.fromstring(str_data, dtype=np.short)

wave_data.shape = -1, 2

wave_data = wave_data.T

time = np.arange(0, nframes) * (1.0 / framerate)

# 绘制波形

pl.subplot(211)

pl.plot(time, wave_data[0])

pl.subplot(212)

pl.plot(time, wave_data[1], c="g")

pl.xlabel("time (seconds)")

pl.show()

2.观察信号频谱

# -*- coding: utf-8 -*-

import numpy as np

import pylab as pl

sampling_rate = 8000

fft_size = 512

t = np.arange(0, 1.0, 1.0/sampling_rate)

x = np.sin(2*np.pi*156.25*t) + 2*np.sin(2*np.pi*234.375*t)

xs = x[:fft_size]

xf = np.fft.rfft(xs)/fft_size

freqs = np.linspace(0, sampling_rate/2, fft_size/2+1)

xfp = 20*np.log10(np.clip(np.abs(xf), 1e-20, 1e100))

pl.figure(figsize=(8,4))

pl.subplot(211)

pl.plot(t[:fft_size], xs)

pl.xlabel(u"时间(秒)")

pl.title(u"156.25Hz和234.375Hz的波形和频谱")

pl.subplot(212)

pl.plot(freqs, xfp)

pl.xlabel(u"频率(Hz)")

pl.subplots_adjust(hspace=0.4)

pl.show()