[英]Is the Fourier transform I am computing in Python displayed in the time domain? If so, how can I display this in the Frequency domain?
我的目标是检测录音中是否存在特定频率和 output 二进制响应。 为此,我计划对音频文件执行傅里叶变换,并查询频点中包含的值。 如果我发现与我要查找的频率相关联的 bin 具有很高的值,这应该意味着它存在(如果我的想法是正确的)。 但是,我无法正确生成转换。 我的代码如下:
from scipy.io import wavfile
from scipy.fft import fft, fftfreq
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
user_in = input("Please enter the relative path to your wav file --> ")
sampling_rate, data = wavfile.read(user_in)
print("sampling rate:", sampling_rate)
duration = len(data) / float(sampling_rate)
print("duration:", duration)
number_samples_in_seg = int(sampling_rate * duration)
fft_of_data = fft(data)
fft_bins_from_data = fftfreq(number_samples_in_seg, 1 / sampling_rate)
print(fft_bins_from_data.size)
plt.plot(fft_bins_from_data, fft_of_data, label="Real part")
plt.show()
使用几个不同的 wav 文件尝试这段代码让我想知道我是否在时域而不是我需要的频域中显示我的变换:
输入:200hz.wav
Output:
sampling rate: 48000
duration: 60.000375
2880018
输入:8000hz.wav
Output:
sampling rate: 48000
duration: 60.000375
2880018
对于这些应该包含纯信号的文件,我希望在我的 plot 上只看到一个尖峰,其中 x = 200 或 x = 800。最后一个文件让我担心我没有查看频域:
输入:beep.wav
Output:
sampling rate: 48000
duration: 5.061958333333333
24297
这似乎显示了明显的哔哔声,因为它在时间的 x 轴上进行。
我试图通过仅绘制正值的大小来清理绘图。 不幸的是,我仍然没有看到频谱上孤立的频率:
plt.plot(fft_bins_from_data[0:number_samples_in_seg//2], abs(fft_of_data[0:number_samples_in_seg//2])
plt.show()
我在发帖前参考了这些资源:
numpy.fft.fft 和 numpy.fft.fftfreq 有什么区别
我的问题摘要:
尝试这个:
import scipy as sp
import scipy.signal as sig
import numpy as np
from numpy import fft
import matplotlib.pyplot as plt
number_samples_in_seg = len(data)
time_axis = np.arange(0, number_samples_in_seg)/sampling_rate
win = sig.windows.hann(number_samples_in_seg)
windowed_data = win*data
plt.plot(time_axis, windowed_data)
plot 如果不是很明显的话,这将是时域中的信号。 我对信号应用了 Hann window,如果信号的开始和结束不匹配(因为 FFT 假定信号片段是周期性的),这将减少伪影。
对于 FFT 的绘图:
fft_data = fft.fft(windowed_data)[0:int(np.floor(number_samples_in_seg/2))]
freq_axis = sp.fft.fftfreq(number_samples_in_seg, 1.0/sample_rate)[0:int(np.floor(number_samples_in_seg/2))]
plt.plot(freq_axis, 20.0*np.log10(np.abs(fft_data)))
fft_data
和freq_axis
上的方括号索引是为了消除 FFT 的负频率部分。 我在 Audacity 中生成了一个 200Hz 的正弦波,长度为 4096 个样本(只是为了使其适合二次方以进行良好的 FFT-ing)并且在我的 plot 中有一个 200Hz 的峰值。还要注意20*log10(abs(fft_data))
以 dB 为单位绘制的东西。
以上应该回答你的问题#3。 至于问题 #2,FFT 始终具有相同数量的时间点和频率点。 不确定问题 #1,但同样,上面的代码应该解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.