我要绘制一个音乐文件的频谱(就像他们在无畏例如做)。 因此,我想在x轴和y轴的振幅(或desibel)频率(赫兹)。
我devide歌曲(约20万个样本)进入4096个样本块在同一时间。 这些块将导致2049(N / 2 + 1)个复数(正弦和余弦 - >实部和虚部)。 所以,现在我有这些成千上万个人2049阵列的,我怎么搭配啊?
可以说,我做FFT导致复数5000 2049阵列5000倍。 我加了5000个阵列的所有值,然后采取联合2049阵列的大小? 做我然后sacle x轴与该歌曲的采样速率/ 2(例如:22050用于文件44100hz)?
任何信息都将appriciated
您使用此应用程序是什么? 我假设你是不是手工做这个,所以这里是一个Matlab的例子:
>> fbins = fs/N * (0:(N/2 - 1)); % Where N is the number of fft samples
现在你可以执行
>> plot(fbins, abs(fftOfSignal(1:N/2)))
被盗
编辑:看看这个http://www.codeproject.com/Articles/9388/How-to-implement-the-FFT-algorithm
哇,我已经写了一个关于这个负载刚刚结束。
我甚至把它变成一个提供博客文章在这里 。
我的解释是倾向于频谱,但它一样容易使图表像你描述!
我可能是不正确的这一个,但据我所知,你有2种方法让整首歌曲的谱。
1)请在整首歌曲,它会给你一个非常好的频率分辨率单FFT,但在实践中效率不高,而且你不需要这种分辨率的反正。
2)把它分成小块(如4096个样本块,像你说的),得到每个的人的FFT和平均光谱。 你会妥协的频率分辨率,而且使计算更易于管理(也降低了频谱的方差)。 威尔森链接的介绍如何计算在C ++的FFT,我觉得有些图书馆已经存在这样做的,像FFTW(但我从来没有设法编译它,是公平=))。
为了获得幅度谱,平均能量(幅度的平方)翻过你块为每一个垃圾箱。 为了得到结果以dB为单位,只有10 * LOG10结果。 这当然是假设你不感兴趣的相位谱。 我想,这是被称为巴雷特的方法 。
我会做这样的事情:
// At this point you have the FFT chunks
float sum[N/2+1];
// For each bin
for (int binIndex = 0; binIndex < N/2 + 1; binIndex++)
{
for (int chunkIndex = 0; chunkIndex < chunkNb; chunkIndex++)
{
// Get the magnitude of the complex number
float magnitude = FFTChunk[chunkIndex].bins[binIndex].real * FFTChunk[chunkIndex].bins[binIndex].real
+ FFTChunk[chunkIndex].bins[binIndex].im * FFTChunk[chunkIndex].bins[binIndex].im;
magnitude = sqrt(magnitude);
// Add the energy
sum[binIndex] += magnitude * magnitude;
}
// Average the energy;
sum[binIndex] /= chunkNb;
}
// Then get the values in decibel
for (int binIndex = 0; binIndex < N/2 + 1; binIndex++)
{
sum[binIndex] = 10 * log10f(sum[binIndex]);
}
希望这回答了你的问题。
编辑:戈兹贝达的帖子会给你足够的信息对此事=)
通常,你会采取只是阵列中的一个,对应点在你感兴趣的音乐的时间。 在你计算每个复杂的数组元素的大小的日志。 画出N / 2的结果的Y值和缩放从0 X轴到fs / 2(其中Fs是采样率)。