Avatar billede roth Nybegynder
29. april 2002 - 17:24 Der er 8 kommentarer og
1 løsning

find længde af wave-fil i sekunder

Jeg skal bruge en funktion der kan give mig længden af en wave-fil i antal sekunder. Har ledt og rodet får at finde det men ingen held.

50 points for en fungerende løsning.

/Roth
Avatar billede martinlind Nybegynder
29. april 2002 - 18:23 #1
Søg de rigtige steder og du skal finde *gg* :

unit WAVfile;

interface

uses
  Classes, SysUtils;

const
  { Used with ChannelModeID property }
  WAV_CM_MONO = 1;                                      { Index for mono mode }
  WAV_CM_STEREO = 2;                                  { Index for stereo mode }

  { Channel mode names }
  WAV_MODE: array [0..2] of string = ('Unknown', 'Mono', 'Stereo');

type
  { Class TWAVfile }
  TWAVfile = class(TObject)
    private
      { Private declarations }
      FValid: Boolean;
      FChannelModeID: Byte;
      FSampleRate: Word;
      FBitsPerSample: Byte;
      FFileSize: Cardinal;
      procedure FResetData;
      function FGetChannelMode: string;
      function FGetDuration: Double;
    public
      { Public declarations }
      constructor Create;                                    { Create object }
      function ReadFromFile(const FileName: string): Boolean;  { Load header }
      property Valid: Boolean read FValid;            { True if header valid }
      property ChannelModeID: Byte read FChannelModeID;  { Channel mode code }
      property ChannelMode: string read FGetChannelMode;  { Channel mode name }
      property SampleRate: Word read FSampleRate;          { Sample rate (hz) }
      property BitsPerSample: Byte read FBitsPerSample;    { Bits per sample }
      property FileSize: Cardinal read FFileSize;        { File size (bytes) }
      property Duration: Double read FGetDuration;      { Duration (seconds) }
  end;

implementation

type
  { Real structure of WAV file header }
  WAVRecord = record
    { RIFF file header }
    RIFFHeader: array [1..4] of Char;                        { Must be "RIFF" }
    FileSize: Integer;                          { Must be "RealFileSize - 8" }
    WAVEHeader: array [1..4] of Char;                        { Must be "WAVE" }
    { Format information }
    FormatHeader: array [1..4] of Char;                      { Must be "fmt " }
    FormatSize: Integer;                              { Must be 16 (decimal) }
    FormatCode: Word;                                            { Must be 1 }
    ChannelNumber: Word;                                { Number of channels }
    SampleRate: Integer;                                  { Sample rate (hz) }
    BytesPerSecond: Integer;                              { Bytes per second }
    BytesPerSample: Word;                                  { Bytes per sample }
    BitsPerSample: Word;                                    { Bits per sample }
    { Data area }
    DataHeader: array [1..4] of Char;                        { Must be "data" }
    DataSize: Integer;                                            { Data size }
  end;

{ ********************* Auxiliary functions & procedures ******************** }

function ReadWAV(const FileName: string; var WAVData: WAVRecord): Boolean;
var
  SourceFile: file;
  Transferred: Integer;
begin
  try
    Result := true;
    { Set read-access and open file }
    AssignFile(SourceFile, FileName);
    FileMode := 0;
    Reset(SourceFile, 1);
    { Read header }
    BlockRead(SourceFile, WAVData, 44, Transferred);
    CloseFile(SourceFile);
    { if transfer is not complete }
    if Transferred < 44 then Result := false;
  except
    { Error }
    Result := false;
  end;
end;

{ --------------------------------------------------------------------------- }

function HeaderIsValid(const WAVData: WAVRecord): Boolean;
begin
  Result := true;
  { Validation }
  if WAVData.RIFFHeader <> 'RIFF' then Result := false;
  if WAVData.WAVEHeader <> 'WAVE' then Result := false;
  if WAVData.FormatHeader <> 'fmt ' then Result := false;
  if (WAVData.ChannelNumber <> WAV_CM_MONO) and
    (WAVData.ChannelNumber <> WAV_CM_STEREO) then Result := false;
