python读取wav文件并进行FFT变换

一、wav格式文件

WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,该格式也支持MSADPCM,CCITT A LAW等多种压缩运算法,支持多种音频数字,取样频率和声道,标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在声音文件质量和CD相差无几! WAV打开工具是WINDOWS的媒体播放器。
  通常使用三个参数来表示声音,量化位数,取样频率和采样点振幅。量化位数分为8位,16位,24位三种,声道有单声道和立体声之分,单声道振幅数据为n1矩阵点,立体声为n2矩阵点,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种,不过尽管音质出色,但在压缩后的文件体积过大!相对其他音频格式而言是一个缺点,其文件大小的计算方式为:WAV格式文件所占容量(B) = (取样频率 X量化位数X 声道) X 时间 / 8 (字节= 8bit) 每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化。
  WAV是最接近无损的音乐格式,所以文件大小相对也比较大。

二、python代码

import wave
from scipy.fftpack import fft,ifft
import matplotlib.pyplot as plt
import numpy as np

def wave_read(path):
    '''#打开wav文件 ,open返回一个的是一个Wave_read类的实例,
    通过调用它的方法读取WAV文件的格式和数据'''
    f=wave.open(path,"rb")
    #一次性返回所有的WAV文件的格式信息,它返回的是一个组元(tuple):声道数, 量化位数(byte单位),
    # 采
    # 样频率, 采样点数, 压缩类型, 压缩类型的描述。wave模块只支持非压缩的数据,因此可以忽略最后两个信息'''
    params=f.getparams()
    # 读取波形数据
    nchannels, sampwidth, framerate, nframes=params[:4]
    # 读取声音数据,传递一个参数指定需要读取的长度(以取样点为单位)
    str_date=f.readframes(nframes)
    f.close()
    # 需要根据声道数和量化单位,将读取的二进制数据转换为一个可以计算的数组
    wave_date=np.frombuffer(str_date,dtype=np.short)
    # 将wave_data数组改为2列,行数自动匹配。在修改shape的属性时,需使得数组的总长度不变。
    wave_date.shape=-1,2
    # 转置数据,使成为2行的数据,方便下面时间匹配
    wave_date=wave_date.T
    #通过取样点数和取样频率计算出每个取样的时间,也就是周期T=采样单数/采样率
    time=np.arange(0,nframes)* (1.0/framerate)
    return wave_date,time

def date_fft(data,time,start,end):
    #wavedata, wavetime = wave_read(path)
    t=[]
    y=[]
    for i in range(time.size):
        if ((time[i]>=start) & (time[i]<=end)):
            t=np.append(t,time[i])
            y=np.append(y,data[0][i])#取左声道
    n=len(t)# 信号长度
    yy=fft(y)
    yf=abs(yy)#取绝对值
    yf1=abs(fft(y))/n#归一化处理
    yf2=yf1[range(int(n/2))]##由于对称性,只取一半区间

    xf=np.arange(len(y))#频率
    xf1=xf
    xf2=xf[range(int(n/2))]#取一半区间

    #显示原始序列
    plt.figure()
    plt.subplot(221)
    plt.plot(t,y,'g')
    plt.xlabel("Time")
    plt.ylabel("Amplitude")
    plt.title("Original wave")

    #显示取绝对值后的序列
    plt.subplot(222)
    plt.plot(xf, yf)
    plt.xlabel("Freq (Hz)")
    plt.ylabel("|Y(freq)|")
    plt.title("FFT of Mixed wave(two sides frequency range",fontsize=7,color='#7A378B')
    # 注意这里的颜色可以查询颜色代码表

    #显示归一化处理后双边序列
    plt.subplot(223)
    plt.plot(xf1, yf1)
    # 注意这里的颜色可以查询颜色代码表
    plt.xlabel("Freq (Hz)")
    plt.ylabel("|Y(freq)|")
    plt.title('FFT of Mixed wave(Normalized processing)',fontsize=10,color='#F08080')

    # 显示归一化处理后单边序列
    plt.subplot(224)
    plt.plot(xf2, yf2, 'b')
    # 注意这里的颜色可以查询颜色代码表
    plt.xlabel("Freq (Hz)")
    plt.ylabel("|Y(freq)|")
    plt.title('FFT of Mixed wave',fontsize=10,color='#F08080')

    plt.show()


wave_date, time=wave_read("01.wav")
date_fft(wave_date,time,1,2)

#左右声道的显示
plt.figure()
plt.subplot(211)
plt.plot(time, wave_date[0])
plt.title("Left channel")
plt.subplot(212)
plt.plot(time, wave_date[1], c="g")
plt.title("Right channel")
plt.show()

三、图像显示

1.左右声道的显示

python读取wav文件并进行FFT变换_第1张图片

2.FFT变换显示

python读取wav文件并进行FFT变换_第2张图片

四、参考文章

1.Python读取麦克风保存成文件并进行FFT
2.https://blog.csdn.net/weixin_32393347/article/details/85273820
3.https://blog.csdn.net/qq_39516859/article/details/79819276
4.https://blog.csdn.net/jeffrey2010/article/details/77427451

你可能感兴趣的:(python,FFT)