2017-04-15 2 views
1

現在、FFTW3とSFMLを使用してオーディオスペクトラムを表示しようとしています。私はhereの指示に従い、FFTとスペクトルとFFTWの多数の参考文献を見ましたが、どういうわけか私のバーはほぼすべてが以下のように左揃えになっています。私が抱えているもう一つの問題は、FFT出力のスケールが何であるかに関する情報を見つけることができないということです。現在、私はそれを64で割っていますが、それは時折それを越えています。さらに、FFTWからの出力が入力と同じサイズでなければならない理由についての情報はまだ見つかりませんでした。私の質問は以下の通りです:FFTスペクトラムが正しく表示されない

  1. 私のスペクトルの大部分は、私の下の画像とは異なり、左に揃えられているのはなぜですか?
  2. 出力が0.0と1.0の間にないのはなぜですか?
  3. 入力サンプル数がfft出力数に関係するのはなぜですか?

は、私が何を得る:私が探している何

enter image description here

:ご質問の

enter image description here

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

答えて

0

すべてはFFTの理論に関連しています。標準的なテキスト/リファレンスブックからFFTのプロパティを調べると、自分ですべての質問に答えることができます。

ここから最低限のものは https://en.wikipedia.org/wiki/Fast_Fourier_transformです。

+0

私はFFT、DFT、Spectral Density Estimationのwikiページを閲覧しましたが、ほとんどの情報が私の理解を超えてしまったため、私の質問に対する回答を特定できませんでした。 –

+0

@trigger_death:https://dsp.stackexchange.com/に質問を投稿する必要があります。 –

0
  1. 多くのFFT実装は省エネルギーです。つまり、出力のスケールは、入力のスケールおよび/またはサイズに直線的に関係しています。

  2. FFTはDFTであり、正方行列変換です。したがって、いくつかの出力が破棄されない限り、出力の数は入力の数と常に等しくなります(または、冗長複素共役半分を厳密に実際の入力とすると半分になります)。そうでない場合は、FFTではありません。出力を少なくしたい場合は、FFT出力をダウンサンプリングしたり、別の方法で処理したりする方法があります。

関連する問題