2013-06-28 59 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块大。你真棒! –