[bb] Length of mp3 by Sonari Eclipsi Onimari [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : Length of mp3
Author : Sonari Eclipsi Onimari
Posted : 1+ years ago

Description : 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!!!

Code :
Code: blitzbasic
;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 tkey = "Genre"
		; tkey+": "+mp3_genre(Int(tdat))
	Else
		; tkey+": "+tdat
	EndIf
End Function

Function mp3_printID3v2(t.id3v2)
	; tkey+": "+tdat
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
	aframestart = pos
	a
um = count
	
	MPEGversionID = (b2 And 24) Shr 3
	ampegVersion = mp3_mvi(MPEGversionID)

	MPEGlayerID = (b2 And 6) Shr 1
	ampegLayer = mp3_mli(MPEGlayerID)
	
	aCRCprotection = (b2 And $1)
	
	BitrateID = (b3 And $f0) Shr 4
	aBitRate = Int(mp3_bri(BitrateID)) * 1000
	
	SamplerateID = (b3 And $c) Shr 2
	aSampleRate = Int(mp3_sri(SamplerateID))
	
	aPadding = (b3 And $2) Shr 1

	aprivateBit = (b3 And 1)

	channelID = (b4 And $C0) Shr 6
	achannel = mp3_chi(channelID)

	aModeExtension_intensity = (b4 And $10) Shr 5
	aModeExtension_MS = (b4 And $20) Shr 6
	
	acopyright = (b4 And $8)

	aoriginal = (b4 And $4)
	
	emphasisID = (b4 And $3)
	aemphasis = mp3_emi(emphasisID)
	
	aFrameLen = Floor((144.0 * Float(aBitRate) / Float(aSampleRate) ) + aPadding)
	
	SeekFile(file,FilePos(file)+aframelen-4)
	Return a
End Function

Function mp3_printAudioFrame(a.audioframe)
	; "Audioframe "+a
um
	; "MPEG Version: " + ampegVersion
	; "MPEG Layer: " + ampegLayer
	If aCRCprotection
		; "NOT Protected by CRC"
	Else
		; "Protected by CRC"
	EndIf
	
	looser= + aBitRate + " bps"	
	; "Samplig rate frequency: " + aSampleRate+" hz"
	
	If aPadding
		; "Frame is padded"
	Else
		; "Frame is not padded"
	EndIf

	If aprivateBit 
		; "private bit is set"
	Else
		; "private bit is not set"
	EndIf

	; "Channel: " + achannel+" mode"

	; "Mode Extension: "
	If aModeExtension_intensity
		; "Intensity Stereo on"
	Else
		; "Intensity Stereo off"
	EndIf
	If aModeExtension_MS
		; "MS Stereo on"
	Else
		; "MS Stereo off"
	EndIf

	If acopyright
		; "Audio is copyrighted"
	Else
		; "Audio is not copyrighted"
	EndIf

	If aoriginal
		; "Original media"
	Else
		; "Copy of original media"
	EndIf
	
	; "Emphasis: " + aemphasis
	
	; "Framelength: "+aFrameLen
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
		tkey = "Songname"
		tdat = Trim(songname)
		
		For i=0 To 29
			Artist$ = Artist$ + Chr(ReadByte(file))
		Next
		t.id3v1 = New id3v1
		tkey = "Artist"
		tdat = Trim(artist)

		For i=0 To 29
			Album$ = Album$ + Chr(ReadByte(file))
		Next
		t.id3v1 = New id3v1
		tkey = "Album"
		tdat = Trim(album)

		txt = ""
		For i=0 To 3
			year$ = year$ + Chr(ReadByte(file))
		Next
		t.id3v1 = New id3v1
		tkey = "Year"
		tdat = Trim(year)

		For i=0 To 29
			Comment$ = Comment$ + Chr(ReadByte(file))
		Next
		t.id3v1 = New id3v1
		tkey = "Comment"
		tdat = Trim(comment)

		For i=0 To 0
			genre = ReadByte(file)
		Next
		t.id3v1 = New id3v1
		tkey = "Genre"
		tdat = 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
				tstart = FilePos(file)-1
				
				b2 = ReadByte(file)
				b3 = ReadByte(file)
				b4 = ReadByte(file)
				tagpos = tagpos + 3

				txt$ = Chr(b1) + Chr(b2) + Chr(b3) + Chr(b4)
				tkey = txt
				
				framesize = syncsafeInt(ReadInt(file))
				tagpos = tagpos + 4
				tsize = framesize
				
				flags = ReadShort(file)
				tagpos = tagpos + 2
				tflags = flags
								
				txt$ = ""
				For i= 1 To framesize
					txt = txt + Chr(ReadByte(file))
					tagpos = tagpos + 1
				Next
				tdat$ = 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 :


Sonari Eclipsi Onimari(Posted 1+ years ago)

 I had to take out all the other stuff I didn't need...


_PJ_(Posted 1+ years ago)

 Need to change:
Code: BASIC
Global filename$ = RequestFile$("","mp3")

For this to run without extraneous files.Substituting in a valid path&filename, however works fine.


_PJ_(Posted 1+ years ago)

 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.<a href="../logs/userloga501.html?log=1719&user=2370" target="_blank">http://www.blitzbasic.com/logs/userlog.php?log=1719&user=2370</a> [/i]