2

音楽ファイルの周波数スペクトルをプロットしたい (たとえば、Audacity のように)。したがって、x 軸にヘルツ単位の周波数、y 軸に振幅 (またはデシベル) が必要です。

曲 (約 2000 万サンプル) を 4096 サンプルずつブロックに分割します。これらのブロックは、2049 (N/2 + 1) の複素数 (正弦と余弦 -> 実数と虚数部) になります。では、これらの何千もの個別の 2049 アレイを取得したので、それらをどのように組み合わせることができるでしょうか?

FFT を 5000 回実行すると、5000 個の 2049 配列の複素数が得られるとします。5000 配列のすべての値を加算してから、結合された 2049 配列の大きさを取得しますか? 次に、x 軸を曲のサンプルレート / 2 (例: 44100hz ファイルの場合は 22050) にしますか?

あらゆる情報が評価されます

4

4 に答える 4

2

私はこれについては正しくないかもしれませんが、私が知る限り、曲全体のスペクトルを取得する方法は2つあります。

1)曲全体に対して単一のFFTを実行します。これにより、非常に優れた周波数分解能が得られますが、実際には効率的ではなく、この種の分解能は必要ありません。

2)それを小さなチャンク(あなたが言ったように4096サンプルブロックのように)に分割し、それらのそれぞれのFFTを取得し、スペクトルを平均します。周波数分解能に妥協しますが、計算をより管理しやすくします(また、スペクトルの分散を減らします)。Wilhelmsenリンクは、C ++でFFTを計算する方法を説明しており、FFTWのように、それを実行するためのライブラリがすでに存在していると思います(ただし、公平を期すために、コンパイルすることはできませんでした=))。

マグニチュードスペクトルを取得するには、すべてのビンのすべてのチャンクのエネルギー(マグニチュードの2乗)を平均します。結果を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]);
}

これがあなたの質問に答えることを願っています。

編集:Gozの投稿はあなたに問題に関するたくさんの情報を与えるでしょう=)

于 2012-05-23T09:43:09.650 に答える
2

うわー、最近これについてたくさん書いた。

私はそれをここで利用できるブログ投稿に変えました.

私の説明はスペクトログラムに傾いていますが、あなたが説明したようにチャートをレンダリングするのと同じくらい簡単です!

于 2012-05-23T09:47:28.073 に答える
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 に答える
1

通常、関心のある音楽の時点に対応する配列を 1 つだけ取得します。複素数配列の各要素の大きさの対数を計算します。N/2 の結果を Y 値としてプロットし、X 軸を 0 から Fs/2 (Fs はサンプリング レート) にスケーリングします。

于 2012-05-20T01:56:34.433 に答える