Read info from MP3 file

Posted on 2000-04-23
Last Modified: 2008-06-23
Hi from Barcelona, Spain!

As "Music" section is still under study by EE responsibles, as VB is the language in which I'm developing my program, I've decided this is the correct place to put this question.

The matter is: is there any simple way to read the song time of playing from a MP3 file? Simple means open the file, perhaps look for a given tag ID, read it and it's done. I pray for not having to use C; anyway, VB can open and read from files, too.

If C programming is needed, I would use from VB via a DLL call. I have a freeware 32 bit C compiler, and I think it's not difficult to create a DLL. After, using my VB manual, I can implement the call (I suppose, as I never have done so). The problem then would be the code itself, as I'm a completely newbie to C.

By now my main problem is I don't know if there is any tag or stamp in the file structure to store the playing time, or if WinAmp makes a calculation from several parameters.

I wouldn't want urls as answers, because I've already visited some of them (, etc) and I haven't found nothing; furthermore, all is C-related. The only way to accept an url as answer is to find there the solution to my question (or nearly), not MP3 technical (very technical) stuff.
Question by:BETTY
  • 3
  • 2
  • 2
  • +4

Expert Comment

ID: 2741431

you should try

This site contains descriptions of all possible file formats including MP3 - I downloaded information about it a while ago.

LVL 14

Expert Comment

ID: 2741631
An MP3 audio file is separated in smaller parts called frames. Each frame is independent. It has its own header and audio informations. There is no file header. Therefore, you can cut any part of a MP3 file and play it correctly.

The BitRate for each frame can be found in the Frame Header. The Frame Header is 4 bytes long and is located at the beginning of each frame. The Data inside of it is BIT aligned, not byte aligned, as such the 4 bytes represent 32 bits of information. Low Order bits 12-15 of the Frame header, specify the BitRate Code, that then can be looked up in a table, to ascertain what the BitRate value is. Generally speaking, most MP3s are homogenous, which means that if you get the BitRate for the first Frame Header, then the BitRate will be the same for the rest of them. In this case, you can then use the following formula to derive a very close approximation of song length in seconds:

LengthInSeconds = (8 * fileSize) / (Bitrate * 1000)

Keep in mind there are Variable BitRate MP3s out there. In those cases, to get a playing time, you have to calculate it frame by frame. (If you notice the slight delay in loading MP3s with Winamp, this is because it is preprocessing the file to calculate play time).

The MP3 Frame Header, contains 13 Bitcoded fields. As they are all tabular in nature and EE comment entry does not support this (posting tables is a mess), I suggest you go to the Web and obtain a properly formatted Frame Header layout. Here is a good link to get you started:

Although it is written in C++, the CMP3INFO class offered there is chock full of information. Additionally, you will find other hyperlinks to peruse on this subject.

LVL 28

Expert Comment

ID: 2741831
Calculates the duration in seconds of a .mp3 file. Also displays the associated layer, bitrate, sample rate of the file

This code shows you how to read the ID3-Tag from MP3-Files


Accepted Solution

sharmon earned 100 total points
ID: 2742600
Here is a link to a class file I wrote that will do pretty much anything to want such as...

MPEG Tag Viewer/Edit and MPEG File Info class module. Allows TAG viewing editing, and returns info on the MPEG file itself like Copyrighted, Seconds, Bytes, Mpeg Version, Layer Version, KBits, Hz, Mode, Private, CRCs, Original, Emphasis, and Channels. I know there is alot of code for editing a TAG but I wanted something that would allow for editing the TAG and viewing the info on the file. BTW: I included a short example program on how to use the class module for anyone who doesn't know about class modules.

Expert Comment

ID: 2746279
Hi Betty,
Im working on similar lines and i have developed a VB (BAS) module that will open up the mp3 file and tell you the exact playback length!
Yes, you're quite right VB can handle opening and reading the mp3 tag all by itself without VC having to cut in!
I'll email it to you.
All the best!


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

ID: 2748357
Rheingold: When I put this question I already had visited the site, and I found code in C++ following some links from there. Thanks.

wsh2: If mp3 files were "uniform" in bitrate, your formula would be genial: simple and fast. Unfortunately, as you say, some (or not so some) files are not bitrate-regular. And I'm so newbie in C++ I would have to spend (not waste if I learn something) lots of time navigating the code. Thanks for the link.

AzraSound and sharmon: I'm going to check your links, and to evaluate which one is better. Specially it's perfect to have a code directly from his author, as if a doubt appears, I expect to ask to perfect person. I'll tell you which one I choose and why.

headrush22m: I'm going to check your link too. But although it's fantastic to get the code directly in my e-mail, think people sometimes research the PAQ for an info through the title, and they will not be very happy if they spend their points in (correctly) answers that are not present. If you put an answer, think in it: if it's not suitable to put it here (length problems), you sould try to give an alternate solution to those who "pay" points after me for the info.

Expert Comment

ID: 2749305
A snippet...

' These may not all be used.. I've just cut it from a program and all they really do is store it for global access.
Public HeaderData As String * 4
Public Artist As String, Song As String, Album As String, Notes As String, Year As String
Public Version As Single, Layer As Byte, Bitrate As Integer, SampleRate As Long, FrameLength As Integer, Stereo As Byte
Public Matrix, StereoMode

