Solved

Get MP3 File Info

Posted on 1998-12-09
8
346 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Error E2158 compiling with Delphi XE10 Seattle 2 126
tidtcpserver connection lost handle 2 110
Need Help Delphi 2010 CheckBox1 Stored value in memo 13 76
Base1 Encode/Decode 3 86
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

749 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