Code: Select all
; ___ ID ___
#MPEG25 = 0 ; MPEG Version 2.5 (later extension of MPEG 2)
#MPEG2 = 2 ; MPEG Version 2 (ISO/IEC 13818-3)
#MPEG1 = 3 ; MPEG Version 1 (ISO/IEC 11172-3)
; __ Layer ___
#Layer1 = 3
#Layer2 = 2
#Layer3 = 1
; ___ Channel Mode ___
#Stereo = 0
#Joint = 1 ; Joint stereo (Stereo)
#DualMono = 2 ; Dual channel (2 mono channels)
#Mono = 3 ; Single channel (Mono)
; ___ Emphasis ___
#None = 0
#MS50_15 = 1 ; 50/15 ms
#CCIT_J17 = 3 ; CCIT J.17
Structure MP3_Structure
ID.i
Layer.i
Protection.i
Bitrate.i
Samplingrate.i
Padding.i
Private.i
Channel.i
Extension.i
Copyright.i
Original.i
Emphasis.i
EndStructure
Procedure.w uint8(Value.b)
ProcedureReturn Value & $FF
EndProcedure
Procedure.i uint16(Value.w, BigEndian.i=#True)
If BigEndian
ProcedureReturn (Value>>8&$FF) | (Value<<8&$FF00)
Else
ProcedureReturn Value & $FFFF
EndIf
EndProcedure
Procedure.i GetBitrate(ID.i, Layer.i, Value.i)
If ID = #MPEG1 ;{ MPEG 1
Select Value
Case 1
ProcedureReturn 32
Case 2
Select Layer
Case #Layer1
ProcedureReturn 64
Case #Layer2
ProcedureReturn 48
Case #Layer3
ProcedureReturn 40
EndSelect
Case 3
Select Layer
Case #Layer1
ProcedureReturn 96
Case #Layer2
ProcedureReturn 56
Case #Layer3
ProcedureReturn 48
EndSelect
Case 4
Select Layer
Case #Layer1
ProcedureReturn 128
Case #Layer2
ProcedureReturn 64
Case #Layer3
ProcedureReturn 56
EndSelect
Case 5
Select Layer
Case #Layer1
ProcedureReturn 160
Case #Layer2
ProcedureReturn 80
Case #Layer3
ProcedureReturn 64
EndSelect
Case 6
Select Layer
Case #Layer1
ProcedureReturn 192
Case #Layer2
ProcedureReturn 96
Case #Layer3
ProcedureReturn 80
EndSelect
Case 7
Select Layer
Case #Layer1
ProcedureReturn 224
Case #Layer2
ProcedureReturn 112
Case #Layer3
ProcedureReturn 96
EndSelect
Case 8
Select Layer
Case #Layer1
ProcedureReturn 256
Case #Layer2
ProcedureReturn 128
Case #Layer3
ProcedureReturn 112
EndSelect
Case 9
Select Layer
Case #Layer1
ProcedureReturn 288
Case #Layer2
ProcedureReturn 160
Case #Layer3
ProcedureReturn 128
EndSelect
Case 10
Select Layer
Case #Layer1
ProcedureReturn 320
Case #Layer2
ProcedureReturn 192
Case #Layer3
ProcedureReturn 160
EndSelect
Case 11
Select Layer
Case #Layer1
ProcedureReturn 352
Case #Layer2
ProcedureReturn 224
Case #Layer3
ProcedureReturn 192
EndSelect
Case 12
Select Layer
Case #Layer1
ProcedureReturn 384
Case #Layer2
ProcedureReturn 256
Case #Layer3
ProcedureReturn 224
EndSelect
Case 13
Select Layer
Case #Layer1
ProcedureReturn 416
Case #Layer2
ProcedureReturn 320
Case #Layer3
ProcedureReturn 256
EndSelect
Case 14
Select Layer
Case #Layer1
ProcedureReturn 448
Case #Layer2
ProcedureReturn 384
Case #Layer3
ProcedureReturn 320
EndSelect
EndSelect
;}
Else
Select Value
Case 1
If Layer = #Layer1
ProcedureReturn 32
Else
ProcedureReturn 8
EndIf
Case 2
If Layer = #Layer1
ProcedureReturn 48
Else
ProcedureReturn 16
EndIf
Case 3
If Layer = #Layer1
ProcedureReturn 56
Else
ProcedureReturn 24
EndIf
Case 4
If Layer = #Layer1
ProcedureReturn 64
Else
ProcedureReturn 32
EndIf
Case 5
If Layer = #Layer1
ProcedureReturn 80
Else
ProcedureReturn 40
EndIf
Case 6
If Layer = #Layer1
ProcedureReturn 96
Else
ProcedureReturn 48
EndIf
Case 7
If Layer = #Layer1
ProcedureReturn 112
Else
ProcedureReturn 56
EndIf
Case 8
If Layer = #Layer1
ProcedureReturn 128
Else
ProcedureReturn 64
EndIf
Case 9
If Layer = #Layer1
ProcedureReturn 144
Else
ProcedureReturn 80
EndIf
Case 10
If Layer = #Layer1
ProcedureReturn 160
Else
ProcedureReturn 96
EndIf
Case 11
If Layer = #Layer1
ProcedureReturn 176
Else
ProcedureReturn 112
EndIf
Case 12
If Layer = #Layer1
ProcedureReturn 192
Else
ProcedureReturn
EndIf
Case 13
If Layer = #Layer1
ProcedureReturn 224
Else
ProcedureReturn 144
EndIf
Case 14
If Layer = #Layer1
ProcedureReturn 256
Else
ProcedureReturn 160
EndIf
EndSelect
EndIf
EndProcedure
Procedure.i GetSamplingRate(ID.i, Value.i)
Select ID
Case #MPEG1
Select Value
Case 0
ProcedureReturn 44100
Case 1
ProcedureReturn 48000
Case 2
ProcedureReturn 32000
EndSelect
Case #MPEG2
Select Value
Case 0
ProcedureReturn 22050
Case 1
ProcedureReturn 24000
Case 2
ProcedureReturn 16000
EndSelect
Case #MPEG25
Select Value
Case 0
ProcedureReturn 11025
Case 1
ProcedureReturn 12000
Case 2
ProcedureReturn 8000
EndSelect
EndSelect
EndProcedure
Procedure HeaderMP3(File.s, *MP3.MP3_Structure)
Define.i FileID, Size, Result
Define Bytes.w, Byte.b
Define *Memory, *EndMem, *StartMem
FileID = ReadFile(#PB_Any, File)
If FileID
Size = Lof(FileID)
If Size
*Memory = AllocateMemory(Size)
If ReadData(FileID, *Memory, Size)
*StartMem = *Memory
*EndMem = *Memory + Size
Repeat
Bytes = uint16(PeekW(*Memory))
If (Bytes >> 5) & %11111111111 = 2047 : Break : EndIf ; Sync
*Memory + 1
Until *Memory >= *EndMem
If (Bytes >> 5) & %11111111111 = 2047
*MP3\ID = (Bytes >> 3) & %11
*MP3\Layer = (Bytes >> 1) & %11
*MP3\Protection = Bytes & %1
Byte = uint8(PeekB(*Memory + 2))
*MP3\Bitrate = GetBitrate(*MP3\ID, *MP3\Layer, (Byte >> 4) & %1111)
*MP3\Samplingrate = GetSamplingRate(*MP3\ID, (Byte >> 2) & %11)
*MP3\Padding = (Byte >> 1) & %1
*MP3\Private = Byte & %1
Byte = uint8(PeekB(*Memory + 3))
*MP3\Channel = (Byte >> 6) & %11
*MP3\Extension = (Byte >> 4) & %11
*MP3\Copyright = (Byte >> 3) & %1
*MP3\Original = (Byte >> 2) & %1
*MP3\Emphasis = Byte & %11
Result = #True
EndIf
FreeMemory(*StartMem)
EndIf
CloseFile(FileID)
EndIf
EndIf
ProcedureReturn Result
EndProcedure
;- ========== Example ===========================
Define MP3.MP3_Structure
MP3File$ = "D:\Temp\Test.mp3"
If HeaderMP3(MP3File$,@MP3)
Select MP3\ID
Case #MPEG1
Debug "Version: MPEG 1"
Case #MPEG2
Debug "Version: MPEG 2"
Case #MPEG25
Debug "Version: MPEG 2.5"
EndSelect
Select MP3\Layer
Case #Layer1
Debug "Layer: 1"
Case #Layer2
Debug "Layer: 2"
Case #Layer3
Debug "Layer: 3"
EndSelect
Debug "Bitrate: " + Str(MP3\Bitrate)
Debug "Sampling rate: " + Str(MP3\Samplingrate) + "Hz"
Select MP3\Channel
Case #Stereo
Debug "Channel Mode: Stereo"
Case #Joint
Debug "Channel Mode: Joint Stereo"
Case #DualMono
Debug "Channel Mode: Dual channel (2 * Mono)"
Case #Mono
Debug "Channel Mode: Single channel (Mono)"
EndSelect
If MP3\Copyright
Debug "Copyright: yes"
Else
Debug "Copyright: no"
EndIf
EndIf