Это часть моего кода для чтения файла .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

enter image description here

1
Wawan Ma-chun 28 Июн 2013 в 21:39

1 ответ

Лучший ответ

С вашим кодом много проблем:

  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;
2
Remy Lebeau 29 Июн 2013 в 00:43
Я последовал твоему предложению, но результат похож на это редактирование 1
 – 
Wawan Ma-chun
29 Июн 2013 в 06:55
Похоже, что я что-то пропустил, эта часть // считывает данные фрагмента по мере необходимости ... следует ли мне использовать mmioRead (HMMIO, @inam, ckiINAM.cksize); ? и какая переменная мне нужна для его хранения?
 – 
Wawan Ma-chun
29 Июн 2013 в 07:02
Хорошо, я понял это благодаря тебе, чувак. Я все еще копаюсь в нем, потому что не все файлы wav имеют фрагмент INAM, более того, у некоторых может быть больше, чем фрагмент INAM, например, фрагмент, в котором хранится дата создания файла и т. д. Вы УДИВИТЕЛЬНЫЙ человек ..
 – 
Wawan Ma-chun
29 Июн 2013 в 12:52