FFT 频谱未正确显示
Posted
技术标签:
【中文标题】FFT 频谱未正确显示【英文标题】:FFT Spectrum not displaying correctly 【发布时间】:2017-04-15 01:58:22 【问题描述】:我目前正在尝试使用 FFTW3 和 SFML 显示音频频谱。我已经按照here 的说明进行操作,并查看了有关 FFT 和频谱以及 FFTW 的大量参考资料,但不知何故,我的条形图几乎都与左对齐,如下所示。我遇到的另一个问题是我找不到有关 FFT 输出规模的信息。目前我将其除以 64,但偶尔仍会超出此范围。此外,我还没有找到关于为什么来自 FFTW 的输出必须与输入大小相同的信息。所以我的问题是:
-
为什么与下图不同,我的大部分光谱都向左对齐?
为什么输出不在 0.0 和 1.0 之间?
为什么输入样本计数与 fft 输出计数相关?
我得到了什么:
我在寻找什么:
const int bufferSize = 256 * 8;
void init()
sampleCount = (int)buffer.getSampleCount();
channelCount = (int)buffer.getChannelCount();
for (int i = 0; i < bufferSize; i++)
window.push_back(0.54f - 0.46f * cos(2.0f * GMath::PI * (float)i / (float)bufferSize));
plan = fftwf_plan_dft_1d(bufferSize, signal, results, FFTW_FORWARD, FFTW_ESTIMATE);
void update()
int mark = (int)(sound.getPlayingOffset().asSeconds() * sampleRate);
for (int i = 0; i < bufferSize; i++)
float s = 0.0f;
if (i + mark < sampleCount)
s = (float)buffer.getSamples()[(i + mark) * channelCount] / (float)SHRT_MAX * window[i];
signal[i][0] = s;
signal[i][1] = 0.0f;
void draw()
int inc = bufferSize / 2 / size.x;
int y = size.y - 1;
int max = size.y;
for (int i = 0; i < size.x; i ++)
float total = 0.0f;
for (int j = 0; j < inc; j++)
int index = i * inc + j;
total += std::sqrt(results[index][0] * results[index][0] + results[index][1] * results[index][1]);
total /= (float)(inc * 64);
Rectangle2I rect = Rectangle2I(i, y, 1, -(int)(total * max)).absRect();
g->setPixel(rect, Pixel(254, toColor(BLACK, GREEN)));
【问题讨论】:
【参考方案1】:您的所有问题都与 FFT 理论有关。从任何标准教科书/参考书上研究 FFT 的特性,您将只能自己回答所有问题。
您至少可以从这里开始: https://en.wikipedia.org/wiki/Fast_Fourier_transform。
【讨论】:
我浏览了 FFT、DFT 和 Spectral Density Estimation wiki 页面,但无法找到任何问题的答案,因为大部分信息超出了我的理解范围。 @trigger_death:那你应该把问题发到dsp.stackexchange.com。【参考方案2】:许多 FFT 实现都是节能的。这意味着输出的规模与输入的规模和/或大小呈线性关系。
FFT 是 DFT 是方阵变换。因此,除非某些输出被丢弃,否则输出的数量将始终等于输入的数量(或通过忽略给定严格实输入的冗余复共轭的一半)。如果不是,则不是 FFT。如果您想要更少的输出,可以通过其他方式对 FFT 输出进行下采样或对其进行后处理。
【讨论】:
以上是关于FFT 频谱未正确显示的主要内容,如果未能解决你的问题,请参考以下文章
FFT频谱分析(补零频谱泄露栅栏效应加窗细化频谱混叠),MatlabC语言代码