【问题标题】:performing fft using sounddevice numpy array使用 sounddevice numpy 数组执行 fft
【发布时间】:2023-04-01 14:06:01
【问题描述】:

我似乎无法弄清楚为什么我的代码不会产生 fft 由 sounddevice.rec() 制成的 numpy 数组 我能够使代码与音频文件一起使用,但不能与 数据形式 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 在钢琴和弦文件上的图片: enter image description here

这是我录音中 fft 的照片 enter image description here

【问题讨论】:

  • 欢迎来到 SO!您能否提供有关该错误的更多详细信息?您提到它适用于文件中的数据,但不适用于设备。它是如何“不起作用”的?
  • 我将它应用于钢琴音符的基本录音,并获得了正常的频率响应作为回报。当我将它应用到我的声音录音中时,该图是极端着色的。我无法想象我以这些频率说话。
  • 我在原帖中添加了图片
  • 你应该先用一个非常简单的声音来测试它,比如正弦波。您的声音完全有可能(甚至可能)包含很大范围的频率。也可能有环境声音。如果可以,一个好的测试将播放您录制​​到文件中的相同声音。这样你就可以验证你在这两种情况下得到的结果是一样的。
  • 感谢您的推荐。所以我使用中间 c 用一个简单的正弦波尝试了它,并得到了与我之前描述的相同的结果。我目前不相信这是噪音。不知何故,当我使用录音时,它正在时域而不是频域中绘制一些东西

标签: python numpy fft


【解决方案1】:

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

print( recording.shape)

然后,对长度为 1 的最后一个维度执行 dft。因此,没有任何变化,ykrecording 完全相同。

要纠正这个问题,可以将实数到复数 DFT np.fft.rfft() 应用于 recording[:,0]。此外,可以添加一个 Tuckey 窗口来缓和将非周期信号的帧视为周期信号的周期的影响:边缘的不连续性会引入杂散频率(频谱泄漏)(请参阅window function)。

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()

【讨论】:

  • 哇,Francis 非常感谢,这太棒了。我刚刚仔细阅读了您所说的内容,但我不确定为什么您需要执行 np.fft.rfft() 而不是 np.fft.fft()。我还保留了我的 k = np.arange(N)。我的代码不适用于 rfft 并更改了 k。但再次感谢。不是百分百确定它为什么会起作用,但确实如此
  • 不客气! numpy.fft.fft() 是复数到复数的一维 DFT:它将复数或实数数组转换为相同大小的复数数组。因此,它完美地发挥了作用。 numpy.fft.rfft() 是一个实数到复数的 DFT:它将大小为 N 的实数数组转换为大小为 N/2+1 的复数数组。因此,yk 的大小不一样,必须修改k 的长度。由于信号是实数,频率系数N-i 是频率分量i 的复共轭。 rfft 不计算冗余系数,减少计算和内存占用。
猜你喜欢
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2012-04-30
  • 1970-01-01
相关资源
最近更新 更多