用python的pylab画wave波形之sampwidth问题
问题
网上找了好多地方,核心代码都是类似的,效果也还行。
wavedata=np.fromstring(bindata,dtype=np.short)
可是不小心加载了一个Office里的音效文件,波形完全不对,接近方波了,都是大起大落的数据。
再看波形参数是这样:
_wave_params(nchannels=1, sampwidth=1, framerate=11025, nframes=5480……)
原来它的取样量化宽度(sampwidth)只是1字节,无脑使用numpy.short明显不对,byte/int8也不行。
加载到音频处理软件显示为无符号8位,对于它来说,uint8才是正解。
另外,画图中也遇到了子图分块、颜色,总图标题及窗口标题的问题。
综合其它搜索结果及自行尝试,尤其是参考了这篇博文,画图参数很详细!
解决方法
最终还是写了如下的简单的代码,自动处理量化宽度、标题、声道个数与波形子图数目等相关事项。
# -*- coding: utf-8 -*-
import wave
import numpy as np
import pylab as pl
#fPath=r"C:\Program Files\Microsoft Office\root\Office16\MEDIA\CAMERA.WAV"
fPath=r"C:\Windows\Media\Alarm04.wav"
f=wave.open(fPath,"rb")
para=f.getparams()
bindata=f.readframes(para.nframes)
f.close()
#按量化位数定数据类型,不能全short,int16
#int0纯属占位,24位量化无法直接处理,无numpy.int24,需自定义
dtypes=[np.int0,np.uint8,np.int16]
#.fromstring()已经过时,不建议使用
wavedata=np.frombuffer(bindata,dtype=dtypes[para.sampwidth])
wavedata.shape = -1,para.nchannels
time=np.arange(0,para.nframes)*(1.0/para.framerate) #转为秒
pColors="bgrcmykw"
wTitle="Wave forms"
pl.figure(wTitle) #窗口自定义初始化,如标题等
#图,总标题,加上文件名,非Windows需修改分隔符
pl.suptitle(wTitle+" of " + fPath.split('\\')[-1])
for i in range(para.nchannels):
pl.subplot(para.nchannels*100+10+i+1)
pl.plot(time,wavedata[:,i],pColors[i])
pl.xlabel("Time(seconds)")
pl.show()