用python实现wav文件的功率谱

用python实现wav文件的功率谱,python,signal-processing,fft,Python,Signal Processing,Fft,我试着加载一个波形文件并用傅里叶变换打印它的光谱。我根据我找到的一些书,从那里得到了一些代码,但结果有点不同 def read_wave(filename): fp=wave.open(filename,'r') nchannels=fp.getnchannels() framerate=fp.getframerate() nframes=fp.getnframes() sampwidth=fp.getsampwidth() z_str=fp

我试着加载一个波形文件并用傅里叶变换打印它的光谱。我根据我找到的一些书,从那里得到了一些代码,但结果有点不同

def read_wave(filename):

    fp=wave.open(filename,'r') 
    nchannels=fp.getnchannels()
    framerate=fp.getframerate()
    nframes=fp.getnframes()
    sampwidth=fp.getsampwidth()

    z_str=fp.readframes(nframes)
    fp.close()

    dtype_map={1:np.uint8,2:np.uint16}
    ys=np.frombuffer(z_str,dtype=dtype_map[sampwidth])

    waveObject=Wave(ys,framerate=framerate)

    return waveObject


class Wave:

    def __init__(self,ys,ts=None,framerate=None):

        # ys:wave array
        # ts:array of time


        self.ys=np.asanyarray(ys)
        self.framerate=framerate

        if ts is None:
            self.ts =np.arange(len(ys))/self.framerate
        else:
            self.ts=ts

    def make_spectrum(self):

        n=len(self.ys);
        d=1/self.framerate;

        hs = np.fft.rfft(self.ys)
        fs = np.fft.rfftfreq(n, d)



        return Spectrum(hs,fs,self.framerate)

class Spectrum:

    def __init__(self,hs,fs,framerate):

        # hs : array of amplitudes (real or complex)
        # fs : array of frequencies

        self.hs=np.asanyarray(hs)
        self.fs=np.asanyarray(fs)
        self.framerate=framerate

    @property
    def amps(self):
        return np.absolute(self.hs)

    def plot(self, high=None):

       plt.plot(self.fs, self.amps)

data=read_wave('hate.wav') <br>
spectrum=data.make_spectrum()<br>
spectrum.plot()<br>
def read_wave(文件名):
fp=wave.open(文件名'r')
nchannels=fp.getnchannels()
framerate=fp.getframerate()
nframes=fp.getnframes()
sampwidth=fp.getsampwidth()
z_str=fp.readframes(nframes)
fp.close()
dtype_map={1:np.uint8,2:np.uint16}
ys=np.frombuffer(z_str,dtype=dtype_map[sampwidth])
waveObject=Wave(ys,帧速率=帧速率)
返回波对象
类波:
def uuu init uuuu(self,ys,ts=None,framerate=None):
#波阵
#ts:时间数组
self.ys=np.asanyarray(ys)
self.framerate=帧速率
如果ts为无:
self.ts=np.arange(len(ys))/self.framerate
其他:
self.ts=ts
def make_光谱(自):
n=len(self.ys);
d=1/自帧率;
hs=np.fft.rfft(self.ys)
fs=np.fft.rfftfreq(n,d)
返回频谱(hs、fs、自帧率)
类别谱:
定义初始(自、hs、fs、帧速率):
#hs:振幅阵列(实数或复数)
#频率阵列
self.hs=np.asanyarray(hs)
self.fs=np.asanyarray(fs)
self.framerate=帧速率
@财产
def安培(自):
返回np.绝对值(self.hs)
def绘图(自身,高=无):
plt.绘图(自fs、自安培)
数据=读取波形('hate.wav')
光谱=数据。生成光谱() spectrum.plot()
但是我得到的光谱是这样的,看起来不对,有什么帮助吗

在f=0处有一个巨大的峰值,这表明信号具有恒定的偏移量

这可能与使用无符号整数类型有关:


尝试使用有符号类型,或从信号中减去平均值以删除偏移量。

存储在波形文件中的无符号8位样本的范围为0到255,因此具有DC偏移量。FFT显示的直流偏移量在开始时有一个巨大的尖峰。从每个样本中减去直流偏移(应为128,或由于记录错误而在128左右的某个值)将从FFT中去除巨大的直流偏移峰值,并允许绘图自动缩放以更好地显示其他频率单元


WAVE文件中的16位样本采用有符号整数格式,因此将其作为无符号值读取可能会损坏数据。

是的,这就是问题所在。使用签名类型解决了这个问题,thx。我正试图复制这个,我需要在你的代码中做些什么来让它工作?是的,这就是问题所在。使用签名类型解决它,thx。
dtype_map={1:np.uint8,2:np.uint16}