我试图为aiff文件创建一个低通滤波器,但发出的声音是白噪声。我只了解FFT的工作原理的广泛概述,所以我猜我的问题与此有关。

基本上,我打开音频文件(例如钢琴循环),将其转换为单声道,然后对样本执行FFT,然后尝试通过将它们设置为零来去除较高的频率。最后,我执行IFTT并将结果保存到新文件中。

import aifc
import struct
import numpy as np

def getMonoSamples(fileName):
    enter code here`obj = aifc.open(fileName,'r')
    obj.setpos(0)
    numFrames = obj.getnframes()
    myFrames = obj.readframes(numFrames)
    samplingRate = obj.getframerate()
    data = struct.unpack('{n}h'.format(n=numFrames*2), myFrames)
    data = np.array(data)
    dataLeft =[]
    for i,x in enumerate(data):
        if i%2==1:
            dataLeft.append(x)
    obj.close()
    return dataLeft,numFrames,samplingRate

def writeMonoFile(fileName,samples,nframes):
    mono_file=aifc.open(file, 'w')
    comptype="NONE"
    compname="not compressed"
    nchannels=1
    sampwidth=2
    mono_file.setparams((nchannels, sampwidth, int(sampling_rate), nframes, comptype, compname))
    print "writing sample aif..."
    for s in samples:
       mono_file.writeframes(struct.pack('h', s))
    mono_file.close()

def lpFilter(dataFft):
    new =[None]*len(dataFft)
    for i,x in enumerate(dataFft):
        #if the frequency is above 5000, remove it
        if i>5000:
            new[i]=0
        else:
            new[i]=x
    return new
# get audio samples from a function that converts stereo to mono
sampleData,numFrames,samplingRate = getMonoSamples('beetP2.aif')
dataFft = np.fft.fft(sampleData)
filtered = lpFilter(dataFft)
invFft = np.fft.ifft(filtered)
invFft = [int(x) for x in invFft]
file = "test.aif"
writeMonoFile(file,invFft,numFrames)

我的确收到警告:“ComplexWarning:将复数值转换为实数会丢弃虚部”,但在执行立体声到单声道转换并保存时,也会收到此警告。直到我尝试过滤音频为止,声音似乎都很好。我猜这是相关的,但不确定如何解决。

我过滤的任何音频样本都会听起来像白噪声,而不是本身的过滤版本。

最佳答案

切换为实数到复杂的 numpy.fft.rfft 及其相反的 numpy.fft.irfft 可能会解决此问题。

由于将复数到复数DFT变换应用于实际数组sampleData,因此输出数组是相同大小的复杂数组dataFft。该阵列的第一项对应于DC分量,第二项对应于频率1 / N,第三项对应于频率2 / N ...然而,该阵列的后半部分应描述为负频率分量。因此,数组最后一项的频率为-1 / N,即-2 / N之前的项...如what FFTW really computes中所述



由于信号是实数,因此频率-k / N的分量必须是频率k / N的分量的复共轭。例如,频率为k / N的余弦波产生了频率为k / N和-k / N的两个相等的实数分量。

通过将阵列的后半部分归零,将丢弃具有低负频率的分量,并且该阵列不再对应于实际阵列的DFT。它不是低通滤波器,可能会解释产生的白噪声。当应用逆DFT invFft = np.fft.ifft(filtered)时,其结果invFft很复杂,其大小与原始数组sampleData相同。

使用实际到复杂的DFT,会将实际数组sampleData转换为大小约为一半的复杂数组dataFft。将此阵列的一个分量置零意味着将正频率和负频率均置零,确保将阵列仍视为真实阵列的DFT。最终可以通过应用逆变换irfft恢复此实际数组。

关于python - 如何使用fft为音频创建低通滤波器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57225531/

10-10 09:05