gpt4 book ai didi

python - 如何使用 fft 创建音频低通滤波器

转载 作者:太空宇宙 更新时间:2023-11-03 20:35:00 26 4
gpt4 key购买 nike

我尝试为 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。该数组的第一项对应于直流分量,第二项对应于频率 1/N,第三项对应于 2/N...不过,数组的后半部分应该描述为负频率分量。因此,数组最后一项的频率为 -1/N,前面的项为 -2/N... 如 what FFTW really computes 中所述。

For those who like to think in terms of positive and negative frequencies, this means that the positive frequencies are stored in the first half of the output and the negative frequencies are stored in backwards order in the second half of the output. (The frequency -k/n is the same as the frequency (n-k)/n.)

由于信号是实数,频率 -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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com