基于Python的QPSK音频的波形和频谱

xiaoxiao2021-02-28  47

1、需求分析

  现有一个QPSK.wav的音频文件,要求使用Python读取该文件画出其波形和频谱。

2、代码实现

import wave import numpy as np import pylab as pl #打开wav文件 ,open返回一个的是一个Wave_read类的实例,通过调用它的方法读取WAV文件的格式和数据。 f = wave.open(r"E:\团队文件\音频\14、QPSK.wav","rb") #读取格式信息 #一次性返回所有的WAV文件的格式信息,它返回的是一个组元(tuple):声道数, 量化位数(byte单位), 采 #样频率, 采样点数, 压缩类型, 压缩类型的描述。wave模块只支持非压缩的数据,因此可以忽略最后两个信息 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) #通过取样点数和取样频率计算出每个取样的时间。 time=np.arange(0,nframes)/framerate #由于plot函数里的两个参数维度不同,于是将time的长度除以2。 len_time = len(time)//2 time = time[0:len_time] fft_size = 512 #FFT处理的取样长度 xs = wave_data [:fft_size]# 从波形数据中取样fft_size个点进行运算 xf = np.fft.rfft(xs)/fft_size# 利用np.fft.rfft()进行FFT计算,rfft()是为了更方便对实数信号进行变换,由公式可知/fft_size为了正确显示波形能量 # rfft函数的返回值是N/2+1个复数,分别表示从0(Hz)到sampling_rate/2(Hz)的分。 #于是可以通过下面的np.linspace计算出返回值中每个下标对应的真正的频率: freqs = np.linspace(0, framerate/2, fft_size/2+1) # np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) #在指定的间隔内返回均匀间隔的数字 xfp = 20*np.log10(np.clip(np.abs(xf), 1e-20, 1e100)) #最后我们计算每个频率分量的幅值,并通过 20*np.log10()将其转换为以db单位的值。为了防止0幅值的成分造成log10无法计算,我们调用np.clip对xf的幅值进行上下限处理 #print(params) #print ("time length = ",len(time) ) #print ("wave_data[0] length = ",len(wave_data) ) #绘图显示结果 pl.figure(figsize=(8,4)) pl.subplot(311) pl.plot(time,wave_data) pl.xlabel("time(s)") pl.title(u"WaveForm And Freq") pl.subplot(312) pl.plot(time[:fft_size], xs) pl.xlabel(u"Time(S)") pl.subplot(313) pl.plot(freqs, xfp) pl.xlabel(u"Freq(Hz)") pl.subplots_adjust(hspace=0.4) pl.show()

注意:

len_time = len(time)//2 time = time[0:len_time]

1、上一篇MORSE音频的代码中没有上面两行代码。在该程序中就会报错: ValueError:x and y must have same first dimension, but have shapes (193032,) and (96516,) 提示plot函数里的两个参数维度不同,于是打印了time 和 wave_data[0]的长度: 所以将time的长度截取一半,再run一边,图就出现啦。

2、在使用Python进行矩阵操作时,当内部含有除法时,会产生错误:

TypeError: slice indices must be integers or None or have an index method.

解决办法:将len_time = len(time)/2中的“/”改为“//”,即:len_time = len(time)//2,程序就可以正常运行了。

3、实现结果

4、结果分析

  在pycharm运行中可以看出wav文件的格式信息如下:   上图中第一条波形为音频文件的原始波形;第二条波形为512个取样点的波形;第三条波形为512个取样点的波形对应的频谱图。

转载请注明原文地址: https://www.6miu.com/read-2626561.html

最新回复(0)