我们经常需要处理wav格式的文件,读取其中的声音信号和相关参数,来做一些事情。如果我们使用C++来做,那么需要对文件的底层存储格式有一个透彻的了解才行,而且考虑不周还有可能出Bug;如果使用MatLab来做,虽然只有一行代码就可以读取文件,但是MatLab语言自身的局限性使得写出的代码难以在实际中投入使用。因此,兼顾简介易用和实用性,用Python来做就显得比较好了。
首先,自然地,我们需要导入Python包:
import wave
这个Pyhton包提供了一个方便的WAV格式文件读写的接口。
它支持单声道与立体声,但是不支持压缩和解压缩。
wave类的方法函数:
open(file, [mode])
打开一个wave文件流对象,返回该对象。
参数:
file: 如果file是一个字符串,那么就打开文件,否则就把它当做一个类文件对象。
mode: 可缺省,如果输入的参数是一个类文件对象,那么file.mode将会作为mode的值。
mode可选参数如下:
只读模式: ‘r’, ‘rb’
只写模式: ‘w’, ‘wb’
注意:不能同时完成读/写操作
close()
关闭该流,使得该实例不可用,它会自动调用对象收集机制。
getnchannels()
返回音频的声道数(1是单声道,2是立体声)。
getsampwidth()
返回该实例每一帧的字节宽度。
getframerate()
返回实例的频率(单位:Hz)。
getnframes()
返回音频的帧数。
getcomtype()
返回压缩类型(仅支持’NONE’)。
getcompname()
是getcomtype()的人类可读的版本,通常用’not compressed’表示’NONE’。
getparams()
返回一个元组tuple (nchannels, sampwidth, framerate, nframes, comptype, compname),包含了以上的方法取得的几个值。
readframes(n)
从流的当前指针位置一次读出音频的n个帧,并且指针后移n个帧,返回一个字节数组。
rewind()
倒带,将该文件指针指向音频流的最开始位置。
其次,我们需要使用numpy中的shape来改变数组的形状,主要是为了解决立体声即双轨声道时候的信号能量表示问题。
import numpy as np arr = np.array([[1,2,3],[4,5,6]]) arr.shape = 3,2
可以将原为2*3的数组(矩阵)转为3*2数组(矩阵)。当某数轴的参数为-1时,可根据元素个数,自动计算另一轴的最大长度。
实例代码:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- def read_wav_data(filename): ''' 读取一个wav文件,返回声音信号的时域谱矩阵和播放时间 ''' wav = wave.open(filename,"rb") # 打开一个wav格式的声音文件流 num_frame = wav.getnframes() # 获取帧数 num_channel=wav.getnchannels() # 获取声道数 framerate=wav.getframerate() # 获取帧速率 num_sample_width=wav.getsampwidth() # 获取实例的比特宽度,即每一帧的字节数 str_data = wav.readframes(num_frame) # 读取全部的帧 wav.close() # 关闭流 wave_data = np.fromstring(str_data, dtype = np.short) # 将声音文件数据转换为数组矩阵形式 wave_data.shape = -1, num_channel # 按照声道数将数组整形,单声道时候是一列数组,双声道时候是两列的矩阵 wave_data = wave_data.T # 将矩阵转置 wave_data = wave_data return wave_data, framerate def wav_show(wave_data, fs): # 显示出来声音波形 time = np.arange(0, len(wave_data)) * (1.0/fs) # 计算声音的播放时间,单位为秒 # 画声音波形 plt.plot(time, wave_data) plt.show() if(__name__=='__main__'): wave_data, fs = read_wav_data("1.wav") wav_show(wave_data[0],fs) wav_show(wave_data[1],fs) # 如果是双声道则保留这一行,否则删掉这一行
版权声明本博客的文章除特别说明外均为原创,本人版权所有。欢迎转载,转载请注明作者及来源链接,谢谢。本文地址: https://blog.ailemon.net/2017/08/29/python-read-wav-files/ All articles are under Attribution-NonCommercial-ShareAlike 4.0 |