gpt4 book ai didi

python - Python 中复数的 FFT 滤波器

转载 作者:太空宇宙 更新时间:2023-11-03 17:44:15 27 4
gpt4 key购买 nike

我的问题与 A. Levy 的解释相关: Analyze audio using Fast Fourier Transform

如何在这些复数上生成带通滤波器...

[-636.00000000 +0.00000000e+00j  -47.84161618 -2.80509841e+02j
30.69754505 -1.30624718e+01j -109.94022791 +7.58155488e+00j
-3.18538186 +1.44880882e+01j -120.36687555 +5.45225425e+00j
50.48671763 +1.69504204e+01j 31.56751791 -7.22728042e+01j
-17.96079093 -3.17853727e+01j -19.25527276 +5.08151876e+00j
18.38143611 -2.60879726e+01j -27.15617871 -4.39789289e+01j...

...已经知道我将使用 ifft 将复杂数组转换回时域。我的带通应该只允许 18500Hz 到 19500Hz 通过(超音速,我知道。我专门寻找从房间另一端的音频发生器发出的这些音调)。我的采样率为 44100Hz,FFT 中的点数为 128。

然后我将在此处使用频率检测代码(它已经适用于我的非过滤样本)Python frequency detection以便在音频到达时给我音调。如果在 19000HZ 处没有播放任何音调(例如),则音高检测函数的输出应返回 0。

我当前的过滤器代码(没有给出正确的结果):

samp = [-10 -16 -15 -11 -8 -10 -9  -12 -7 -13 -4 -10 
-1 -4 -11 -6 -8 -8 -10 -6 -9 -7 -16 -11 5 -14
-9 -3 -9 -7 -7 -6 -3 -11 -13 -9 -10 -4 -6 -7
-11 -15 -15 -3 -5 -15 -11 -8 -13 -9 -12 -10 -8 -16
-13 -5 -4 -12 -14 -8 -14 -6 -7 -7 -4 -6 -9 -4 -4
-4 1 -10 -3 -9 -9 -1 -5 -2 -5 -3 -3 2 -3 2
-5 -4 -6 1 -2 -6 -8 -3 -10 -11 -6 -2 -5 -3
0 3 0 1 1 -1 -3 -3 1 3 -3 -3 3 -3 -1
-3 -1 2 1 0 -8 0 6 -3 -4 -7 -5 -10 -4 -4]

sample_time = 0.000022675 # 1/44100

low_cut = 18500
high_cut = 19500

float_samp = np.float32(samp)
fft_spectrum = np.fft.fft(float_samp)

freqs = np.fft.fftfreq(len(fft_spectrum), d=sample_time)

### wrong approach ###
for i in range(len(freqs)): # (H-red)

if abs(freqs[i]) >= high or abs(freqs[i]) <= low:
fft_spectrum[i] = 0.0
### -------------- ###

time_domain = np.fft.ifft(fft_spectrum)
converted = np.int16(time_domain)

目前,无论是否存在音调,它在基音检测后返回 18500Hz 到 19500Hz 之间的值。我相信情况确实如此,因为我从 fft_spectrum 列表中删除了除包含过滤器值的信息之外的所有信息。即使音调不存在,唯一留下的信息是该频带内的信息,因此这就是音调检测器正在读取的信息。这是我的假设。

请注意:我无法使用 Scipy,因为我在 Android 上部署它,并且该库在该平台上不可用。我希望有一种方法可以通过 Numpy 来做到这一点。

最佳答案

您链接的频率检测代码正在执行 FFT,然后查找幅度最大的 bin。返回零的唯一方法是最大量级位于第 0 个容器中。即使您可能不会以您感兴趣的频率发出音调,但那里肯定存在能量,因此是最大的候选者。为了完成您所要求的操作,您需要修改引用的代码以提供所需的行为。例如,您可以应用某种最低阈值。

which = fftData[1:].argmax() + 1
if (fftData[which] < threshold)
return -1; // no peak found

当您这样做时:我不明白为什么您要经历带通滤波信号的过程,而您可以限制频率检测来搜索感兴趣的箱:

binMin = floor(low_cut / 22050.0 * 128)
binMax = ceil(high_cut / 22050.0 * 128)
which = fftData[binMin:binMax].argmax() + 1

关于python - Python 中复数的 FFT 滤波器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30042348/

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