|
{*============================================================================== Copyright (C) 2002, All rights reserved, Com-N-Sense Ltd ================================================================================ File: WaveFileParser.pas Author: Liran Shahar, Com-N-Sense Ltd Updated: 24/03/2002 Purpose: Parsing wave file into chunks ================================================================================ 24/03/2002, Liran Shahar - Initial release. ==============================================================================*} unit WaveFileParser;
interface
uses Sysutils, Classes;
type TChunkType = array[1..4] of char;
PChunk = ^TChunk; TChunk = packed record cType: TChunkType; dwSize: cardinal; pData: pointer; end;
TcnsWaveFileParser = class(TPersistent) private FFilename: AnsiString; Chunks: TList; protected procedure SetFilename(AFilename: AnsiString); virtual; function GetChunksCount: integer; virtual; function GetChunk(Index: integer): PChunk; virtual; procedure ProcessFile; virtual; procedure ClearChunks; virtual; public constructor Create; virtual; destructor Destroy; override; function GetChunkByType(ChunkType: TChunkType): PChunk; virtual; property Filename: AnsiString read FFilename write SetFilename; property ChunksCount: integer read GetChunksCount; property Chunk[Index: integer]: PChunk read GetChunk; end;
implementation
const RIFF_SIGNATURE = 'RIFF'; WAVE_SIGNATURE = 'WAVE';
type TRIFFHeader = packed record cSignature: TChunkType; dwSize: cardinal; cType: TChunkType; end;
constructor TcnsWaveFileParser.Create; begin inherited Create; FFilename := ''; Chunks := TList.Create; end;
destructor TcnsWaveFileParser.Destroy; begin ClearChunks; inherited Destroy; end;
procedure TcnsWaveFileParser.SetFilename(AFilename: AnsiString); begin if FFilename <> AFilename then begin ClearChunks; FFilename := AFilename; ProcessFile; end; // if end;
function TcnsWaveFileParser.GetChunksCount: integer; begin Result := Chunks.Count; end;
function TcnsWaveFileParser.GetChunk(Index: integer): PChunk; begin Result := nil; if (Index > -1) and (Index < Chunks.Count) then Result := Chunks[Index]; end;
procedure TcnsWaveFileParser.ProcessFile; var WaveFile: TFileStream; Header: TRIFFHeader; Chunk: PChunk; begin try WaveFile := TFileStream.Create(FFilename, fmOpenRead + fmShareDenyWrite); WaveFile.Read(Header, sizeof(Header)); if (AnsiCompareText(Header.cSignature, RIFF_SIGNATURE) = 0) and (AnsiCompareText(Header.cType, WAVE_SIGNATURE) = 0) then begin while WaveFile.Position < WaveFile.Size do begin Chunk := AllocMem(sizeof(TChunk)); with Chunk^ do begin WaveFile.Read(cType, sizeof(cType)); WaveFile.Read(dwSize, sizeof(dwSize)); pData := AllocMem(dwSize); WaveFile.Read(pData^, dwSize); end; // with Chunks.Add(Chunk); end; // while end; // if finally FreeAndNil(WaveFile); end; end;
procedure TcnsWaveFileParser.ClearChunks; var Chunk: PChunk; begin while Chunks.Count > 0 do begin Chunk := Chunks[0]; Chunks.Delete(0); if assigned(Chunk^.pData) then FreeMem(Chunk^.pData); dispose(Chunk); end; // while end;
function TcnsWaveFileParser.GetChunkByType(ChunkType: TChunkType): PChunk; var iIndex: integer; begin Result := nil; iIndex := 0; while iIndex < Chunks.Count do if AnsiCompareText(PChunk(Chunks[iIndex])^.cType, ChunkType) = 0 then begin Result := Chunks[iIndex]; break; end else iIndex := iIndex + 1; end;
end.
|