如何将低通滤波器应用于python上的声音记录?

时间:2019-11-19 09:51:18

标签: signal-processing fft noise noise-reduction whitenoise

我必须减少录音中的白噪声。因此,我使用了傅立叶变换。但是我不知道如何使用fftquincy域中的fft函数的返回值。如何使用fft数据来降低噪声?

这是我的代码

from scipy.io import wavfile
import matplotlib.pyplot as plt
import simpleaudio as sa
from numpy.fft import fft,fftfreq,ifft

#reading wav file

fs,data=wavfile.read("a.wav","wb")

n=len(data)

freqs=fftfreq(n)

mask=freqs>0

#calculating raw fft values
fft_vals=fft(data)

#calculating theorical fft values

fft_theo=2*np.abs(fft_vals/n)

#ploting

plt.plot(freqs[mask],fft_theo[mask])
plt.show()```

1 个答案:

答案 0 :(得分:0)

此类问题最好建立一个综合示例,因此您不必发布大型数据文件,人们仍然可以关注您的问题(MCVE)。

绘制中间结果也是很重要的,因为我们正在谈论对复数的运算,因此我们经常必须分别采用re,im部分或绝对值和角度。

实函数的傅立叶变换很复杂,但对于正负频率是对称的。也可以从信息理论的角度看待这一问题:您不希望N个独立的实数及时产生2N个独立的实数来描述频谱。

尽管通常可以绘制频谱的绝对或绝对平方(电压与功率),但在应用滤波器时,可以使其复杂。在通过IFFT将时间反向转换为时间后,要对其进行绘制,您将不得不再次将其转换为实数,在这种情况下,必须取绝对值。

如果在时域中设计滤波器内核(高斯的FFT将为高斯),则滤波器的FFT与频谱的乘积的IFFT将只有非常小的虚部,然后您可以实部(从物理学的角度来看更有意义,您从实部开始,以实部结束)。

import numpy as np
import matplotlib.pyplot as p
%matplotlib inline

T=3 # secs
d=0.04 # secs
n=int(T/d)
print(n)
t=np.arange(0,T,d)  
fr=1 # Hz
y1= np.sin(2*np.pi*fr*t) +1          # dc offset helps with backconversion, try setting it to zero
y2= 1/5*np.sin(2*np.pi*7*fr*t+0.5) 
y=y1+y2 
f=np.fft.fftshift(np.fft.fft(y))
freq=np.fft.fftshift(np.fft.fftfreq(n,d))

filter=np.exp(- freq**2/6)  # simple Gaussian filter in the frequency domain
filtered_spectrum=f*filter  # apply the filter to the spectrum

filtered_data =  np.fft.ifft(filtered_spectrum)  # then backtransform to time domain


p.figure(figsize=(24,16))

p.subplot(321)
p.plot(t,y1,'.-',color='red', lw=0.5, ms=1, label='signal')  
p.plot(t,y2,'.-',color='blue', lw=0.5,ms=1, label='noise') 
p.plot(t,y,'.-',color='green', lw=4, ms=4, alpha=0.3, label='noisy signal') 
p.xlabel('time (sec)')
p.ylabel('amplitude (Volt)')
p.legend()

p.subplot(322)
p.plot(freq,np.abs(f)/n, label='raw spectrum')
p.plot(freq,filter,label='filter')
p.xlabel(' freq (Hz)')
p.ylabel('amplitude (Volt)');
p.legend()

p.subplot(323)
p.plot(t,  np.absolute(filtered_data),'.-',color='green', lw=4, ms=4, alpha=0.3, label='cleaned signal')
p.legend()

p.subplot(324)
p.plot(freq,np.abs(filtered_spectrum), label = 'filtered spectrum')
p.legend()


p.subplot(326)
p.plot(freq,np.log( np.abs(filtered_spectrum)), label = 'filtered spectrum') 
p.legend()
p.title(' in the log plot the noise is still visible');

enter image description here