2013-04-26 51 views
0

我一直在使用this代碼來讀取delphi中的.wav數據,我一直在比較結果與我從matlab函數wavread得到的值。從中我可以說,matlab函數可以自動識別哪一個是樣本數據值,但不能用delphi(但matlab和delphi代碼的結果都是一樣的)。由於我的delphi代碼無法識別樣本數據值,因此我查看了數組,發現樣本數據值啓動的索引與每個.wav文件不同。舉一個例子我測試一些.wav文件,並獲得這樣的:.wav示例數據值起始索引?

  1. classic1.wav的採樣數據值開始上wavedata []數據[]索引號40
  2. classic2.wav的採樣數據值開始上wavedata []。Data [] index number 35

我通過查看結果y,[y,然後我去結果delphi返回一個數組中檢查它的值,並找到完全相同的值開始在索引40爲classic1.wav和35爲classic2.wav。我想知道是否有方法可以知道每個.wav文件的樣本數據值的起始索引?

編輯:我已更正類似reference給出的記錄,它是完全正確的頭(從ChunkID到Subchunk2size),但我仍然對後面的示例數據感到困惑,因爲從前面的結果沒有變化。

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; 
    NumChannels: word; 
    SampleRate: longint; 
    ByteRate: longint; 
    BlockAlign:word; 
    BitsPerSample: word; 


    Marker_data: array [0..3] of char; 
    DataBytes: longint; 
    end; 

    TChannel = record 
    Data : array of smallint; 


end; 
+0

IIRC一個簡單的WAVE文件以RIFF塊描述符開頭,後面跟着一個RIFF子標題,後面跟着一個[WAVEFORMATEX](http://msdn.microsoft.com/en-us/library/windows/desktop/dd390970( v = vs.85).aspx)結構。 [我已經寫了真正的WAVE編碼器/解碼器,但那是幾年前,我不記得所有的細節。我所知道的其實很簡單。] – 2013-04-26 17:09:10

+0

Andreas提出了一個很好的觀點,你應該重新訪問你的結構聲明並根據[規範]進行拆分(https://ccrma.stanford.edu/courses/422/projects/ WaveFormat /) – OnTheFly 2013-04-26 17:32:46

+0

是的,我已根據規格進行重構,它至少直到Subchunk2Size,但沒有跟隨它的數據。我不知道我在做什麼錯誤 – 2013-04-27 01:42:24

回答

4

你顯然沒有正確跳過所有的頭字段。 Wav文件可以有一些可選的標題信息,所以雖然實際的樣本值通常在字節44開始,但這並不是總是的情況。

在這裏看到,例如:直接跳到樣本數據https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

一種方法是掃描的ASCII字符串的文件(一次四個字節)(閱讀任何你需要的頭部的部分內容後)數據「(64 61 74 61 hex),然後讀取緊隨其後的4個字節,其中(作爲基數或長字)表示要讀取的字節總數。實際樣本緊隨該基數之後。

編輯:

正如預期的那樣,看着文件Classic1.wav和Classic2.wav在十六進制編輯器很明顯,他們都有一些元數據。在每個文件的位置36處,而不是找到「數據」的SubchunkID,而是找到「LIST」。接下來的四個字節給出了這個附加數據的大小。這是您必須跳過才能看到音樂樣本數據。

例如,Classic1.wav從偏移量44開始有148字節的額外數據。這將Subchunk2ID放置在偏移量192,Subchunk2Size放置在偏移量196,這意味着第一個樣本從文件中的偏移量200開始。

Classic2.wav從偏移量44開始有128字節的額外數據。這將Subchunk2ID放置在偏移量172處,Subchunk2Size放置在偏移量176處,這意味着第一個樣本從文件中的偏移量180開始。

這是Classic2。WAV在一個非常基本的十六進制編輯器: enter image description here

+0

存儲在數據塊前面的數字是樣本數據使用的**字節數**。 **數量的樣本**實際上存儲在一個單獨的「事實」塊中。請記住,音頻採樣不需要,通常不是,8位大小。 – 2013-04-26 20:12:10

+0

@Stuart我該如何掃描並查看「數據」?其實我只是開始使用delphi,也許你可以給我一個例子? – 2013-04-27 02:10:32

+0

@Remy。是的你是對的,它是*字節*的總數,而不是樣本。我會編輯它來糾正。謝謝。 – Stuart 2013-04-27 04:56:09

3

,而不是做的所有的文件I/O手動,你應該使用Win32多媒體API函數來代替 - mmioOpen()mmioDescend()mmioAscend()mmioRead()等讓他們做的所有你辛苦的工作。您的代碼將更易於管理和閱讀,因爲您將能夠更專注於各個塊的內容,同時讓API處理查找每個塊的底層細節。

+0

MSDN幫助說mmioOpen已棄用? – 2014-04-07 17:14:24

+0

我不知道爲什麼MSDN說,考慮到其他多媒體功能不被棄用,'mmioOpen()'是以兼容的方式打開文件的唯一方法。 'CreateFile()'不能代替'mmioOpen()'的作用。如果你切換到'CreateFile()',你必須手動處理所有的降序/升序邏輯,這就違背了爲你提供多媒體API的目的。 – 2014-04-07 20:21:32

+0

MSDN,撰寫文檔的人從來沒有想過這樣的事情。 – 2014-04-07 20:50:28