我想採用一個大小爲70-80k的字節數組,並將它們從時域轉換到頻域(可能使用DFT)。到目前爲止,我一直在關注wiki並獲得此代碼。如何將一組離散的數據傳輸到頻域並返回(最好是無損地)
for (int k = 0; k < windows.length; k++) {
double imag = 0.0;
double real = 0.0;
for (int n = 0; n < data.length; n++) {
double val = (data[n])
* Math.exp(-2.0 * Math.PI * n * k/data.length)
/128;
imag += Math.cos(val);
real += Math.sin(val);
}
windows[k] = Math.sqrt(imag * imag + real
* real);
}
並據我所知,它發現每個頻率窗口/ bin的幅度。然後,我穿過窗戶,找到最高級別的窗戶。我添加一個標誌到該頻率重建信號時使用。我檢查重建的信號是否與我的原始數據集匹配。如果沒有找到下一個最高頻率窗口並標記重建信號時要使用的頻率窗口。
這裏是我有用於重建其我大多一定的信號中的代碼是非常錯誤的(它應該執行IDFT):
for (int n = 0; n < data.length; n++) {
double imag = 0.0;
double real = 0.0;
sinValue[n] = 0;
for (int k = 0; k < freqUsed.length; k++) {
if (freqUsed[k]) {
double val = (windows[k] * Math.exp(2.0 * Math.PI * n
* k/data.length));
imag += Math.cos(val);
real += Math.sin(val);
}
}
sinValue[n] = imag* imag + real * real;
sinValue[n] /= data.length;
newData[n] = (byte) (127 * sinValue[n]);
}
freqUsed用來標誌是否一個布爾陣列重建信號時不應使用頻率窗口。
無論如何,這裏是出現的問題:
- 即使所有頻率窗口的使用,信號不會重建。這可能是由於以下事實...
- 有時Math.exp()的值太高,因此返回無窮大。這使得難以精確計算。
- 雖然我一直在關注wiki作爲指導,但很難判斷我的數據是否有意義。這使得很難測試和識別問題。
副手從問題:
我是相當新的這一點,並沒有完全明白了一切。因此,任何幫助或見解是值得讚賞的。感謝您花時間閱讀所有內容,並提前感謝您提供的任何幫助。任何幫助真的會很好,即使你認爲我正在做這個最糟糕的可能的方式,我想知道。再次感謝。
-
編輯:
所以我更新了我的代碼看起來像:
for (int k = 0; k < windows.length; k++) {
double imag = 0.0;
double real = 0.0;
for (int n = 0; n < data.length; n++) {
double val = (-2.0 * Math.PI * n * k/data.length);
imag += data[n]*-Math.sin(val);
real += data[n]*Math.cos(val);
}
windows[k] = Math.sqrt(imag * imag + real
* real);
}
原始變換和:
for (int n = 0; n < data.length; n++) {
double imag = 0.0;
double real = 0.0;
sinValue[n] = 0;
for (int k = 0; k < freqUsed.length; k++) {
if (freqUsed[k]) {
double val = (2.0 * Math.PI * n
* k/data.length);
imag += windows[k]*-Math.sin(val);
real += windows[k]*Math.cos(val);
}
}
sinValue[n] = Math.sqrt(imag* imag + real * real);
sinValue[n] /= data.length;
newData[n] = (byte) (Math.floor(sinValue[n]));
}
的逆變換。雖然我仍然擔心它不能正常工作。我生成一個數組,持有一個單一的正弦波,它甚至不能分解/重建。任何有關我失蹤的信息?
如果有任何更多信息可以幫助解決問題,請告訴我,我很樂意發佈。 – Matt
我改變了我的代碼,以便它不再將值轉換成域[-1,1]並將它們留下[-128,127] ...它仍然不起作用。 – Matt
如果你的正弦波相對於其核心頻率窗口是相移的或者它的週期不是任何頻率窗口週期的乘法,那麼你的DFT不能保證重構的有效數據集合是頻域信號重構的基本問題。爲了解決這個問題,你必須有足夠多的樣本,有時甚至可以在DFT/IDFT之前轉換信號來同步你的DFT/IDFT ... – Spektre