| 
			Author: Lou Adler
How do I get the length of a Wav file without using a TMediaPlayer to open the file?
Answer:
Getting the length is possible using the MCI_SENDSTRING API call, but that does get 
involved. However, a better method has been suggested that accesses the file 
directly and interprets its own internal data to obtain the information.
Here is the function:
1   function GetWaveLength(WaveFile: string): Double;
2   var
3       groupID: array[0..3] of char;
4       riffType: array[0..3] of char;
5       BytesPerSec: Integer;
6       Stream: TFileStream;
7       dataSize: Integer;
8     // chunk seeking function,
9     // -1 means: chunk not found
10  
11    function GotoChunk(ID: string): Integer;
12    var
13        chunkID: array[0..3] of char;
14        chunkSize: Integer;
15    begin
16        Result := -1;
17  
18      with Stream do
19          begin
20               // index of first chunk
21            Position := 12;
22          repeat
23               // read next chunk
24            read(chunkID, 4);
25            read(chunkSize, 4);
26             if chunkID <> ID then
27               // skip chunk
28           Position := Position + chunkSize;
29            until(chunkID = ID) or (Position >= Size);
30            if chunkID = ID then
31                 // chunk found,
32               // return chunk size
33              Result := chunkSize;
34          end;
35    end;
36  
37  begin
38      Result := -1;
39      Stream := TFileStream.Create(WaveFile, fmOpenRead or fmShareDenyNone);
40      with Stream do
41          try
42            read(groupID, 4);
43          Position := Position + 4; // skip four bytes (file size)
44          read(riffType, 4);
45  
46          if(groupID = 'RIFF') and (riffType = 'WAVE') then
47             begin
48                // search for format chunk
49             if GotoChunk('fmt') <> -1 then
50                begin
51                  // found it
52                Position := Position + 8;
53                read(BytesPerSec, 4);
54                   //search for data chunk
55                  dataSize := GotoChunk('data');
56  
57                  if dataSize <> -1 then
58                       // found it
59                    Result := dataSize / BytesPerSec
60                  end
61              end
62          finally
63            Free;
64        end;
65  end;
66  
67  //This returns the number of seconds as a floating point number, which is not 
68  necessarily the most helpful format. Far better to return it as a string 
69  representing the time in hours, minutes and seconds. The following function 
70  achieves this based on the number of seconds as an integer:
71  
72  function SecondsToTimeStr(RemainingSeconds: Integer): string;
73  var
74      Hours, Minutes, Seconds: Integer;
75      HourString, MinuteString, SecondString: string;
76  begin
77       // Calculate Minutes
78      Seconds := RemainingSeconds mod 60;
79      Minutes := RemainingSeconds div 60;
80      Hours := Minutes div 60;
81      Minutes := Minutes - (Hours * 60);
82  
83      if Hours < 10 then
84         HourString := '0' + IntToStr(Hours) + ':'
85       else
86         HourString := IntToStr(Hours) + ':';
87  
88      if Minutes < 10 then
89          MinuteString := '0' + IntToStr(Minutes) + ':'
90        else
91          MinuteString := IntToStr(Minutes) + ':';
92  
93      if Seconds < 10 then
94          SecondString := '0' + IntToStr(Seconds)
95        else
96          SecondString := IntToStr(Seconds);
97      Result := HourString + MinuteString + SecondString;
98  end;
99  
100 //Having created these functions you can call them from any relevant event - for 
101 example a button click:
102 
103 procedure TForm1.Button1Click(Sender: TObject);
104 var
105    Seconds: Integer;
106 begin
107     Seconds := Trunc(GetWaveLength(Edit1.Text));
108     //gets only the Integer part of the length
109     Label1.Caption := SecondsToTimeStr(Seconds);
110 end;
111 
112 You can even reduce this to a single line of code if you prefer:
113 
114 procedure TForm1.Button1Click(Sender: TObject);
115 begin
116     Label1.Caption := SecondsToTimeStr(Trunc(GetWaveLength(Edit1.Text)));
117 end;
			 |