' Reads various MP3 details from the first packet...
Public Sub ReadHeader(Filename As String)
  Dim Byte1 As Byte, Byte2 As Byte, Byte3 As Byte, Byte4 As Byte, BitRateArray, SampleRateArray
  Dim hFrameSync As Integer, hVersion As Byte, hLayer As Byte, hProtect As Byte, hBitRate As Byte, hSampleRate As Byte
  Dim hPadding As Byte, hPrivate As Byte, hChannel As Byte, hModeExt As Byte, hCopyright As Byte, hOriginal As Byte, hEmphasis As Byte
  Open Filename For Binary Access Read As #3
  Get #3, , HeaderData
  Close #3
  Byte1 = Asc(Mid$(HeaderData, 1, 1))
  Byte2 = Asc(Mid$(HeaderData, 2, 1))
  Byte3 = Asc(Mid$(HeaderData, 3, 1))
  Byte4 = Asc(Mid$(HeaderData, 4, 1))
  hFrameSync = Byte1 * &H8 + (Byte2 And &HE0) / &H20
  hVersion = (Byte2 And &H18) / &H8     ' 0=v2.5, 2=v2, 3=v1
  Version = 4 - hVersion
  If hVersion = 0 Then Version = 2.5
  hLayer = (Byte2 And &H6) / &H2        ' 1=l3, 2=l2, 3=l1
  Layer = 4 - hLayer
  hProtect = Byte2 And &H1              ' 0=CRC, 1=No
  hBitRate = (Byte3 And &HF0) / &H10    ' ---
  Select Case Int(Version) * 10 + Layer
    Case 11
      BitRateArray = Array(0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 999)
    Case 12
      BitRateArray = Array(0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 999)
    Case 13
      BitRateArray = Array(0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 999)
    Case 21
      BitRateArray = Array(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 999)
    Case 22, 23
      BitRateArray = Array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 999)
  End Select
  Bitrate = BitRateArray(hBitRate)
  hSampleRate = (Byte3 And &HC) / &H4   ' ---
  Select Case Version
    Case 1
      SampleRateArray = Array(44100, 48000, 32000)
    Case 2
      SampleRateArray = Array(22050, 24000, 16000)
    Case 2.5
      SampleRateArray = Array(11025, 12000, 8000)
  End Select
  SampleRate = SampleRateArray(hSampleRate)
  hPadding = (Byte3 And &H2) / &H2      ' 0=No, 1=Yes
  hPrivate = Byte3 And &H1              ' ???
  hChannel = (Byte4 And &HC0) / &H40    ' 0=Stereo, 1=JSt, 2=Dual, 3=Mono
  Stereo = hChannel
  hModeExt = (Byte4 And &H30) / &H10    ' (JSt only) ---
  hCopyright = (Byte4 And &H8) / &H8    ' 0=No, 1=Yes
  hOriginal = (Byte4 And &H4) / &H4     ' 0=Copy, 1=Original
  hEmphasis = Byte4 And &H3             ' 0=None, 1=50/15ms, 3=CCIT J.17
  If Layer = 1 Then FrameLength = Fix((12000 * Bitrate / SampleRate + hPadding) * 4) Else FrameLength = Fix(144000 * Bitrate / SampleRate + hPadding)
End Sub

' Inits a couple of arrays
Public Sub InitMP3s()
  Matrix = Array("Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip -Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&b", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro -Techno", "Ambient", "Trip -Hop", "Vocal", "Jazz Funk", "Fusion", "Trance", "Classical", _
    "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno -Industrial", "Electronic", "Pop -Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", _
    "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo -Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", _
    "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capela", "Euro-House", "Dance Hall")
  StereoMode = Array("Stereo", "Joint Stereo", "Dual Channel", "Mono")
End Sub

Author Comment

ID: 2752320
headrush22m: Your site only leads to your e-mail, so I'm not capable to check anything. This is the cause for me to reject your answer. Anyway, I'm among people here in EE that think no one would have to answer anymore, as the new layout in EE allows to accept a comment as answer. This is due to the fact that some experts don't check locked questions, and this leads to a loss of range of answers.

Note: yor SoundGarden software layout looks great!

Expert Comment

ID: 2774596
Thanks Betty! yeah i agree with you on the EE front!

Author Comment

ID: 2783744
Cloud 1: This code is similar to the others, perhaps a little more easy as it does not involve lots of Kb or classes. Thanks.

And the winner is... sharmon!!!! Yes, thus AzraSound's ones are near, I think yours is the most complete. Below are the changes needed to work under VB5, VB6 works as is in the link.


Delete the line:


Between BEGIN y END, in General:Declarations, it's not accepted:

  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject

In Function GenreText

Dim aGenre() As Variant
Dim aGenre

Expert Comment

ID: 2785297
Well thanks!  I wrote it a while back, while it's mostly complete, I haven't really looked through it in a while, I am sure there are things that need tidied up but I am glad you got it all working.  Overall it's pretty complete and does most everything.  Now you got me wanting to go back and work on it more:)  Take care, thanks.

Shannon Harmon

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

Title # Comments Views Activity
Pull multiple cvs files into one access table 28 64
vba find the last empty column 10 88
DIR issue 7 51
Cannot enter table caption text in Word protected document 6 111
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

910 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

16 Experts available now in Live!

Get 1:1 Help Now