Êàê îïðåäåëèòü ïðîäîëæèòåëüíîñòü â ñåêóíäàõ wav ôàéëà?

Previous  Top  Next

    
 

 

 

Code:

uses

MPlayer, MMsystem;

 

type

EMyMCIException = class(Exception);

TWavHeader = record

   Marker1: array[0..3] of Char;

   BytesFollowing: Longint;

   Marker2: array[0..3] of Char;

   Marker3: array[0..3] of Char;

   Fixed1: Longint;

   FormatTag: Word;

   Channels: Word;

   SampleRate: Longint;

   BytesPerSecond: Longint;

   BytesPerSample: Word;

   BitsPerSample: Word;

   Marker4: array[0..3] of Char;

   DataBytes: Longint;

end;

 

procedure TForm1.Button1Click(Sender: TObject);

var

Header: TWavHeader;

begin

with TFileStream.Create('C:\SomeFile.wav', fmOpenRead) do

   try

     ReadBuffer(Header, SizeOf(Header));

   finally

     Free;

   end;

ShowMessage(FloatToStr((Int64(1000) * header.DataBytes div header.BytesPerSecond) / 1000));

end

 

©Drkb::03600

Âçÿòî ñ ñàéòà http://www.swissdelphicenter.ch/en/tipsindex.php


Code:

function GetWaveLength(WaveFile: string): Double;

var

  groupID: array[0..3] of char;

  riffType: array[0..3] of char;

  BytesPerSec: Integer;

  Stream: TFileStream;

  dataSize: Integer;

// chunk seeking function,

// -1 means: chunk not found

 

function GotoChunk(ID: string): Integer;

var

     chunkID: array[0..3] of char;

     chunkSize: Integer;

begin

     Result := -1;

 

   with Stream do

       begin

            // index of first chunk

         Position := 12;

       repeat

            // read next chunk

         Read(chunkID, 4);

         Read(chunkSize, 4);

          if chunkID <> ID then

            // skip chunk

        Position := Position + chunkSize;

         until(chunkID = ID) or (Position >= Size);

         if chunkID = ID then

              // chunk found,

            // return chunk size

           Result := chunkSize;

       end;

end;

 

begin

  Result := -1;

  Stream := TFileStream.Create(WaveFile, fmOpenRead or fmShareDenyNone);

  with Stream do

       try

         Read(groupID, 4);

      Position := Position + 4; // skip four bytes (file size)

      Read(riffType, 4);

 

      if(groupID = 'RIFF') and (riffType = 'WAVE') then

          begin

             // search for format chunk

         if GotoChunk('fmt') <> -1 then

             begin

               // found it

            Position := Position + 8;

            Read(BytesPerSec, 4);

               //search for data chunk

              dataSize := GotoChunk('data');

 

              if dataSize <> -1 then

                    // found it

                Result := dataSize / BytesPerSec

               end

           end

       finally

         Free;

    end;

end;

 

 

 

This returns the number of seconds as a floating point number, which is not necessarily the most helpful format. Far better to return it as a string representing the time in hours, minutes and seconds. The following function achieves this based on the number of seconds as an integer:

Code:

function SecondsToTimeStr(RemainingSeconds: Integer): string;

var

  Hours, Minutes, Seconds: Integer;

  HourString, MinuteString, SecondString: string;

begin

   // Calculate Minutes

  Seconds := RemainingSeconds mod 60;

  Minutes := RemainingSeconds div 60;

  Hours := Minutes div 60;

  Minutes := Minutes - (Hours * 60);

 

  if Hours < 10 then

      HourString := '0' + IntToStr(Hours) + ':'

    else

      HourString := IntToStr(Hours) + ':';

 

  if Minutes < 10 then

       MinuteString := '0' + IntToStr(Minutes) + ':'

     else

       MinuteString := IntToStr(Minutes) + ':';

 

  if Seconds < 10 then

       SecondString := '0' + IntToStr(Seconds)

     else

       SecondString := IntToStr(Seconds);

  Result := HourString + MinuteString + SecondString;

end;

 

 

 

Having created these functions you can call them from any relevant event - for example a button click:

Code:

procedure TForm1.Button1Click(Sender: TObject);

var

 Seconds: Integer;

begin

  Seconds := Trunc(GetWaveLength(Edit1.Text));

   //gets only the Integer part of the length

  Label1.Caption := SecondsToTimeStr(Seconds);

end;

 

 

 

You can even reduce this to a single line of code if you prefer:

Code:

procedure TForm1.Button1Click(Sender: TObject);

begin

  Label1.Caption := SecondsToTimeStr(Trunc(GetWaveLength(Edit1.Text)));

end;

 

©Drkb::03601

Âçÿòî ñ Delphi Knowledge Base: http://www.baltsoft.com/