end;

{ ********************** Private functions & procedures ********************* }

procedure TWAVfile.FResetData;
begin
  FValid := false;
  FChannelModeID := 0;
  FSampleRate := 0;
  FBitsPerSample := 0;
  FFileSize := 0;
end;

{ --------------------------------------------------------------------------- }

function TWAVfile.FGetChannelMode: string;
begin
  Result := WAV_MODE[FChannelModeID];
end;

{ --------------------------------------------------------------------------- }

function TWAVfile.FGetDuration: Double;
begin
  if FValid then
    Result := (FFileSize - 44) * 8 /
      FSampleRate / FBitsPerSample / FChannelModeID
  else
    Result := 0;
end;

{ ********************** Public functions & procedures ********************** }

constructor TWAVfile.Create;
begin
  inherited;
  FResetData;
end;

{ --------------------------------------------------------------------------- }

function TWAVfile.ReadFromFile(const FileName: string): Boolean;
var
  WAVData: WAVRecord;
begin
  { Reset and load header data from file to variable }
  FResetData;
  Result := ReadWAV(FileName, WAVData);
  { Process data if loaded and header valid }
  if (Result) and (HeaderIsValid(WAVData)) then
  begin
    FValid := true;
    { Fill properties with header data }
    FChannelModeID := WAVData.ChannelNumber;
    FSampleRate := WAVData.SampleRate;
    FBitsPerSample := WAVData.BitsPerSample;
    FFileSize := WAVData.FileSize + 8;
  end;
end;

end.
Avatar billede roth Nybegynder
29. april 2002 - 20:44 #2
hmm, kan du også fortælle mig hvordan jeg skal bruge alt det der?

/Roth
Avatar billede martinlind Nybegynder
29. april 2002 - 20:50 #3
lave en fil hvor du indsætter min kode, lav en form der user den nye unit du har lavet ( med min kode ) lav en knap og skriv følgende kode :

VAR
  T : TWavFile;
begin
  T := TWavFile.Create;
  T.ReadFromFile('C:\Hest.WAV');
  ShowMessageFmt('%.0f',[T.Duration]);
  T.Free;
end;
Avatar billede roth Nybegynder
29. april 2002 - 21:46 #4
det er jo for cool det der :)

mange mange tak!!

/Roth
Avatar billede martinlind Nybegynder
29. april 2002 - 21:49 #5
Selv Tak :)
Avatar billede roth Nybegynder
29. april 2002 - 22:15 #6
ok det er helt klart for længe siden jeg sidst har leget med delphi .. håber du gider hjælpe mig en lille smule mere.
Jeg har aldrig set den der ShowMessageFmt før, og jeg kan ikke gennemskue hvad ('%.of',[T.Duration]) spytter ud. T.Duration laver en double og den kan jeg heller ikke addere til en integer.

Følgende linie regner intervallet ud for mig:
FormMain.Ttimer.Interval := 60000*(StrToInt(FormMain.Einterval.Text));

der skal længden af wave-filen lægges til så det bliver noget i stil med

FormMain.Ttimer.Interval := 60000*(StrToInt(FormMain.Einterval.Text))+1000*T.Duration;

Men det vil den naturligvis ikke pga type mismatch blabla (Cardinal and Extended siger delphi 6).

ellers en vældig smart unit du sendte, hvis jeg da så bare kunne fatte hehe

/Roth
Avatar billede martinlind Nybegynder
29. april 2002 - 22:19 #7
FormMain.Ttimer.Interval := Round(60000*(StrToInt(FormMain.Einterval.Text))+1000*T.Duration);
Avatar billede martinlind Nybegynder
29. april 2002 - 22:20 #8
kig i hjælpen på Format();
Avatar billede roth Nybegynder
29. april 2002 - 22:44 #9
og vupti så virker det, nu har jeg også kun været i gang siden middag hehe :)

endnu engang mange tak!

/Roth
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester