2015-08-15 95 views
1

我有一些FFT數據,257維,每10毫秒,121幀,即1.21秒。我想第一維可能是別的,剩下的就是FFT係數。 這可能只是譜圖數據。根據關於FFT數據的評論,sqrt10和平均方差標準化可能已應用於此。轉換FFT到PCM

從那裏,我想計算回一些44.1赫茲的PCM信號,所以我可以播放聲音。我問same question in a more mathematical way here,但也許StackOverflow是一個更好的地方,因爲我真的想要實現這一點。 我也問過關於理論here on DSP SE的同樣問題。

我該怎麼做?也許我需要一些更多的信息(我必須找出來) - 哪一個?也許這些缺失的信息可以被智能地猜到?

這個問題是關於理論和實際實施。我猜想這個實現是微不足道的。但某些語言的具體例子對幫助理解理論很有幫助。也許C++與FFTW?我跳過了FFTW文檔,但我無法理解所有的術語和背景,例如here。爲什麼從複雜到現實或其他方式,我只想要真實。 REDFT是什麼?什麼是DCT,DFT,DST? FFTW_HC2R?

我把所有的FFT數據,即121 * 257個浮點數,讀入矢量freq_bins

std::vector<float32_t> freq_bins; // FFT data 
int freq_bins_count = 257; 
size_t len = 121; 

std::vector<float32_t> pcm; // output, PCM data 

int N = freq_bins_count; 
std::vector<double> out(N), orig_in(N); 

// inspiration: https://stackoverflow.com/questions/2459295/invertible-stft-and-istft-in-python/6891772#6891772 
for(int f = 0; f < len; ++f) { 
    size_t pos = freq_bins_count * f; 
    for(int i = 0; i < N; ++i) 
     out[i] = pow(freq_bins[pos + i] + offset, 10); // fft was sqrt10 + mvn 
    fftw_plan q = fftw_plan_r2r_1d(N, &out[0], &orig_in[0], FFTW_REDFT00, FFTW_ESTIMATE); 
    fftw_execute(q); 
    fftw_destroy_plan(q); 

    // naive overlap-and-add 
    auto start_frame = size_t(f * dt * sampleRate); 
    for(int i = 0; i < N; ++i) { 
     sample_t frame = orig_in[i] * scale/(2 * (N - 1)); 
     size_t idx = start_frame + i; 
     while(idx >= pcm.size()) 
      pcm.push_back(0); 
     pcm[idx] += frame; 
    } 
} 

但我猜這是錯誤的。我只是得到垃圾。

相關可能是this question。或this

+0

鑑於您正在討論實現(而不是理論),並且在下面的評論中提到了庫,您應該使用您打算使用的語言來標記此問題... –

+0

@OliverCharlesworth:這是關於兩者,或者甚至更多關於這個理論。我猜想這個實現是微不足道的。但某些語言的具體例子對幫助理解理論很有幫助。也許C++與FFTW?我跳過了FFTW文檔,但我無法理解所有的術語和背景,例如[這裏](http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data)。爲什麼從複雜到現實或其他方式,我只想要真實。 REDFT是什麼?什麼是DCT,DFT,DST?等 – Albert

+0

如果問題是關於理論的話,那麼http://dsp.stackexchange.com可能是您最好的選擇。 –

回答

0

您只需通過逆傅里葉變換即可推送您的數據。所有的FFT庫都提供前向和後向轉換功能。

+0

你能否提供一些信息?目前我不使用這樣的圖書館。我將使用哪一個以及如何獲取PCM數據?也許你可以給一些庫的一些例子代碼? – Albert

2

如果您擁有的數據是真實的,那麼你擁有的數據是最有可能spectrogram數據,如果您收到的數據是複雜的,那麼你極有可能不得不原料short time fourier transform(STFT)數據(參見this後的圖瞭解如何生成STFT /光譜圖數據)。頻譜圖數據是通過取STFT數據的幅度平方產生的,因此是不可逆的,因爲音頻信號中的所有相位信息已經丟失,但原始STFT數據是可逆的,所以如果這是你所擁有的,那麼你可能想要尋找庫,執行反STFT功能並嘗試使用它。

至於數據中FFT尺寸代表什麼問題,我估計你每10ms接收到的257個數據點是STFT過程中使用的512點FFT的結果。第一個例子是0Hz頻率,其餘256個數據點是FFT頻譜的一半(另一半FFT數據已被丟棄,因爲FFT的輸入是實數,所以一半的FFT數據只是複數共軛的另一半)。

除此之外,我想指出的是,僅僅因爲您每隔10ms接收一次FFT數據121次並不意味着音頻信號是1.21。STFT通常是通過使用重疊窗口產生的,因此您的音頻信號可能短於1.21s。

+0

我只有這257個尺寸。即使我不能再現真實信號,我是否可以以某種方式再現某些會產生相同FFT數據的信號? – Albert

+0

簡單地說,如果你有原始STFT數據(即你有代表音頻複數的矩陣頻率數據),那麼你可以反轉的數據,讓你的音頻信號回來,但如果你有頻譜數據(即頻率數據你有一個代表數據的實數矩陣),那麼你將無法反轉它,或者甚至得到一個接近原始信號的信號,因爲所有的相位信息都被丟棄了。有關反轉STFT的更多信息,請參閱: http://eeweb.poly.edu/iselesni/EL713/STFT/stft_inverse.pdf – KillaKem

+0

我只是真實數據(或者是128 +複雜的現實1的那些257點的尺寸?但它們看起來都一樣,所以我想257真正更有意義)。所以我想這就是譜圖(你是如何從原始STFT?sqrt(abs(fft))左右得到的?)。我不能以某種方式重新創建某些階段數據嗎?如果我只是假設0或任何東西,我會回到相同的譜圖?如果不是,我可以以某種方式猜測相位數據,以便得到相同的譜圖?或者你是否說同一個譜圖的兩個聲音聽起來完全不同?這是爲什麼?這對我來說非常直觀。 – Albert