📄 mmwaveio.pas
字号:
wio.dwDataSamples := $FFFFFFFF;
TempRes := RiffInitINFO(wio.lpInfo);
if TempRes <> 0 then
begin
Result := TempRes;
goto ERROR_READING_WAVE;
end;
TempRes := RiffInitDISP(wio.lpDisp);
if TempRes <> 0 then
begin
Result := TempRes;
goto ERROR_READING_WAVE;
end;
CheckDataSize := False;
NextOffset := wio.dwFileSize;
hasFormat := False;
hasData := False;
while mmioDescend(hmmio, @ck, @ckRIFF, 0) = 0 do
begin
{ quickly check for corrupt RIFF file--don't ascend past end! }
if (ck.dwDataOffset + ck.cksize > ckRIFF.dwDataOffset + ckRIFF.ckSize) then
begin
if hasFormat and hasData then
break
else if (ck.dwDataOffset + ck.cksize > wio.dwFileSize) then
begin
ck.ckSize := wio.dwFileSize-ck.dwDataOffset;
{goto ERROR_READING_WAVE;}
end;
end;
if CheckDataSize then
begin
NextOffset := ck.dwDataOffset-8;
CheckDataSize := False;
end;
if ck.ckid = mmioFOURCC('L', 'I', 'S', 'T') then
begin
if (ck.fccType = mmioFOURCC('I', 'N', 'F', 'O')) then
begin
TempRes := RiffReadINFO(hmmio, @ck, wio.lpInfo);
if TempRes <> 0 then
begin
Result := TempRes;
goto ERROR_READING_WAVE;
end;
end;
end
else if ck.ckid = mmioFOURCC('D', 'I', 'S', 'P') then
begin
TempRes := RiffReadDISP(hmmio, @ck, wio.lpDisp);
if TempRes <> 0 then
begin
Result := TempRes;
goto ERROR_READING_WAVE;
end;
end
else if ck.ckid = mmioFOURCC('f', 'm', 't', ' ') then
begin
{ !?! another format chunk !?! }
if (lpwio <> Nil) then break;
{ get size of the format chunk, allocate and lock memory }
{ for it. we always alloc a complete extended format header }
{ (even for PCM headers that do not have the cbSize field }
{ defined--we just set it to zero). }
dw := ck.cksize;
if (dw < sizeof(TWAVEFORMATEX)) then
dw := sizeof(TWAVEFORMATEX);
inc(dw, sizeof(TWAVEIOCB) - sizeof(TWAVEFORMATEX));
lpwio := GlobalAllocMem(dw);
if (lpwio = Nil) then
begin
Result := WIOERR_NOMEM;
goto ERROR_READING_WAVE;
end;
lpwio^.dwSize := dw;
{ read the format chunk }
Result := WIOERR_FILEERROR;
dw := ck.cksize;
if mmioRead(hmmio, PChar(@lpwio^.wfx), dw) <> dw then
goto ERROR_READING_WAVE;
hasFormat := True;
end
else if ck.ckid = mmioFOURCC('d', 'a', 't', 'a') then
begin
{ !?! multiple data chunks !?! }
if (wio.dwDataBytes <> 0) then break;
{ just hang on to the total length in bytes of this data }
{ chunk.. }
wio.dwDataBytes := ck.cksize;
{ offset of data portion of data chunk }
wio.dwDataOffset:= ck.dwDataOffset;
CheckDataSize := True;
hasData := True;
end
else if ck.ckid = mmioFOURCC('f', 'a', 'c', 't') then
begin
{ !?! multiple fact chunks !?! }
if (wio.dwDataSamples <> $FFFFFFFF) then break;
{ read the first dword in the fact chunk--it's the only }
{ info we need (and is currently the only info defined for }
{ the fact chunk...) }
{ if this fails, dwDataSamples will remain -1 so we will }
{ deal with it later... }
mmioRead(hmmio, PChar(@wio.dwDataSamples), sizeof(Longint));
end;
{ step up to prepare for next chunk.. }
if mmioAscend(hmmio, @ck, 0) <> 0 then
{ bug fix for files with not 4 byte aligned chunks }
if (wio.dwDataBytes <> 0) then break
else goto ERROR_READING_WAVE;
end;
if (dwFlags and RIFF_INFO_ONLY = 0) then
begin
{ if no fmt chunk was found, then die! }
if (lpwio = Nil) then
begin
Result := WIOERR_ERROR;
goto ERROR_READING_WAVE;
end;
wio.dwDataBytes := ((NextOffset-wio.dwDataOffset) div lpwio^.wfx.nBlockAlign)*lpwio^.wfx.nBlockAlign;
{ some wave files have wrong entrys for AvgBytesPerSecond and }
{ BlockAlign so we calculate them ourself }
if (lpwio^.wfx.wFormatTag = WAVE_FORMAT_PCM) then
with lpwio^.wfx do
begin
nBlockAlign := (wBitsPerSample * nChannels) div 8;
nAvgBytesPerSec:= nBlockAlign * nSamplesPerSec;
end;
{ all wave files other than PCM are _REQUIRED_ to have a fact chunk }
{ telling the number of samples that are contained in the file. it }
{ is optional for PCM (and if not present, we compute it here). }
{ check for corrupt fact chunk and repair }
if (wio.dwDataSamples <> wioBytesToSamplesEx(lpwio,wio.dwDataBytes)) then
wio.dwDataSamples := wioBytesToSamplesEX(lpwio,wio.dwDataBytes);
{ cool! no problems... }
lpwio^.hmmio := 0;
lpwio^.dwFlags := dwFlags;
lpwio^.dwFileSize := wio.dwFileSize;
lpwio^.dwDataBytes := wio.dwDataBytes;
lpwio^.dwDataSamples := wio.dwDataSamples;
lpwio^.dwDataOffset := wio.dwDataOffset;
lpwio^.dwFirstSample := 0;
lpwio^.dwLastSample := wio.dwDataSamples;
lpwio^.dwBytesLeft := 0;
lpwio^.dwPosition := 0;
lpwio^.lpFilePath := wio.lpFilePath;
lpwio^.lpDisp := wio.lpDisp;
lpwio^.lpInfo := wio.lpInfo;
end
else
begin
dw := sizeof(TWAVEFORMATEX) + sizeof(TWAVEIOCB);
lpwio := GlobalAllocMem(dw);
if (lpwio = Nil) then
begin
Result := WIOERR_NOMEM;
goto ERROR_READING_WAVE;
end;
FillChar(lpwio^,dw,0);
lpwio^.dwSize := dw;
lpwio^.dwFlags := dwFlags;
lpwio^.lpFilePath := wio.lpFilePath;
lpwio^.lpDisp := wio.lpDisp;
lpwio^.lpInfo := wio.lpInfo;
end;
wioFileClose(hmmio, hMem);
Result := WIOERR_NOERROR;
exit;
{ return error (after minor cleanup) }
ERROR_READING_WAVE:
wioFileClose(hmmio, hMem);
wioFreeFileInfo(lpwio);
if (lpwio <> Nil) then GlobalFreeMem(Pointer(lpwio));
lpwio := Nil;
end;
{**************************************************************************}
function wioCreateFileInfo(Var lpwio: PWAVEIOCB; pwfx: PWaveFormatEx): integer;
Label ERROR_CREATE_INFO;
Var
dwSize: Longint;
TempRes: integer;
ExtraAlloc: Longint;
begin
{ default our error return (assume the worst) }
Result := WIOERR_BADPARAM;
lpwio := Nil;
if (pwfx = Nil) then
goto ERROR_CREATE_INFO;
{ allocate and lock memory for lpwio. we always alloc a complete }
{ extended format header (even for PCM headers that do not have }
{ the cbSize field defined--we just set it to zero). }
if (pwfx^.wFormatTag = WAVE_FORMAT_PCM) then
ExtraAlloc := 0
else
ExtraAlloc := pwfx^.cbSize;
dwSize := sizeOf(TWAVEIOCB) + ExtraAlloc;
lpwio := GlobalAllocMem(dwSize);
if (lpwio = Nil) then
begin
Result := WIOERR_NOMEM;
goto ERROR_CREATE_INFO;
end;
{ set the wio struc size }
lpwio^.dwSize := dwSize;
{ copy the WaveFormatEx struc to lpwio's }
Move(pwfx^, lpwio^.wfx, sizeOf(TWAVEFORMATEX) + ExtraAlloc);
{ create a new INFO struc }
TempRes := RiffInitINFO(lpwio^.lpInfo);
if (TempRes <> 0) then
begin
Result := TempRes;
goto ERROR_CREATE_INFO;
end;
{ create a new DISP list }
TempRes := RiffInitDISP(lpwio^.lpDisp);
if (TempRes <> 0) then
begin
Result := TempRes;
goto ERROR_CREATE_INFO;
end;
Result := WIOERR_NOERROR;
exit;
{ return error (after minor cleanup) }
ERROR_CREATE_INFO:
wioFreeFileInfo(lpwio);
end;
{**************************************************************************}
function wioCopyFileInfo(lpwioDst, lpwioSrc: PWAVEIOCB): integer;
begin
{ default our error return (assume the worst) }
Result := WIOERR_BADPARAM;
if (lpwioSrc = Nil) or (lpwioDst = nil) then
exit;
Result := WIOERR_ERROR;
{ copy the INFO chunk to the destination }
if RiffCopyInfo(lpwioDst^.lpInfo, lpwioSrc^.lpInfo) <> 0 then
exit;
{ copy the DISP chunk to the destination }
if RiffCopyDISP(lpwioDst^.lpDisp, lpwioSrc^.lpDisp) <> 0 then
exit;
Result := WIOERR_NOERROR;
end;
{**************************************************************************}
function wioBuildFileInfoFromMem(Var lpwio: PWaveIOCB; Memory: Pointer; MemSize: DWORD): Word;
Var
mmioInfo: TMMIOINFO;
begin
Result := WIOERR_FILEERROR;
lpwio := nil;
if (Memory <> nil) and (MemSize > 0) then
begin
FillChar(mmioInfo, sizeOf(TMMIOINFO),0);
mmioInfo.pchBuffer := Memory;
mmioInfo.cchBuffer := MemSize;
Result := wioReadFileInfo(lpwio, PChar(@mmioInfo),
mmioFOURCC('W', 'A', 'V', 'E'), RIFF_MEMORY);
end;
end;
{**************************************************************************}
function wioBuildFileInfoFromResource(Var lpwio: PWaveIOCB; ResourceName: PChar): Word;
begin
lpwio := nil;
Result := wioReadFileInfo(lpwio, ResourceName,
mmioFOURCC('W', 'A', 'V', 'E'), RIFF_RESOURCE);
end;
{**************************************************************************}
function wioBuildFileInfoFromRAWEx(Var lpwio: PWaveIOCB; lpFileName: PChar; DataOffset: DWORD;
pwfx: PWaveFormatEx): integer;
var
h: THandle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -