2013-06-28 61 views
1

這是我的代碼部分用於讀取.wav文件使用mmio函數讀取列表塊失敗?

//Variable 
    wavehdr:TWaveHeader; 
    ckiRIFF,ckiFmt,ckiData,ckiLIST: TMMCKInfo; 
    mmioinfo: PMMIOInfo; 
    waveFmt: TWaveFormatEx; 
    buf: Array of smallint; 
    buf_recon: Array of double; 
    list:Array of longint; // THIS IS MY GUESS so it's definetly not work 
    HMMIO: hFile; 

    //Locate the "RIFF" chunk 
    ckiRIFF.fccType := mmioStringToFOURCC('WAVE',0); 
    mmioDescend(HMMIO, @ckiRIFF, nil, MMIO_FINDRIFF); 
    mmioAscend(HMMIO, @ckiRIFF, MMIO_FINDRIFF); 

    //Locate the "FMT" subchunk 
    ckiFmt.ckid := mmioStringToFOURCC('fmt', 0); 
    mmioDescend(HMMIO, @ckiFmt, nil, MMIO_FINDCHUNK); 
    mmioRead(HMMIO, @waveFmt, ckiFmt.cksize); 
    mmioAscend(HMMIO, @ckiFmt, 0); 

    //Locate the "LIST" chunk (THIS PART IS NOT WORK) 
    ckiLIST.fccType := mmioStringToFOURCC('LIST',0); 
    mmioDescend(HMMIO, @ckiLIST, nil, MMIO_FINDLIST); 
    mmioRead(HMMIO, @list, ckiLIST.cksize); 
    mmioAscend(HMMIO, @ckiFmt, 0); 

    //Locate the "data" subchunk 
    ckiData.ckid := mmioStringToFOURCC('data', 0); 
    if (mmioDescend(HMMIO, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then begin 
    SetLength(buf, ckiData.cksize); 
    mmioRead(HMMIO, PAnsiChar(buf), ckiData.cksize); 

而且它的工作只是完美,直到我意識到我錯過了LIST塊,這裏我只設法獲得「LIST」。這裏文件之前,我閱讀和寫回,並有單塊,它的數據enter image description here

這裏的例子是後我閱讀和寫回enter image description here

標誌着我走了一部分。所以,如果有人知道我錯在這裏請大家幫我

編輯1

enter image description here

回答

2

存在諸多問題與您的代碼:

  1. 你是不是檢查錯誤。
  2. 在讀取列表之前,您沒有爲列表分配任何內存。
  3. 無論如何,您並沒有正確讀取「LIST」塊,因爲WAV文件中沒有「LIST」塊開頭。你試圖閱讀的是一個「INFO」塊,它是一個LIST類型。因此,您必須找到並下降到「INFO」塊中,根據需要下降並讀取其子塊,然後重新上升到RIFF塊。
  4. 當您不應該時,您正在從「RIFF」塊中提升。

試試這個:

var 
    wavehdr: TWaveHeader; 
    ckiRIFF, ckiFmt, ckiData, ckiLIST, ckiINAM: TMMCKInfo; 
    mmioinfo: PMMIOInfo; 
    waveFmt: TWaveFormatEx; 
    buf: Array of smallint; 
    buf_recon: Array of double; 
    HMMIO: hFile; 
begin 
    ... 
    //Locate the "RIFF" chunk 
    ckiRIFF.fccType := mmioStringToFOURCC('WAVE',0); 
    if mmioDescend(HMMIO, @ckiRIFF, nil, MMIO_FINDRIFF) = 0 then 
    begin 
    //Locate the "FMT" subchunk 
    ZeroMemory(@waveFmt, SizeOf(waveFmt)); 
    ckiFmt.ckid := mmioStringToFOURCC('fmt', 0); 
    if mmioDescend(HMMIO, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = 0 then 
    begin 
     // technically, you should use a dynamic-length buffer instead of a static buffer 
     mmioRead(HMMIO, @waveFmt, ckiFmt.cksize); 
     mmioAscend(HMMIO, @ckiFmt, 0); 
    end; 

    //Locate the "INFO" chunk 
    ckiLIST.fccType := mmioStringToFOURCC('INFO', 0); 
    if mmioDescend(HMMIO, @ckiLIST, @ckiRIFF, MMIO_FINDLIST) = 0 then 
    begin 
     //Locate the "INAM" chunk 
     ckiINAM.fccType := mmioStringToFOURCC('INAM', 0); 
     if mmioDescend(HMMIO, @ckiINAM, @ckiLIST, MMIO_FINDCHUNK) = 0 then 
     begin 
     // read chunk data as needed... 
     mmioAscend(HMMIO, @ckiINAM, 0); 
     end; 
     mmioAscend(HMMIO, @ckiLIST, 0); 
    end; 

    //Locate the "data" subchunk 
    ckiData.ckid := mmioStringToFOURCC('data', 0); 
    if (mmioDescend(HMMIO, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then 
    begin 
     SetLength(buf, ckiData.cksize); 
     mmioRead(HMMIO, PAnsiChar(buf), ckiData.cksize); 
     mmioAscend(HMMIO, @ckiData, 0); 
    end; 
    ... 
    end; 
    ... 
end; 
+0

我也跟着你的建議,但結果卻是這樣的編輯1 –

+0

好像我錯過了什麼,這部分//讀取的塊數據的需要......我應該使用mmioRead(HMMIO,@inam,ckiINAM.cksize); ?以及我需要存儲什麼變量? –

+0

好吧,我想出來感謝你的人。我仍然在挖掘它,因爲不是所有的wav文件都有INAM塊,而且有些INAM塊可能比存儲創建文件日期的塊等INAM塊大。你真棒! –