⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmwaveio.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
begin
   Result := WIOERR_FILEERROR;
   lpwio  := nil;

   if wioCreateFileInfo(lpwio, pwfx) = WIOERR_NOERROR then
   begin
      h := FileOpen(StrPas(lpFileName), fmOpenRead or fmShareDenyNone);
      if (h <> $FFFFFFFF) then
      with lpwio^ do
      begin
         dwFlags      := RAW_FILE;
         dwFileSize   := FileSeek(h, 0, 2);
         dwDataBytes  := dwFileSize-DataOffset;

         dwDataOffset := DataOffset;
         dwDataSamples:= wioBytesToSamplesEx(lpwio,dwDataBytes);

         dwFirstSample:= 0;
         dwLastSample := dwDataSamples;
         dwBytesLeft  := 0;
         dwPosition   := 0;

         lpFilePath   := StrNew(lpFileName);

         FileClose(h);
         Result := WIOERR_NOERROR;
      end
      else wioFreeFileInfo(lpwio);
   end;
end;

{**************************************************************************}
function  wioBuildFileInfoFromRAW(Var lpwio: PWaveIOCB; lpFileName: PChar;
                                  DataOffset, BitLength,
                                  Channels, SampleRate: DWORD): integer;
var
   wfx: TWaveFormatEx;
begin
   pcmBuildWaveHeader(@wfx,BitLength,Channels,SampleRate);
   Result := wioBuildFileInfoFromRAWEx(lpwio,lpFileName,DataOffset,@wfx);
end;

{**************************************************************************}
function wioWriteFileInfo(Var lpwio: PWAVEIOCB; lpFilePath: PChar): integer;
Label ERROR_CANNOT_WRITE;
Var
   hmmio: THMMIO;
   ckDATA, ckRIFF: TMMCKINFO;
   dw: Longint;

begin
    { default our error return (assume the worst) }
    Result := WIOERR_FILEERROR;
    hmmio := 0;

    { validate a couple of things }
    if (lpwio = Nil) or (lpFilePath = Nil) then
    begin
       Result := WIOERR_BADPARAM;
       goto ERROR_CANNOT_WRITE;
    end;

    { yes, this is the open... }
    hmmio := mmioOpen(lpFilePath, Nil, MMIO_CREATE or MMIO_READWRITE or MMIO_ALLOCBUF);
    if (hmmio = 0) then
       goto ERROR_CANNOT_WRITE;

    { create the RIFF chunk of form type 'WAVE' }
    ckRIFF.fccType := mmioFOURCC('W', 'A', 'V', 'E');
    ckRIFF.cksize  := 0;
    if mmioCreateChunk(hmmio, @ckRIFF, MMIO_CREATERIFF) <> 0 then
       goto ERROR_CANNOT_WRITE;

    { now create the destination fmt and data chunks _in that order_       }
    { hmmio is now descended into the 'RIFF' chunk--create the format chunk}
    { and write the format header into it                                  }
    dw := wioSizeOfWaveFormat(@lpwio^.wfx);

    ckDATA.ckid := mmioFOURCC('f', 'm', 't', ' ');
    ckDATA.cksize := dw;
    if mmioCreateChunk(hmmio, @ckDATA, 0) <> 0 then
       goto ERROR_CANNOT_WRITE;

    { Write the WAVEFORMAT structure to the 'fmt ' chunk. }
    if mmioWrite(hmmio, @lpwio^.wfx, dw) <> dw then
       goto ERROR_CANNOT_WRITE;

    { Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. }
    if mmioAscend(hmmio, @ckDATA, 0) <> 0 then
       goto ERROR_CANNOT_WRITE;

    { create the data chunk AND STAY DESCENDED... for reasons that }
    { will become apparent later..                                 }
    ckDATA.ckid   := mmioFOURCC('d', 'a', 't', 'a');
    ckDATA.cksize := 0;
    ckData.dwFlags:= MMIO_DIRTY;
    if mmioCreateChunk(hmmio, @ckDATA, 0) <> 0 then
       goto ERROR_CANNOT_WRITE;

    { to close the file do:
    mmioAscend(hmmio, @ckData, 0);
    mmioAscend(hmmio, @ckRIFF, 0);
    mmioClose(hmmio, 0); }

    { cool! no problems.. }
    lpwio^.hmmio         := hmmio;
    lpwio^.ckRIFF        := ckRIFF;
    lpwio^.ckDATA        := ckDATA;
    lpwio^.dwDataOffset  := ckDATA.dwDataOffset;
    lpwio^.lpFilePath    := StrNew(lpFilePath);
    lpwio^.dwDataSamples := wioBytesToSamplesEx(lpwio, lpwio^.dwDataBytes);
    lpwio^.dwFirstSample := 0;
    lpwio^.dwLastSample  := lpwio^.dwDataSamples;

    Result := WIOERR_NOERROR;
    exit;

    { return error (after minor cleanup) }
