1

这是我读取 .wav 文件的代码的一部分

    //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”。这是我读取和写回文件之前的文件示例,并且有列表块及其数据在此处输入图像描述

这是在我读完并写回来之后在此处输入图像描述

我标记的部分不见了。所以如果有人知道我的错误在这里请帮助我

编辑 1

在此处输入图像描述

4

1 回答 1

2

你的代码有很多问题:

  1. 您没有检查错误。
  2. 在读取列表之前,您没有为列表分配任何内存。
  3. 无论如何,您都没有正确读取“LIST”块,因为 WAV 文件中没有“LIST”块开始。您要阅读的是一个“信息”块,它是一个 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;
于 2013-06-28T20:43:19.230 回答