我目前运行Python的Numpy fft的44100赫兹音频样本,这使我的工作频率范围0HZ-22050赫兹(谢谢尼奎斯特)。一旦我使用fft的那些时域值,我有128个点在我的fft频谱给我172赫兹的每一个频域大小。
我想收紧频率箱到86赫兹,仍然保持只有128个fft点,而不是增加我的fft计数到256通过调整我是如何创建我的样本。
我的问题是,这在理论上是否可行。我的想法是只对0Hz到11025Hz之间的任何Hz值运行fft。不管怎么说,我不关心任何事情。这将把我的工作频谱减半,把我的频率箱在86赫兹,同时保持我的128个频谱箱。也许这可以通过时间域的窗口函数来实现?
目前,我用来创建示例并转换为fft的代码是:
import numpy as np
sample_rate = 44100
chunk = 128
record_seconds = 2
stream = self.audio.open(format=pyaudio.paInt16, channels=1,
rate=sample_rate, input=True, frames_per_buffer=6300)
sample_list = []
for i in range(0, int(sample_rate / chunk * record_seconds)):
data = stream.read(chunk)
sample_list.append(np.fromstring(data, dtype=np.int16))
### then later ###:
for samp in sample_list:
samp_fft = np.fft.fft(samp) ...我希望我的措辞足够清楚。如果我需要调整我的解释或术语,请告诉我。
发布于 2015-05-06 08:00:24
你想要的是不可能的。正如您在评论中提到的,您需要一个很短的时间窗口。我想这是因为你试图检测信号何时到达某一频率(我已经回答了你先前关于这个问题的问题),而且你希望检测是对时间敏感的。但是,您的垃圾箱大小似乎太大,无法满足您的要求。
只有两种方法可以减小垃圾箱的大小。1)增加FFT的长度。不幸的是,这也意味着获取数据需要更长的时间。2)降低采样率(通过采样率转换或硬件级),但由于采样速度较慢,获取数据也需要更长的时间。
我将向你们建议第三种选择(根据我从这个问题中收集到的信息,以及你们的其他问题可能是一个更好的解决方案),那就是:在时间域中执行频率检测。这将需要一个时域带通滤波器,然后是一个均方根计.就实现而言,这将是一个或多个biquad过滤器,您可以在python中为过滤器实现--可能已经有实现可用。棘手的部分是设计过滤器,但我很乐意帮助你聊天。均方根计基本上是取滤波器输出样本平方和的平方根。
发布于 2015-05-06 06:09:36
将快速傅立叶变换的大小增加一倍是显而易见的,但是如果有一个很好的理由你不能这样做,那么在FFT之前考虑2倍的下采样,以使有效的采样率降低到22050 Hz:
- Apply low pass filter with cut off at 11 kHz
- Discard every other sample from filtered output
- Apply FFT to down-sampled data发布于 2015-05-06 18:02:16
如果您不试图解决接近相邻的频率峰值或噪声之间,那么,到一半的频率箱间距,您可以零垫您的数据双倍的FFT长度,而不必等待更多的数据。然后,如果你只想要频率范围0..f/2的下半部分,只需丢弃FFT结果向量的中半部分(这通常比试图通过非FFT均值计算频率范围的下半部要有效得多)。
请注意,零填充给出的结果与高质量的插值(在平滑图的原始FFT结果点)相同。它不会增加峰值分离分辨率,但如果噪音水平足够低,则可以更容易地在图中选择更精确的峰值位置。
https://stackoverflow.com/questions/30067812
复制相似问题