ERROR_CANNOT_WRITE:

    if (hmmio <> 0) then
       mmioClose(hmmio, 0);    { close the new file }

    { delete the half-written file. }
    wioFileDelete(lpFilePath);
end;

{**************************************************************************}
function wioFreeFileInfo(Var lpwio: PWAVEIOCB): integer;
begin
     { validate a couple of things... }
     if (lpwio = Nil) then
     begin
	  Result := WIOERR_BADPARAM;
          exit;
     end;

     { get rid of stuff... }
     if (lpwio^.hmmio <> 0) then
     begin
          if (lpwio^.dwFlags and RAW_FILE <> 0) then
              FileClose(lpwio^.hmmio)
          else
              mmioClose(lpwio^.hmmio, 0);
	  lpwio^.hmmio := 0;
     end;

     if (lpwio^.lpFilePath <> Nil) then
        StrDispose(lpwio^.lpFilePath);

     if (lpwio^.lpInfo <> Nil) then
	RiffFreeINFO(lpwio^.lpInfo);

     if (lpwio^.lpDisp <> Nil) then
	RiffFreeDISP(lpwio^.lpDisp,True);

     GlobalFreeMem(Pointer(lpwio));
     lpwio := Nil;

     Result := WIOERR_NOERROR;
end;

(**************************************************************************
 * This routine will copy from a source wave file to a destination wave
 * file all those useless chunks (well, the ones useless to conversions,
 * etc --> apparently people use them!). The source will be seeked to the
 * begining, but the destination has to be at a current pointer to put the
 * new chunks. This will also seek back to the start of the wave riff
 * header at the end of the routine.
 *
 * Both files must be open !!!
 *
 * Returns 0 if successful, else the error code. If this routine fails, it
 * still attemps to seek back to the start of the wave riff header, though
 * this too could be unsuccessful.
 **************************************************************************)
