私はこれについては正しくないかもしれませんが、私が知る限り、曲全体のスペクトルを取得する方法は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の投稿はあなたに問題に関するたくさんの情報を与えるでしょう=)