在进行 FFT 和改变频率分量值后,我只会在音频中听到噪音。我哪里错了?

I only get noise in the audio after taking a FFT and varying frequency component values . Where am I going wrong?

我的项目objective是合成声音。我想要做的是读取一个波形文件并将其转换为振幅谱。因为我对幅度和相应的频率感兴趣。我还需要更改某些频率(我得到的)的幅度,以便我可以生成不同的声音 wav 文件并播放它。然而,即使不改变幅度,重建的信号也充满了噪声。

简单来说,读取文件---FFT---改变幅度---播放。

下面是代码

import scipy.io.wavfile
import sounfile as sf
data , rate = sf.read("bird_chirp.wav")
FFt_data =np.fft.rfft(data)
magnitude = np.abs(FFt_data)
phase = np.angle(FFt_data)
N= len(data) # Define the length of the wav file
timestamp = np.linspace(0.0, N*T, N)
T= 1.0/rate
n = data.size


#get the corresponding Frequencies
freq = np.fft.rfftfreq(n, d=1./rate)


# save it as a Dataframe
df = {"freq":freq, "mag":magnitude}
df =pd.DataFrame(df)


#Normalize the magnitude
a=df["mag"]
norm_a = a/a.max(axis=0)
df["mag"] = norm_a


# here I would play around with magnitude , make it high or low
#code to change magnitude

#Get back the new data to write in wav
y=0
for magnitudes ,frequencies in df.iterrows():
   y+= magnitudes["mag"]*(np.sin(frequencies["freq"] *2.0*np.pi*timestamp)) 


#save it 
sf.write(file="test.wav", data=y,samplerate=rate)

代码播放的声音充满噪音。

下面是一个简单的程序,它 (a) 读取波形文件,(b) 傅里叶变换数据,(c) 修改特定频率的振幅,(d) 反转傅里叶变换以将数据转换回时域,并且 (e) 将结果保存到另一个 wave 文件,您可以使用任何常用的音频播放程序播放该文件。

为了以简单的方式演示您可以对信号做什么, 我们在 1 kHz 处衰减幅度,在 440 Hz 处添加连续音调,在 880 处添加高斯形脉冲。

请注意,注入的信号在傅里叶变换中被缩放到其他信号的最大值。或者,我们可以选择一个振幅并根据数据的长度对其进行缩放。

这里的一个重要概念是傅立叶变换是节能的。因此,傅里叶变换中的信号按其持续时间缩放。

这是实现您在问题中寻找的内容的代码:

import scipy.io.wavfile
import soundfile as sf

import numpy as np

# Input the wave file
data , rate = sf.read("bird_chirp.wav")

# Fourier transform
FFT_data = np.fft.rfft(data)

# Get the list of frequencies
freq = np.fft.rfftfreq(len(data), d=1./rate)

# Find the bin closest to 1kHz and attenuate
idx = (np.abs(freq - 1.E3)).argmin()
FFT_data[idx] *= 1./2

# Find the bin closest to 440 Hz and set a continuous tone
idx = (np.abs(freq - 440)).argmin()
FFT_data[idx] = max( abs( FFT_data) )

# Add a Gaussian pulse, width in frequency is inverse of its duration
FFT_data += max( abs( FFT_data) )/2. * np.exp( -((freq-880)/5.)**2 )

# Convert back to time domain
newdata = np.fft.irfft(FFT_data)

# And save it to a new wave file
sf.write(file="test.wav", data=newdata, samplerate=rate)