function wioWaveCopyUselessChunks(lpwioSrc, lpwioDst: PWaveIOCB): integer;
Label COPY_ERROR;
begin
     Result := WIOERR_FILEERROR;
     { First seek to the start of the file, not including the riff header }
     with lpwioSrc^ do
     begin
        if mmioSeek(hmmio, ckRIFF.dwDataOffset + sizeOf(FOURCC), SEEK_SET) = -1 then
           goto COPY_ERROR;

        while mmioDescend(hmmio, @ckDATA, @ckRIFF, 0) = 0 do
        begin
           { quickly check for corrupt RIFF file--don't ascend past end! }
           if (ckData.dwDataOffset + ckDATA.cksize > ckRIFF.dwDataOffset + ckRIFF.cksize) then
              goto COPY_ERROR;

           { copy chunks that are OK to copy }
           if ckDATA.ckid = mmioFOURCC('c', 'u', 'e', ' ') then
              { it doesn't make much sense }
              RiffCopyChunk(hmmio, lpwioDst^.hmmio, @ckDATA)

           else if ckDATA.ckid = mmioFOURCC('p', 'l', 's', 't') then
              { although without the 'cue' chunk, it doesn't make much sense }
              RiffCopyChunk(hmmio, lpwioDst^.hmmio, @ckDATA)

           { don't copy unknown chunks }
           else break;

           { step up to prepare for next chunk.. }
           mmioAscend(hmmio, @ckDATA, 0);
        end;
     end;

     Result := WIOERR_NOERROR;

COPY_ERROR:

     { Seek back to source RIFF header }
     with lpwioSrc^ do
     mmioSeek(hmmio, ckRIFF.dwDataOffset + sizeof(FOURCC), SEEK_SET);
end;

{**************************************************************************}
(* TODO: does not work !? mmioGetInfo returns in cchBuffer bad size !!!???*)
function wioSetIOBufferSize(lpwio: PWaveIOCB; dwSize: integer): integer;
begin
     Result := WIOERR_BADPARAM;

     { validate a couple of things... }
     if (lpwio = Nil) then exit;

     Result := WIOERR_ERROR;

     if (lpwio^.dwFlags and RIFF_MEMORY <> 0) or
        (lpwio^.dwFlags and RIFF_RESOURCE <> 0) or
        (lpwio^.dwFlags and RAW_FILE <> 0) then
        Result := WIOERR_NOERROR
     else if (lpwio^.hmmio <> 0) and (dwSize >= 0) then
        Result := mmioSetBuffer(lpwio^.hmmio, Nil, dwSize, 0);
end;

{**************************************************************************}
function wioWaveOpen(lpwio: PWaveIOCB): integer;
begin
     Result := WIOERR_BADPARAM;

     { validate a couple of things... }
     if (lpwio = Nil) then exit;

     Result := WIOERR_FILEERROR;

     { (re)open the file }
     if (lpwio^.hmmio = 0) then
     with lpwio^ do
     begin
        if (dwFlags and RAW_FILE <> 0) then
            hmmio := FileOpen(StrPas(lpFilePath),fmOpenRead or fmShareDenyNone)
        else wioFileOpen(hmmio, ckRIFF, hMem, lpFilePath,
                         mmioFOURCC('W', 'A', 'V', 'E'),dwFlags);
     end;

     { set start position }
     if (lpwio^.hmmio <> 0) then
        if wioWaveSetPosition(lpwio, lpwio^.dwPosition) = 0 then
           Result := WIOERR_NOERROR;
end;

{**************************************************************************}
function wioWaveClose(lpwio: PWaveIOCB): integer;
Label ERROR_CANNOT_WRITE;
Var
   mmioInfo: TMMIOINFO;

begin
     Result := WIOERR_NOERROR;
     if (lpwio = Nil) or (lpwio^.hmmio = 0) then exit;

     with lpwio^ do
     begin
        Result := WIOERR_FILEERROR;

        if (dwFlags and RAW_FILE = 0) and
           (ckData.dwFlags and MMIO_DIRTY <> 0) then
        begin
           if mmioGetInfo(hmmio, @mmioInfo, 0) <> 0 then
              goto ERROR_CANNOT_WRITE;

           if mmioFlush(hmmio,0) <> 0 then
              goto ERROR_CANNOT_WRITE;    { cannot write file, probably }

           if mmioInfo.dwFlags and MMIO_CREATE = 0 then
           begin
              { rewrite the size of data chunk }
              ckData.cksize := 0;
              ckData.dwFlags:= ckData.dwFlags or MMIO_DIRTY;

              { seek to the end of the chunk first }
              if mmioSeek(hmmio,dwDataOffset+dwDataBytes,SEEK_SET) = -1 then
                 goto ERROR_CANNOT_WRITE;    { cannot seek, probably }

              { force the rif chunk to rewrite }
              ckRiff.cksize := 0;
              ckRiff.dwFlags:= ckRiff.dwFlags or MMIO_DIRTY;
           end;

           { Ascend the output file out of the 'data' chunk - this will }
           { cause the chunk size of the 'data' chunk to be written.    }
           if mmioAscend(hmmio, @ckDATA, 0) <> 0 then
              goto ERROR_CANNOT_WRITE;    { cannot write file, probably }

           { Now create the fact chunk, not required for PCM but nice to have. }
           ckDATA.ckid   := mmioFOURCC('f', 'a', 'c', 't');
           ckDATA.cksize := 0;
           if mmioCreateChunk(hmmio, @ckDATA, 0) <> 0 then
              goto ERROR_CANNOT_WRITE;

           { If it didn't fail, write the fact chunk out }
           if mmioWrite(hmmio, @dwDataSamples, sizeOf(Longint)) <> sizeOf(Longint) then
              goto ERROR_CANNOT_WRITE;

           { Now ascend out of the fact chunk... }
           if mmioAscend(hmmio, @ckDATA, 0) <> 0 then
              goto ERROR_CANNOT_WRITE;

           { now write out possibly editted chunks... }
           if RiffWriteDISP(hmmio, lpDisp) <> 0 then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -