Solved

Get MP3 File Info

Posted on 1998-12-09
8
343 Views
Last Modified: 2010-04-04
How can I extract information about artist and recording quality (khz and bits) from an MP3 file?

Any help appreciated
Thanks in advance
0
Comment
Question by:friberg
  • 3
  • 3
  • 2
8 Comments
 
LVL 4

Expert Comment

by:jeurk
ID: 1350054
to get artist information you can look at the tag included in the mp3 file, don't know for the rest.
If you want I can retrieve you the link to a component that can read tag's found on torry's
I can remember it for the moment, but I can look at it if you want.
0
 

Author Comment

by:friberg
ID: 1350055
Yes, please give the link, that could be of some help.

Is anyone having a code example on the above?

0
 
LVL 4

Expert Comment

by:jeurk
ID: 1350056
here it is, source code included i think

http://www.torry.ru/vcl/mmedia/mp3tag.zip
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 3

Expert Comment

by:williams2
ID: 1350057
I have made a Header info function that is able to parse all necessary information from the 4 bytes header in the mp3 file. Is that what you need??

Regards,
Williams
0
 

Author Comment

by:friberg
ID: 1350058
Williams, yes I thinks that's exactly what I need. I don't know how the header info is stored, but I need to know about kbps, khz and mono/stereo on mp3 files. Could you please send me the function?
0
 
LVL 3

Accepted Solution

by:
williams2 earned 100 total points
ID: 1350059
If that is what you want, here is your answer:

This version of the MPx header extracter is not proffen to be sure to catch the header, as many headers might be hidden longer inside the file of the MP3. This will be corrected in a future release. There might be some not so pure coding in this, but my skills have been developed since last time I laid my hand on this, but it sure works :-)

Regards,
Williams

unit MPHeUnit;


  // This MPEG Layer 1-3 header extraction utility v1.0 has been developed by
  // Thomas Williams (c) 1997
  // The unit is freeware and can be used in any commercial way as I will be
  // creditet as the author of the functionality.

interface

Uses SysUtils;

Const
  BoolAnswer: Array[0..1] of String = ('No','Yes');
  Modes: Array[0..3] of String = ('Stereo','Joint Stereo','Dual Channel','Mono');
  Freqs: Array[0..6] of Integer =
  ( 44100, 48000, 32000, 22050, 24000, 16000 , 11025 );

  Tabs123: Array[0..(2*3*16-1)] of Integer = (
    0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0,
    0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,0,
    0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,0,
    0,32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256,0,
    0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0,
    0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0
  );

  Translations: Array[0..(2*3*16-1)] of Integer = (
    0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0,
    0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0,
    0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,
    0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0,
    0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0
  );

Type

  TMpeg3Head = class
  Private
    //                ver., layer, bitrate
    tabsel_123: Array[0..1, 0..2 , 0..15  ] of Integer;
    Translate:  Array[0..1, 0..2 , 0..15  ] of Integer;
    Stereo: Integer;
    jsbound: Integer;
//    single: Integer;
    II_sblimit: Integer;
    lsf: Integer;
    mpg25: Integer;
//    down_sample: Integer;
//    header_change: Integer;
//    block_size: Integer;
    lay: Integer;
    error_protection: Integer;
    bitrate_index: Integer;
    sampling_frequency: Integer;
    padding: Integer;
    extension: Integer;
    mode: Integer;
    mode_ext: Integer;
    copyright_: Integer;
    original_: Integer;
    emphasis_: Integer;
    Privat_: Integer;
    Size_: Integer;
    MSB,LSB: Word;
    Bit: Array[0..31] of 0..1;
    Procedure SetBits;
    Procedure Get_II_stuff;
  Public
    Error: String;
    Version: String;
    Frames: String;
    Length: String;
    Frequency: String;
    Layer: String;
    BitRate, BitRateExt: String;
    OutputMode, OutputModeExt: String;
    Privat: String;
    CRC: String;
    Copyright: String;
    Original: String;
    Emphasis: String;
    Header: String;
    Size: String;
    Constructor Create;
    Function GetHeader(FilePath, FileName: String): Boolean;
  End;

implementation

  Function getLength(var S: String): Integer;
  Begin Result:= Length(S) End;

  Constructor TMpeg3Head.Create;
  var  //
    x,y,z,i: Integer;
  Begin
    i:= 0;
    For z:= 0 to 1 do
      For y:= 0 to 2 do
        For x:= 0 to 15 do
        begin
          Tabsel_123[z,y,x]:= Tabs123[i];
          Translate[z,y,x]:= Translations[i];
          inc(i);
        End;
    Error:= '';
  End;

  Procedure TMpeg3Head.SetBits;
  var
    i: Integer;
  Begin
    For i:= 0 to 15 do
      Bit[i]:= (LSB Shr i) AND $1;
    For i:= 0 to 15 do
      Bit[i+16]:= (MSB Shr i) AND $1;
  End;

  Procedure TMpeg3Head.Get_II_stuff;
  Const
    sblims: Array[0..4] of Integer = ( 27 , 30 , 8, 12 , 30 );
  var
    table: Integer;
  Begin
    if lsf<>0 then
      table := 4
    else
      table := translate[sampling_frequency,2 - stereo,bitrate_index];
    II_sblimit := sblims[table];;
//    static struct al_table *tables[5] =
//         { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
//    fr->alloc = tables[table];
  End;

  Function TMpeg3Head.GetHeader(FilePath, FileName: String): Boolean;
  Const
    RIFF_SKIP = $46;
  var
    FrameSize,Frames_,Secs: Integer;
    Bytes: Array[1..4] of Byte;
    F: File of Byte;
  Begin
    Try
      AssignFile(F,FilePath+FileName);
      FileMode := 0; // Read Only
      Reset(F);
      Size_:= FileSize(F);
      If Size_<4 then Error:='Invalid MPEG file' else
      Begin
        Read(F,Bytes[1],Bytes[2],Bytes[3],Bytes[4]);
        If   (Bytes[1]=Ord('R')) AND (Bytes[2]=Ord('I'))
         AND (Bytes[3]=Ord('F')) AND (Bytes[4]=Ord('F')) then
        If Size_<=(RIFF_SKIP +4) then Error:='Invalid MPEG file' else
        Begin
          Seek(F,RIFF_SKIP);
          Read(F,Bytes[1],Bytes[2],Bytes[3],Bytes[4]);
          Dec(Size_,RIFF_SKIP);
        End;
        MSB:= Bytes[1]*256+Bytes[2];
        LSB:= Bytes[3]*256+Bytes[4];
        SetBits;
        If (MSB And $ffe0) <> $ffe0 then Error:= 'Invalid Header' else
        Begin
          Error:= '';
          if Bit[20]=1 then
          Begin
            lsf:= 1-Bit[19];
            mpg25:= 0;
          End else
          Begin
            lsf:= 1;
            mpg25:= 1;
          End;
          lay := 4 - (Bit[18]*2+Bit[17]);//((MSB shr 1) AND 3);
          BitRate_index := ((LSB shr 12) AND $F);
          If Bit[11]*2+Bit[10]=3 then Error:= 'Stream Error!';
          if mpg25=1 then
            sampling_frequency := 6
          else
            sampling_frequency := (Bit[11]*2+Bit[10]) + lsf * 3;
          error_protection := Bit[16] XOR 1;
          Padding:=    Bit[9];
          Extension:=  Bit[8];
          Mode:=       Bit[7]*2+Bit[6];
          Mode_Ext:=   Bit[5]*2+Bit[4];
          Copyright_:= Bit[3];
          Original_:=  Bit[2];
          Privat_:=    Bit[1];
          Emphasis_:=  Bit[0];
          If mode = 3 then // MD_MONO
            Stereo:= 1 else Stereo:= 2;
          If BitRate_Index=0 then Error:= 'Free format not Supported';
          Case lay Of
            1 : Begin
                  if mode=1 then
                    jsbound:= mode_ext*4+4
                  else
                    jsbound:= 32;
                  FrameSize:=  Tabsel_123[lsf,0,BitRate_index]*12000;
                  FrameSize:=  FrameSize div Freqs[sampling_frequency];
                  FrameSize:= (FrameSize + Padding) * 4 - 4;
                End;
            2 : Begin
                  Get_II_stuff;
                  if mode=1 then
                    jsbound:= mode_ext*4+4
                  else
                    jsbound:= II_Sblimit;
                  FrameSize:=  Tabsel_123[lsf,1,BitRate_index]*144000;
                  FrameSize:=  FrameSize div Freqs[sampling_frequency];
                  FrameSize:=  FrameSize + Padding - 4;
                End;
            3 : Begin
                  FrameSize:=  Tabsel_123[lsf,2,BitRate_index]*144000;
                  FrameSize:=  FrameSize div Freqs[sampling_frequency];
                  FrameSize:=  FrameSize + Padding - 4;
                End;
           Else Begin
                  Error:= 'Layer not supported!';
                  Result:= False;
                  Exit
                End;
          End;
          Inc(FrameSize,3); // Skip Header Info
          If mpg25=1 then Version:='MPEG 2.5' else
            If lsf=0 then Version:= 'MPEG 1.0' else Version:= 'MPEG 2.0';
          Frames_ := size_ div FrameSize;
          Frames := IntToStr(Frames_ * 2);
          Secs := (Frames_*2) div 77;
          Length:= IntToStr(Secs mod 60);
          If getLength(Length)=1 then Length:= '0'+Length;

          Length := IntToStr(Secs Div 60)+':'+Length;
          Layer := 'Layer '+IntToStr(Lay);
          Frequency := IntToStr(freqs[sampling_frequency])+'Hz';
          BitRate := IntToStr(tabsel_123[lsf,lay-1,bitrate_index])+' Kbits/s';
          BitRateExt := IntToStr(Extension);
          OutputMode := Modes[Mode];
          OutputModeExt := IntToStr(Mode_Ext);
          CRC := BoolAnswer[error_protection];
          Copyright := BoolAnswer[Copyright_];
          Original := BoolAnswer[Original_];
          Privat:= BoolAnswer[Privat_];
          Emphasis := BoolAnswer[Emphasis_];
          Header:= IntToHex(MSB,4)+IntToHex(LSB,4);
          Size:= IntToStr(Size_);
        End;
      End;
    finally
      CloseFile(F);
    End;
    Result:= Error='';
  End;

end.

0
 

Author Comment

by:friberg
ID: 1350060
Thanks again, just what I needed.
0
 
LVL 3

Expert Comment

by:williams2
ID: 1350061
That's allright my friend! Should it be another time?

Cheers,
Williams
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question