2013-04-24 138 views
1

我試圖做濾波使用HAAR式的.wav採樣數據值,但遇到錯誤「浮點溢出」如何處理浮點溢出?

編輯:添加更多的代碼

numsamples := round(wavehdr.SampleRate); 
SetLength(wavedata[0].Data, numsamples); 
Stream.Read(wavedata[0].Data[0], numsamples); 
SetLength(cA1, numsamples); 
SetLength(cD1, numsamples); 
for i:=1 to numsamples-1 do begin 
cA1[i]:=(wavedata[0].Data[(i*2)-1]*0.7071) + (wavedata[0].Data[(i*2)]*0.7071); 
cD1[i]:=(wavedata[0].Data[(i*2)-1]*0.7071) + (wavedata[0].Data[(i*2)]*-0.7071); 
end; 

其中wavedata [0]。數據[我],我從函數Stream.Read獲取它加載.wav文件的示例數據值。我不知道爲什麼我得到了錯誤,或者錯誤的含義,我一直在尋找大部分由零引起的錯誤,但是在我的代碼中沒有零的分割。所以也許我可以在這裏幫助一下在我的代碼中的錯誤意味着什麼?

編輯1:(我真的很新的德爾福,這個代碼是不是我的,我發現它的互聯網在我的理解下面的代碼是一個讀.wav文件的採樣數據值。)

type 
    TWaveHeader = packed record 

    Marker_RIFF: array [0..3] of char; 
    ChunkSize: cardinal; 


    Marker_WAVE: array [0..3] of char; 


    Marker_fmt: array [0..3] of char; 
    SubChunkSize: cardinal; 


    FormatTag: word; 

    { nChannels : 1 mono, 2 stereo } 
    NumChannels: word; 
    SampleRate: longint; 
    BytesPerSecond: longint; 
    BytesPerSample: word; 
    BitsPerSample: word; 


    Marker_data: array [0..3] of char; 


    DataBytes: longint; 
    end; 

    TChannel = record 

    Data : array of double; 
    end; 

和私人聲明:

private 
    wavehdr:TWaveHeader; 

功能:

FillChar(wavehdr, sizeof(wavehdr),0); 
Stream.Read(wavehdr,sizeof(wavehdr)); 

我修改了一下的代碼以在讀取樣本數據處理空值:當表達式產生不適合在其中表達式求值的數據類型的範圍內的值時,發生

if(IsNan(wavedata[0].Data[(i*2)-1])) then begin 
     wavedata[0].Data[(i*2)-1]:=0; 
    end 
    else if(IsNan(wavedata[0].Data[(i*2)])) then begin 
     wavedata[0].Data[(i*2)]:=0; 
    end; 
+0

如何是cA1,cD1和wavedata [0] .Data是否聲明? – 2013-04-24 05:46:31

+0

cA1 cD1和wavedata都是雙倍數組。其中wavedata數組可能包含的值如:0,1.98E-04等(它是樣本.wav數據的值) – 2013-04-24 05:50:55

+0

結果是大到你的float中保存試試看懂使用數學; procedure TForm6.Button1Click(Sender:TObject); var f:Double; begin f:= MaxDouble; f:= F * 2; Showmessage(FloatToStr(F)) end; Showmessage(FloatToStr(F)) end; – bummi 2013-04-24 05:51:49

回答

6

i:=0 ...

(wavedata[0].Data[(i*2)-1]

你真的有數組元素Data[-1]

P.S.調試時設置範圍檢查編譯器選項。

編輯:我看到了一些新的代碼,讓我們一起去第2步:

SetLength(wavedata[0].Data, **numsamples**); 

for i:=1 to **numsamples**-1 

wavedata[0].Data[(**i*2)**] 

難道我們要檢查徹底的每一行代碼?

+0

這是一個非常可能的解釋。 +1 – 2013-04-24 09:47:00

+0

@DavidHeffernan看起來很奇怪,我已經看到(並且有個人挑戰去調試)大型代碼庫,其中一些數組從0開始,一些在1,一些在-1,一些在-2等。這是一個可能的解釋。 – 2013-04-24 10:30:16

+0

耶對不起,這也是一個錯誤,但我改變後我:= 0我:= 1我仍然得到同樣的錯誤。 – 2013-04-24 14:43:17

4

溢出。正數和負數可能會發生溢出。

如果輸入值已經接近溢出浮點值,那麼您的特定表達式只會導致溢出。因此,如果您使用雙精度值,那麼只有當輸入數據的幅度大約爲1e308時,您的代碼纔會溢出。

您的輸入數據似乎不太可能是這種形式。所以我的猜測是你的問題與你如何閱讀你的輸入數據有關。我懷疑你是不正確地閱讀它,所以最終對無意義的值進行算術運算。

+0

對於像我這樣的初學者來說,這是一個很好的解釋:D。是的,我有一些價值,我認爲它超出了數據類型範圍的範圍,例如:1.39073482014559E-309,4.2399158143648E-314等等。我使用我發現的一些代碼讀取了我的輸入數據,也許我會編輯併發布它,以便您可以看到它們。 – 2013-04-24 14:47:35

+0

我已經發布了更多的代碼來添加細節如何閱讀.wav值,也許你可以糾正我,如果我做錯了? – 2013-04-24 14:59:54

+0

我想我回答了你問的原始問題。這本質上是相當一般的。我無法詳細調試代碼的細節。我確定您的輸入數據被錯誤地讀取。 – 2013-04-24 16:06:46

0

當我嘗試這個,並且我發現了自己的錯誤,感謝@MBo縮小mw焦點的答案,這對我來說真的很愚蠢。該循環應該像

for i:=0 to round(numsamples/2) do begin 

它不是元素數據[-1],該問題,但是,如果陣列wavedata = X的長度,然後我嘗試達到的元素[X * 2]其是不一半後肯定會導致錯誤。例如數組[4],但我嘗試達到數組[4 * 2]這是不可用(對不起我英語不好,我不知道我的解釋是否好)但謝謝大家的幫助:D

+0

這不會增加MBo的答案。你應該接受這個答案並刪除它。 – 2013-04-24 21:22:32