Не могу сгенерировать Numpy FFT правильно

1

Я пытаюсь найти частотный спектр людей, говорящих в wav файле, но до этого я решил, что попробую сделать это с помощью простого звукового файла 200 Гц. В следующем коде я читаю в файле 200hz и рисую его на экране. Примечание. Размер файла 200 Гц имеет частоту дискретизации 192000. Размер моего куска составляет 1/10, поэтому каждые 19200 выборок

from scipy.io import wavfile
import numpy as np

### This is just for drawing
import matplotlib.pyplot as plt
import matplotlib.animation as animation

### Above is for drawing

# Read the .wav file
sample_rate, data = wavfile.read('200hz.wav')
CHUNK_SAMPLES_PER_SECOND = 10
CHUNK = sample_rate / CHUNK_SAMPLES_PER_SECOND

# Now compute the spectrum on a given frame
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

# Now, lets just draw the plot
for frame in range(len(data) / CHUNK):
    ax1.clear()
    frame_data = data[frame * CHUNK:(frame + 1) * CHUNK, 0] # normally 2 channel, take 1st channel
    frame_data = frame_data * 1.0 / frame_data.max()

    #### Below, activate those to use the FFT ####
    # frame_data = np.fft.fft(frame_data) # Calculate FFT on dataset
    # frame_data = frame_data * 1.0 / frame_data.max() # Normalize FFT data
    # ax1.set_xlabel('frequency')

    ax1.plot(np.abs(frame_data), '-')
    ax1.set_xlabel('sample')
    ax1.set_ylabel('volume')
    plt.pause(1.0 / CHUNK_SAMPLES_PER_SECOND)

Вышеприведенный код дает:

Изображение 174551

Для меня это выглядит правильно. Поскольку я беру только 19200 выборок с частотой дискретизации 192000, график должен составлять 0,1 секунды. Таким образом, сигнал 200 Гц должен иметь примерно 20 полных волн.

Когда я затем включу следующий код, раскомментируя:

#### Below, activate those to use the FFT ####
# frame_data = np.fft.fft(frame_data) # Calculate FFT on dataset
# frame_data = frame_data * 1.0 / frame_data.max() # Normalize FFT data
# ax1.set_xlabel('frequency')

Он создает фанки выглядящую диаграмму fft:

Изображение 174551

Я предполагаю, что я ожидал, что это будет показывать пик около ~ 200 Гц или хорошо хотя бы один четко определенный пик для частоты сигнала. Спасибо!

Edit: Я добавил фактический аудио файл, который я использовал здесь.

Я также отрегулировал ось Y до шкалы шкалы и диапазона оси x ниже:

Изображение 174551

  • 1
    Вы пытались увеличить диапазон 0-400 для оси X? Вот где действие должно быть! Кроме того, используйте ось журнала для y.
  • 0
    Это выглядит правильно, просто действительно уменьшено. Если вы увеличите левый шип, вы увидите одну большую ячейку FFT. Если вы используете numpy.fft.fftfreq чтобы создать реальную частотную ось в герцах и построить график против numpy.fft.fftfreq , этот пик должен составлять 200 Гц. Правильный скачок должен быть на 192000-200 Гц. Если вы разместите свой файл WAV, мы можем подтвердить самостоятельно.
Показать ещё 2 комментария
Теги:
audio
fft

1 ответ

2
Лучший ответ

Ваша частотная ось идет от 0 до 19200. Это неверно, если взять меньший кусок, вы не уменьшаете частоту дискретизации. Он должен идти от 0 до 192000.

Итак, представьте, что каждое значение вдоль этой оси умножается на 10. Таким образом, у вас есть пик на 200 Гц, как и ожидалось, и куча пиков с целыми кратными им, как и ожидалось. Обратите внимание, что ваш образец не является идеальной синусоидой, он имеет много гармоник из-за формы.

Отметим также, что второй большой пик, близкий к 192000 Гц, соответствует "отрицательной частоте": вторая половина выхода ДПФ избыточна, зеркальная копия первой половины.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню