Solved

Get MP3 File Info

Posted on 1998-12-09
8
335 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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 …
Send secure, cloud-based, encrypted alerts and maintain HIPAA compliant messaging. Integrates priority & secure messaging into one application. Ensures IT, emergency respondents and healthcare professionals that their critical messages are never mis…

911 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now