Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to parse a wave file Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
28-Aug-03
Category
Multimedia
Language
Delphi 3.x
Views
123
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Liran Shahar

Access each chunk within a wave file is a tricky business but sometime you need to 
access the actual samples/data to get what you want...so how can that be done?

Answer:

A WAV file is binary file in the RIFF format, RIFF format enables the user to haev 
multiple information in the same file which can either be used or not. 

The information is stored in chunks, each chunk have its type (4 chars) and side 
(dword) so it can be skipped if you are not interested in the data or to be read 
from the file. 

You can download the demo software that shows wave file in a signal display graph 
with functions as: paning, zoom, multiple audio channels and more from 

http://www.com-n-sense.com/ftproot/SignalDisplay.zip 
http://www.com-n-sense.com/ftproot/SignalDisplay.zip

(the zip file contains the wavefileparser component and signaldisplay component). 

The following code parses WAV files into accessable chunks: 

1   {*=========================================================================
2   =====
3             Copyright (C) 2002, All rights reserved, Com-N-Sense Ltd
4   ================================================================================
5   File: WaveFileParser.pas
6   Author: Liran Shahar, Com-N-Sense Ltd
7   Updated: 24/03/2002
8   Purpose: Parsing wave file into chunks
9   ================================================================================
10    24/03/2002, Liran Shahar
11    - Initial release.
12  ==============================================================================*}
13  unit WaveFileParser;
14  
15  interface
16  
17  uses
18    Sysutils, Classes;
19  
20  type
21    TChunkType = array[1..4] of char;
22  
23    PChunk = ^TChunk;
24    TChunk = packed record
25      cType: TChunkType;
26      dwSize: cardinal;
27      pData: pointer;
28    end;
29  
30    TcnsWaveFileParser = class(TPersistent)
31    private
32      FFilename: AnsiString;
33      Chunks: TList;
34    protected
35      procedure SetFilename(AFilename: AnsiString); virtual;
36      function GetChunksCount: integer; virtual;
37      function GetChunk(Index: integer): PChunk; virtual;
38      procedure ProcessFile; virtual;
39      procedure ClearChunks; virtual;
40    public
41      constructor Create; virtual;
42      destructor Destroy; override;
43      function GetChunkByType(ChunkType: TChunkType): PChunk; virtual;
44      property Filename: AnsiString read FFilename write SetFilename;
45      property ChunksCount: integer read GetChunksCount;
46      property Chunk[Index: integer]: PChunk read GetChunk;
47    end;
48  
49  implementation
50  
51  const
52    RIFF_SIGNATURE = 'RIFF';
53    WAVE_SIGNATURE = 'WAVE';
54  
55  type
56    TRIFFHeader = packed record
57      cSignature: TChunkType;
58      dwSize: cardinal;
59      cType: TChunkType;
60    end;
61  
62  constructor TcnsWaveFileParser.Create;
63  begin
64    inherited Create;
65    FFilename := '';
66    Chunks := TList.Create;
67  end;
68  
69  destructor TcnsWaveFileParser.Destroy;
70  begin
71    ClearChunks;
72    inherited Destroy;
73  end;
74  
75  procedure TcnsWaveFileParser.SetFilename(AFilename: AnsiString);
76  begin
77    if FFilename <> AFilename then
78    begin
79      ClearChunks;
80      FFilename := AFilename;
81      ProcessFile;
82    end; // if
83  end;
84  
85  function TcnsWaveFileParser.GetChunksCount: integer;
86  begin
87    Result := Chunks.Count;
88  end;
89  
90  function TcnsWaveFileParser.GetChunk(Index: integer): PChunk;
91  begin
92    Result := nil;
93    if (Index > -1) and (Index < Chunks.Count) then
94      Result := Chunks[Index];
95  end;
96  
97  procedure TcnsWaveFileParser.ProcessFile;
98  var
99    WaveFile: TFileStream;
100   Header: TRIFFHeader;
101   Chunk: PChunk;
102 begin
103   try
104     WaveFile := TFileStream.Create(FFilename, fmOpenRead + fmShareDenyWrite);
105     WaveFile.read(Header, sizeof(Header));
106     if (AnsiCompareText(Header.cSignature, RIFF_SIGNATURE) = 0) and
107       (AnsiCompareText(Header.cType, WAVE_SIGNATURE) = 0) then
108     begin
109       while WaveFile.Position < WaveFile.Size do
110       begin
111         Chunk := AllocMem(sizeof(TChunk));
112         with Chunk^ do
113         begin
114           WaveFile.read(cType, sizeof(cType));
115           WaveFile.read(dwSize, sizeof(dwSize));
116           pData := AllocMem(dwSize);
117           WaveFile.read(pData^, dwSize);
118         end; // with
119         Chunks.Add(Chunk);
120       end; // while
121     end; // if
122   finally
123     FreeAndNil(WaveFile);
124   end;
125 end;
126 
127 procedure TcnsWaveFileParser.ClearChunks;
128 var
129   Chunk: PChunk;
130 begin
131   while Chunks.Count > 0 do
132   begin
133     Chunk := Chunks[0];
134     Chunks.Delete(0);
135     if assigned(Chunk^.pData) then
136       FreeMem(Chunk^.pData);
137     dispose(Chunk);
138   end; // while
139 end;
140 
141 function TcnsWaveFileParser.GetChunkByType(ChunkType: TChunkType): PChunk;
142 var
143   iIndex: integer;
144 begin
145   Result := nil;
146   iIndex := 0;
147   while iIndex < Chunks.Count do
148     if AnsiCompareText(PChunk(Chunks[iIndex])^.cType, ChunkType) = 0 then
149     begin
150       Result := Chunks[iIndex];
151       break;
152     end
153     else
154       iIndex := iIndex + 1;
155 end;
156 
157 end.



Component Download: http://www.com-n-sense.com/ftproot/SignalDisplay.ziphttp://www.com-n-sense.com/ftproot/SignalDisplay.zip

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC