Code archives/Audio/Length of mp3
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Okay, this has been a butt for anyone trying to devolp a media player that shows time. This works perfect on any mp3 file. Thanks to Floppy, and Bram32 on www.codersworkshop.com and the Mp3 tags archive here in the codearcs, this function is now a reality!!! | |||||
;def
Global looser
Dim mp3_bri$(16)
mp3_bri$(0) = "free"
mp3_bri$(1) = "32"
mp3_bri$(2) = "40"
mp3_bri$(3) = "48"
mp3_bri$(4) = "56"
mp3_bri$(5) = "64"
mp3_bri$(6) = "80"
mp3_bri$(7) = "96"
mp3_bri$(8) = "112"
mp3_bri$(9) = "128"
mp3_bri$(10) = "160"
mp3_bri$(11) = "192"
mp3_bri$(12) = "224"
mp3_bri$(13) = "256"
mp3_bri$(14) = "320"
mp3_bri$(15) = "bad"
Dim mp3_sri$(4)
mp3_sri(0) = "44100"
mp3_sri(1) = "48000"
mp3_sri(2) = "32000"
mp3_sri(3) = "reserved"
Dim mp3_chi$(4)
mp3_chi(0) = "Stereo"
mp3_chi(1) = "Joint Stereo"
mp3_chi(2) = "Dual"
mp3_chi(3) = "Mono"
Dim mp3_emi$(4)
mp3_emi(0) = "None"
mp3_emi(1) = "50/15"
mp3_emi(2) = "reserved"
mp3_emi(3) = "CCIT J.17"
Dim mp3_mvi$(4)
mp3_mvi$(0) = "MPEG Version 2.5 (not an official standard)"
mp3_mvi$(1) = "reserved"
mp3_mvi$(2) = "MPEG Version 2"
mp3_mvi$(3) = "MPEG Version 1"
Dim mp3_mli$(4)
mp3_mli$(0) = "reserved"
mp3_mli$(1) = "Layer III"
mp3_mli$(2) = "Layer II"
mp3_mli$(3) = "Layer I"
Dim mp3_genre$(128)
mp3_genre( 0)= "Blues"
mp3_genre( 1)= "Classic Rock"
mp3_genre( 2)= "Country"
mp3_genre( 3)= "Dance"
mp3_genre( 4)= "Disco"
mp3_genre( 5)= "Funk"
mp3_genre( 6)= "Grunge"
mp3_genre( 7)= "Hip-Hop"
mp3_genre( 8)= "Jazz"
mp3_genre( 9)= "Metal"
mp3_genre(10)= "New Age"
mp3_genre(11)= "Oldies"
mp3_genre(12)= "Other"
mp3_genre(13)= "Pop"
mp3_genre(14)= "R&B"
mp3_genre(15)= "Rap"
mp3_genre(16)= "Reggae"
mp3_genre(17)= "Rock"
mp3_genre(18)= "Techno"
mp3_genre(19)= "Industrial"
mp3_genre(20)= "Alternative"
mp3_genre(21)= "Ska"
mp3_genre(22)= "Death Metal"
mp3_genre(23)= "Pranks"
mp3_genre(24)= "Soundtrack"
mp3_genre(25)= "Euro-Techno"
mp3_genre(26)= "Ambient"
mp3_genre(27)= "Trip-Hop"
mp3_genre(28)= "Vocal"
mp3_genre(29)= "Jazz+Funk"
mp3_genre(30)= "Fusion"
mp3_genre(31)= "Trance"
mp3_genre(32)= "Classical"
mp3_genre(33)= "Instrumental"
mp3_genre(34)= "Acid"
mp3_genre(35)= "House"
mp3_genre(36)= "Game"
mp3_genre(37)= "Sound Clip"
mp3_genre(38)= "Gospel"
mp3_genre(39)= "Noise"
mp3_genre(40)= "AlternRock"
mp3_genre(41)= "Bass"
mp3_genre(42)= "Soul"
mp3_genre(43)= "Punk"
mp3_genre(44)= "Space"
mp3_genre(45)= "Meditative"
mp3_genre(46)= "Instrumental Pop"
mp3_genre(47)= "Instrumental Rock"
mp3_genre(48)= "Ethnic"
mp3_genre(49)= "Gothic"
mp3_genre(50)= "Darkwave"
mp3_genre(51)= "Techno-Industrial"
mp3_genre(52)= "Electronic"
mp3_genre(53)= "Pop-Folk"
mp3_genre(54)= "Eurodance"
mp3_genre(55)= "Dream"
mp3_genre(56)= "Southern Rock"
mp3_genre(57)= "Comedy"
mp3_genre(58)= "Cult"
mp3_genre(59)= "Gangsta"
mp3_genre(60)= "Top 40"
mp3_genre(61)= "Christian Rap"
mp3_genre(62)= "Pop/Funk"
mp3_genre(63)= "Jungle"
mp3_genre(64)= "Native American"
mp3_genre(65)= "Cabaret"
mp3_genre(66)= "New Wave"
mp3_genre(67)= "Psychadelic"
mp3_genre(68)= "Rave"
mp3_genre(69)= "Showtunes"
mp3_genre(70)= "Trailer"
mp3_genre(71)= "Lo-Fi"
mp3_genre(72)= "Tribal"
mp3_genre(73)= "Acid Punk"
mp3_genre(74)= "Acid Jazz"
mp3_genre(75)= "Polka"
mp3_genre(76)= "Retro"
mp3_genre(77)= "Musical"
mp3_genre(78)= "Rock & Roll"
mp3_genre(79)= "Hard Rock"
Global mp3_FileSize
Type id3v1
Field key$
Field Dat$
End Type
Type id3v2
Field key$
Field flags
Field Dat$
Field size
Field start
End Type
Type AudioFrame
Field mpegVersion$
Field mpegLayer$
Field CRCprotection
Field Bitrate
Field samplerate
Field padding
Field PrivateBit
Field Channel$
Field ModeExtension_intensity
Field ModeExtension_MS
Field copyright
Field Original
Field Emphasis$
Field num
Field framelen
Field framestart
End Type
Global filename$ = RequestFile$("","mp3")
; "Anlysing: "+filename
; "----"
readTagv1(filename)
file = mp3_openFile(filename)
analyseMP3(file)
file = mp3_closeFile(filename)
; "----"
mp3_printAudioFrame(Last AudioFrame)
; "----"
For t1.id3v1 = Each id3v1
mp3_printID3v1(t1)
Next
; "----"
For t2.id3v2 = Each id3v2
mp3_printID3v2(t2)
Next
Function mp3_printID3v1(t.id3v1)
If t\key = "Genre"
; t\key+": "+mp3_genre(Int(t\dat))
Else
; t\key+": "+t\dat
EndIf
End Function
Function mp3_printID3v2(t.id3v2)
; t\key+": "+t\dat
End Function
Function mp3_openFile(filename$)
If Not FileType(filename) = 1 Then Return False
file = ReadFile(filename)
mp3_FileSize = FileSize(filename)
Return file
End Function
Function mp3_closeFile(filename$)
If Not FileType(filename) = 1 Then Return False
file = ReadFile(filename)
Return file
End Function
Function analyseMP3(file)
SeekFile(file,0)
readTagv2(file)
While Not Eof(file)
a.audioframe = mp3_readAudioFrame.AudioFrame(file,count)
If a = Null
; "interupt by "+FilePos(file)
Exit
Else
lastvalid.Audioframe = a
EndIf
count = count + 1
Wend
; "Analysed "+count+" Audioframes"
End Function
Function mp3_readAudioFrame.AudioFrame(file,count)
pos = FilePos(file)
b1 = ReadByte(file)
b2 = ReadByte(file)
b3 = ReadByte(file)
b4 = ReadByte(file)
If b1 <> $ff And (b2 And 224) <> 224
; "Frame syncronizer not found"
SeekFile(file,FilePos(file)-4)
Return Null
EndIf
a.AudioFrame = New AudioFrame
a\framestart = pos
a\num = count
MPEGversionID = (b2 And 24) Shr 3
a\mpegVersion = mp3_mvi(MPEGversionID)
MPEGlayerID = (b2 And 6) Shr 1
a\mpegLayer = mp3_mli(MPEGlayerID)
a\CRCprotection = (b2 And $1)
BitrateID = (b3 And $f0) Shr 4
a\BitRate = Int(mp3_bri(BitrateID)) * 1000
SamplerateID = (b3 And $c) Shr 2
a\SampleRate = Int(mp3_sri(SamplerateID))
a\Padding = (b3 And $2) Shr 1
a\privateBit = (b3 And 1)
channelID = (b4 And $C0) Shr 6
a\channel = mp3_chi(channelID)
a\ModeExtension_intensity = (b4 And $10) Shr 5
a\ModeExtension_MS = (b4 And $20) Shr 6
a\copyright = (b4 And $8)
a\original = (b4 And $4)
emphasisID = (b4 And $3)
a\emphasis = mp3_emi(emphasisID)
a\FrameLen = Floor((144.0 * Float(a\BitRate) / Float(a\SampleRate) ) + a\Padding)
SeekFile(file,FilePos(file)+a\framelen-4)
Return a
End Function
Function mp3_printAudioFrame(a.audioframe)
; "Audioframe "+a\num
; "MPEG Version: " + a\mpegVersion
; "MPEG Layer: " + a\mpegLayer
If a\CRCprotection
; "NOT Protected by CRC"
Else
; "Protected by CRC"
EndIf
looser= + a\BitRate + " bps"
; "Samplig rate frequency: " + a\SampleRate+" hz"
If a\Padding
; "Frame is padded"
Else
; "Frame is not padded"
EndIf
If a\privateBit
; "private bit is set"
Else
; "private bit is not set"
EndIf
; "Channel: " + a\channel+" mode"
; "Mode Extension: "
If a\ModeExtension_intensity
; "Intensity Stereo on"
Else
; "Intensity Stereo off"
EndIf
If a\ModeExtension_MS
; "MS Stereo on"
Else
; "MS Stereo off"
EndIf
If a\copyright
; "Audio is copyrighted"
Else
; "Audio is not copyrighted"
EndIf
If a\original
; "Original media"
Else
; "Copy of original media"
EndIf
; "Emphasis: " + a\emphasis
; "Framelength: "+a\FrameLen
End Function
Function readTagv1(filename$)
If Not FileType(filename) = 1 Then Return False
file = ReadFile(filename)
SeekFile(file,FileSize(filename)-128)
For i=0 To 2
txt$ = txt$ + Chr(ReadByte(file))
Next
If txt = "TAG"
; "ID3 v1 Tag present"
txt = ""
For i=0 To 29
songname$ = songname$ + Chr(ReadByte(file))
Next
t.id3v1 = New id3v1
t\key = "Songname"
t\dat = Trim(songname)
For i=0 To 29
Artist$ = Artist$ + Chr(ReadByte(file))
Next
t.id3v1 = New id3v1
t\key = "Artist"
t\dat = Trim(artist)
For i=0 To 29
Album$ = Album$ + Chr(ReadByte(file))
Next
t.id3v1 = New id3v1
t\key = "Album"
t\dat = Trim(album)
txt = ""
For i=0 To 3
year$ = year$ + Chr(ReadByte(file))
Next
t.id3v1 = New id3v1
t\key = "Year"
t\dat = Trim(year)
For i=0 To 29
Comment$ = Comment$ + Chr(ReadByte(file))
Next
t.id3v1 = New id3v1
t\key = "Comment"
t\dat = Trim(comment)
For i=0 To 0
genre = ReadByte(file)
Next
t.id3v1 = New id3v1
t\key = "Genre"
t\dat = Trim(genre)
EndIf
End Function
Function readTagv2(file)
For i=0 To 2
txt$ = txt$ + Chr(ReadByte(file))
Next
If txt = "ID3"
;read TAG version
hiVersion = ReadByte(file)
lowVersion = ReadByte(file)
; "ID3 v2 Tag present (version: "+hiVersion+"/"+lowVersion+")"
;read flags
flags = ReadByte(file)
;read size of tag
b = ReadInt(file)
size = syncsafeInt(b)
While tagpos < size
;read frame TAG
txt = ""
b1 = ReadByte(file)
tagpos = tagpos + 1
If b1
t.id3v2 = New id3v2
t\start = FilePos(file)-1
b2 = ReadByte(file)
b3 = ReadByte(file)
b4 = ReadByte(file)
tagpos = tagpos + 3
txt$ = Chr(b1) + Chr(b2) + Chr(b3) + Chr(b4)
t\key = txt
framesize = syncsafeInt(ReadInt(file))
tagpos = tagpos + 4
t\size = framesize
flags = ReadShort(file)
tagpos = tagpos + 2
t\flags = flags
txt$ = ""
For i= 1 To framesize
txt = txt + Chr(ReadByte(file))
tagpos = tagpos + 1
Next
t\dat$ = Trim(txt)
EndIf
;WaitKey
Wend
Else
SeekFile(file,0)
EndIf
End Function
Function syncsafeInt(b)
b1 = b And $ff000000
b2 = b And $00ff0000
b3 = b And $0000ff00
b4 = b And $000000ff
b1 = (b And $ff000000) Shr 24
b2 = (b And $00ff0000) Shr 8
b3 = (b And $0000ff00) Shr 8
b4 = (b And $000000ff) Shr 24
b4 = b4 Shr 3
b3 = b3 Shr 2
b2 = b2 Shr 1
size = b4 Or b3 Or b2 Or b1
Return size
End Function
y=looser/1000
Print "Bitrate: "+y
z#=FileSize(filename$)/1024.0
bits = z*1024*8
time# = (bits/(y*1000)) ;this is in seconds
;calculate min/secs
min% = Floor(time/60)
sec% = time Mod 60
Print min + " minutes " + sec + " seconds"
WaitKey()
End |
Comments
| ||
| I had to take out all the other stuff I didn't need... |
| ||
Need to change:
Global filename$ = RequestFile$("","mp3")
For this to run without extraneous files. Substituting in a valid path&filename, however works fine. |
| ||
| Calculations with the floating poitns are somewhat inaccurate. Here I have devised a method to read the duration (And much more) from the ID V2 TAGs. http://www.blitzbasic.com/logs/userlog.php?log=1719&user=2370 |
Code Archives Forum