Solved

Read info from MP3 file

Posted on 2000-04-23
11
1,269 Views
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 (www.id3.org, 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.
0
Comment
Question by:BETTY
  • 3
  • 2
  • 2
  • +4
11 Comments
 
LVL 1

Expert Comment

by:Rheingold
ID: 2741431
Hi

you should try www.wotsit.org

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

Regards
0
 
LVL 14

Expert Comment

by:wsh2
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:

http://home.swipnet.se/grd/mp3info/

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.

0
 
LVL 28

Expert Comment

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

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=1&txtCodeId=4185



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

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=1&txtCodeId=6326
 


0
 
LVL 6

Accepted Solution

by:
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...

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=1&txtCodeId=4547

Descripton:
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.
0
 

Expert Comment

by:headrush22m
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!

-headrush
http://kashalkar.tripod.com


0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 1

Author Comment

by:BETTY
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.
0
 

Expert Comment

by:Cloud_1
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
0
 
LVL 1

Author Comment

by:BETTY
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!
0
 

Expert Comment

by:headrush22m
ID: 2774596
Thanks Betty! yeah i agree with you on the EE front!
0
 
LVL 1

Author Comment

by:BETTY
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.

prjID3Class.vbp:

Delete the line:
Retained=0

cIDV3.cls:

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

Change:
Dim aGenre() As Variant
with:
Dim aGenre
0
 
LVL 6

Expert Comment

by:sharmon
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
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

707 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