2

我想绘制音乐文件的频谱(就像他们在 Audacity 中所做的那样)。因此,我想要 x 轴上的赫兹频率和 y 轴上的幅度(或分贝)。

我一次将歌曲(大约 2000 万个样本)分成 4096 个样本块。这些块将产生 2049 (N/2 + 1) 个复数(正弦和余弦 -> 实部和虚部)。所以现在我有这数千个单独的 2049 阵列,我该如何组合它们?

假设我做了 5000 次 FFT,得到 5000 个 2049 复数数组。我是否将 5000 个数组的所有值相加,然后取组合 2049 个数组的大小?然后我是否使用歌曲采样率 / 2(例如:22050 用于 44100hz 文件)来调整 x 轴?

任何信息将被appriciated

4

4 回答 4

2

您为此使用什么应用程序?我假设您不是手动执行此操作,所以这是一个 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

于 2012-05-19T10:01:14.663 回答
2

我在这方面可能不正确,但据我所知,您有两种方法可以获得整首歌的频谱。

1)对整首歌曲进行一次FFT,这会给你一个非常好的频率分辨率,但实际上效率不高,而且你也不需要这种分辨率。

2)将它分成小块(如你所说的4096个样本块),为每个块获取FFT并平均光谱。您将在频率分辨率上妥协,但使计算更易于管理(并且还减少了频谱的方差)。Wilhelmsen 链接描述了如何在 C++ 中计算 FFT,我认为已经有一些库可以做到这一点,比如 FFTW(但我从来没有设法编译它,公平地说 =))。

要获得幅度谱,请平均每个 bin 的所有块的能量(幅度的平方)。要获得以 dB 为单位的结果,只需 10 * log10 的结果。这当然是假设您对相位谱不感兴趣。我认为这被称为Barlett 方法

我会做这样的事情:

//  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]);
}

希望这能回答你的问题。

编辑:Goz 的帖子将为您提供有关此事的大量信息 =)

于 2012-05-23T09:43:09.650 回答
2

哇,我最近写了一篇关于这个的文章。

我什至把它变成了一篇博文,可以在这里找到

我的解释是倾向于频谱图,但它就像你描述的那样容易渲染图表!

于 2012-05-23T09:47:28.073 回答
1

通常,您只需要一个数组,对应于您感兴趣的音乐的时间点。您将计算每个复杂数组元素的大小的对数。将 N/2 结果绘制为 Y 值,并将 X 轴从 0 缩放到 Fs/2(其中 Fs 是采样率)。

于 2012-05-20T01:56:34.433 回答