首页 > 解决方案 > 使用 sounddevice numpy 数组执行 fft

问题描述

我似乎无法弄清楚为什么我的代码不会生成由 sounddevice.rec() 制成的 numpy 数组的 fft 我能够使代码与音频文件一起使用,但不能与 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 的 图片 在此处输入图像描述

标签: pythonnumpyfft

解决方案


记录函数sd.rec()返回一个形状为 [44100,1] 的二维 numpy 数组。维度 1 与通道数有关(此处为 1)。要对其进行测试,请键入:

print( recording.shape)

然后,在长度为 1 的最后一个维度上执行 dft。因此,没有任何变化并且yk与 完全相同recording

为了纠正这个问题,np.fft.rfft()可以将实数到复数 DFT 应用于recording[:,0]. 此外,可以添加一个 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()

推荐阅读