2017-04-15 150 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/中發佈問題。 – 2017-04-15 11:39:38

0
  1. 許多FFT實現都是保持能量的。這意味着輸出的比例與輸入的比例和/或大小成線性關係。

  2. FFT是DFT是方陣變換。所以輸出的數量總是等於輸入的數量(或者通過忽略嚴格實數輸入的冗餘複共軛一半的數量),除非有些輸出被丟棄。如果不是,那不是一個FFT。如果您想減少輸出,可以採用其他方式對FFT輸出進行縮減採樣或後處理。