выполнение fft с использованием звукового устройства - PullRequest
0 голосов
/ 14 февраля 2019

Кажется, я не могу понять, почему мой код не создает fft массива numpy, сделанного из sounddevice.rec (). Я могу заставить код работать с аудиофайлом, но не с формой данных sounddevice

вот мой код:

import sounddevice as sd
import numpy as np
import matplotlib.pyplot as plt

duration = 1 #sec
fs = 44100

def record():
"""records from the mic"""
   recording = sd.rec(int(duration * fs), samplerate = fs, channels =1, 
   dtype='float64')
   #waits till ur finished recording
   sd.wait(duration)
   return recording

def play(recording):
"""plays recording"""
   sd.play(recording, fs)
   sd.wait(duration)

def plot_signal_freq(ys):
   N = ys.size
   print(N)
   L = N/fs
   yk = np.fft.fft_freq(ys)
   k = np.arange(N)
   freqs = k/L
   fig, ax = plt.subplots()
   ax.plot(freqs, np.abs(yk))


while True:
   recording = record()
   print(type(recording.dtype))
   print(recording)
   play(recording)
   plot_signal_freq(recording)`

вот изображение fft в файле аккордов для фортепиано: введите описание изображения здесь

вот изображение fftна мою запись голоса введите описание изображения здесь

1 Ответ

0 голосов
/ 15 февраля 2019

Функция записи sd.rec() возвращает двумерный массив пустышек формы [44100,1].Размер 1 связан с номером канала (здесь 1).Чтобы проверить это, наберите:

print( recording.shape)

Затем выполняется dft для последнего измерения длины 1. Следовательно, ничего не меняется, и yk полностью идентичен recording.

Чтобы исправить это, к recording[:,0] можно применить вещественное к сложному ДПФ np.fft.rfft().Кроме того, окно Tuckey может быть добавлено, чтобы умерить эффект от рассмотрения кадра непериодического сигнала как периода периодического сигнала: разрыв на краю вводит скачкообразные частоты (спектральный недостаток) (см. оконная функция ).

from scipy import signal
...

N = ys.shape[0]
print(N , ys.shape)
L = N/fs
tuckey_window=signal.tukey(N,0.01,True) #generate the Tuckey window, widely open, alpha=0.01
ysc=ys[:,0]*tuckey_window               #applying the Tuckey window
yk = np.fft.rfft(ysc)                   #real to complex DFT
k = np.arange(yk.shape[0])
freqs = k/L
fig, ax = plt.subplots()
ax.plot(freqs, np.abs(yk))
plt.show()
...