Np.fft.fft работает правильно? Я получаю очень большие значения частоты - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь провести некоторую очистку звука, чего раньше никогда не делал python или другим способом, и мне пришла в голову мысль, что я мог бы использовать FFT, чтобы найти частоты, составляющие мое аудио, и устранить частоты, которые не принадлежат я сделал это на обычном аудио, но я не мог понять результаты, поэтому я попробовал это на простой синусоиде. и это выглядело и звучало как волна нормального размера.

fig, ax = plt.subplots(figsize=(20,3))
ax.plot(sine_wave[:500])
IPython.display.Audio(data=sine_wave, rate=44100)

Но когда я сделал fft и посмотрел на частоты на графике, это не имело смысла

def do_fft(data_samples):  
    data_fft = np.fft.fft(data_samples)
    freq = (np.abs(data_fft[:len(data_fft)]))
    plt.subplots(figsize=(20,10))
    plt.plot(freq)
    print("The frequency is {} Hz".format(np.argmax(freq)))
    return freq

sine_freq = do_fft(sine_wave)
sine_freq[47000]

Для одного Я не совсем понимаю, что должен означать мой частотный массив. Я знаю, что большое число при определенном индексе K означает, что K Гц часто появляется в звуке. Это имело бы смысл, поскольку я получил значение, равное 23 999,9999,9 при 1000 Гц, то есть частоту моей волны. Что не имеет смысла, так это то, что я получил 24 000 за 47 000 Гц. Это не имеет никакого смысла для меня. Я сделал что-то неправильно? FFT не работает должным образом?

Ответы [ 2 ]

4 голосов
/ 04 февраля 2020

БПФ строго реальных (все мнимые компоненты == ноль) данных всегда сопряжено зеркально симметрично c. Именно так работает математика БПФ. Таким образом, ваш пик 47 кГц (такой же, как -1 кГц) - это просто зеркальное отображение 1 кГц при частоте дискретизации 48 кГц. Частота свертывания Найквиста или шарнир зеркального отражения составляют половину частоты дискретизации (и / или ноль, если считать верхние частоты бина отрицательными).

1 голос
/ 04 февраля 2020

Я предпочитаю явно определять время и вычислять частоты. FT должен быть нанесен на график против этих частот. Только argmax вычисляет место в векторе, а не частоту. Частота дискретизации (sa / se c) не является частотой. Теорема Найквиста утверждает (среди прочего), что ваша максимальная частота (в Гц) составляет 1/2 частоты дискретизации в Sa / se c. Поскольку мы используем комплекс FT (показаны положительные и отрицательные частоты), -999,979 Гц на самом деле составляет +1000 Гц.

import numpy as np
import matplotlib.pyplot as p

sampling_rate = 48000 

t= np.linspace(0,1,sampling_rate+1)       # time vector
dt=t[1]-t[0]
print(f'first/last time {t[0]}, {t[-1]}')
print(f'time interval : {dt}')


f = 1000
sig = np.sin(2 * np.pi * f*t)

fig = p.figure(figsize=(15,10))
p.subplot(211)
p.plot(sig[:500])

p.subplot(212)
ft = np.fft.fftshift(np.fft.fft(sig))
freq=np.fft.fftshift(np.fft.fftfreq(len(t),dt))
p.plot(freq,ft )
print(f'argmax of FT is not a frequency, but a position in a vector : {np.argmax(ft)}')
f0=freq[np.argmax(ft)]
print(f'the frequency is {f0:.3f} Hz')

enter image description here

...