Structuring categories.
"{ Package: '__NoProject__' }"
"{ NameSpace: SaugFix }"
ApplicationModel subclass:#MP3FileHeader
instanceVariableNames:'long filesize'
classVariableNames:''
poolDictionaries:''
category:'Description'
!
!MP3FileHeader class methodsFor:'instance creation'!
from: aFilename
^ super new filename: aFilename
! !
!MP3FileHeader methodsFor:'accessing'!
bitrate
"/ Original table from a MP3 documentation:
"/
"/ Bit 16 Bit 17 Bit 18 Bit 19 Dezimal MPEG 1 MPEG 1 MPEG 1 MPEG 2 MPEG 2 MPEG 2
"/ Layer I Layer II Layer III Layer I Layer II Layer III
"/ 0 0 0 0 0 - - - - - -
"/ 0 0 0 1 1 32 kBit/s 32 kBit/s 32 kBit/s 32 kBit/s 32 kBit/s 8 kBit/s
"/ 0 0 1 0 2 64 kBit/s 48 kBit/s 40 kBit/s 64 kBit/s 48 kBit/s 16 kBit/s
"/ 0 0 1 1 3 96 kBit/s 56 kBit/s 48 kBit/s 96 kBit/s 56 kBit/s 24 kBit/s
"/ 0 1 0 0 4 128 kBit/s 64 kBit/s 56 kBit/s 128 kBit/s 64 kBit/s 32 kBit/s
"/ 0 1 0 1 5 160 kBit/s 80 kBit/s 64 kBit/s 160 kBit/s 80 kBit/s 64 kBit/s
"/ 0 1 1 0 6 192 kBit/s 96 kBit/s 80 kBit/s 192 kBit/s 96 kBit/s 80 kBit/s
"/ 0 1 1 1 7 224 kBit/s 112 kBit/s 96 kBit/s 224 kBit/s 112 kBit/s 56 kBit/s
"/ 1 0 0 0 8 256 kBit/s 128 kBit/s 112 kBit/s 256 kBit/s 128 kBit/s 64 kBit/s
"/ 1 0 0 1 9 288 kBit/s 160 kBit/s 128 kBit/s 288 kBit/s 160 kBit/s 128 kBit/s
"/ 1 0 1 0 10 320 kBit/s 192 kBit/s 160 kBit/s 320 kBit/s 192 kBit/s 160 kBit/s
"/ 1 0 1 1 11 352 kBit/s 224 kBit/s 192 kBit/s 352 kBit/s 224 kBit/s 112 kBit/s
"/ 1 1 0 0 12 384 kBit/s 256 kBit/s 224 kBit/s 384 kBit/s 256 kBit/s 128 kBit/s
"/ 1 1 0 1 13 416 kBit/s 320 kBit/s 256 kBit/s 416 kBit/s 320 kBit/s 256 kBit/s
"/ 1 1 1 0 14 448 kBit/s 384 kBit/s 320 kBit/s 448 kBit/s 384 kBit/s 320 kBit/s
"/ 1 1 1 1 15 - - - - - -
| index |
index := 1 + ( ( long copy bitAnd: 2r00000000000000001111000000000000 ) >> ( 32 - 20 ) ).
index := index + ( 16 * ( self layer - 1 ) ) + ( 48 * ( self version - 1) ).
^ #( nil 32 64 96 128 160 192 224 256 288 320 352 384 416 448 nil
nil 32 48 56 64 80 96 112 128 160 192 224 256 320 384 nil
nil 32 40 48 56 64 80 96 112 128 160 192 224 256 320 nil
nil 32 64 96 128 160 192 224 256 288 320 352 384 416 448 nil
nil 32 48 56 64 80 96 112 128 160 192 224 256 320 348 nil
nil 8 16 24 32 64 80 56 64 128 160 112 128 256 320 nil ) at: index.
!
copyright
^ ( long bitAt: ( 32 - 28 ) ) == 1.
!
filename: aFilename
| stream start |
stream := aFilename readStream.
start := stream peek.
"Is there a sync?"
start = 255 asCharacter ifFalse: [ "Seems to have an MP3V2 ID3 Information at file beginning."
stream skipFor: 255 asCharacter. "We take next sync point. Best we could do."
stream backStep.
stream backStep.
].
long := stream nextLong.
filesize := stream size.
stream close.
"/ Transcript
"/ cr;
"/ showCr: aFilename asString;
"/ cr;
"/ showCr: 'header: ', ( ( long printStringBase: 2 ) leftPaddedTo: 32 with: $0 );
"/ showCr: 'Size: ', filesize printString;
"/ showCr: 'Version: ', self version printString;
"/ showCr: 'Layer: ', self layer printString;
"/ showCr: 'Protection: ', self protection printString;
"/ showCr: 'Bitrate: ', self bitrate printString;
"/ showCr: 'Sample frequnecy: ', self samplingFrequency printString;
"/ showCr: 'Padding: ', self padding printString;
"/ showCr: 'Private: ', self private printString;
"/ showCr: 'Mode: ', self mode printString;
"/ showCr: 'Copyright: ', self copyright printString;
"/ showCr: 'Original home: ', self originalHome printString;
"/ showCr: 'Length: ', self length printString.
!
layer
"/ Original table from a MP3 documentation:
"/
"/ Bit 13 Bit 14 Dezimal Layer
"/ 0 0 0 undef.
"/ 0 1 1 Layer III
"/ 1 0 2 Layer II
"/ 1 1 3 Layer I
| index |
index := ( long copy bitAnd: 2r00000000000001100000000000000000 ) >> ( 32 - 15 ).
( index == 0 ) ifTrue: [ ^ nil ].
^ 4 - index.
!
length
"Not in the header, but we're able to calculate it. ;-)"
"Calculation is not absolute precise, because instead of filesize we should"
"calculate with the size of the used data without any headers and ID3-tags."
"The lack of precision is about one second."
| time |
time := Time fromSeconds: ( 8 * filesize / ( self bitrate * 1000 ) ) asInteger.
^ ( ( time minutes printString ) leftPaddedTo: 2 with: $ ) , ':', ( ( time seconds printString ) paddedTo:2 with: $0 ).
!
mode
"/ Original table from a MP3 documentation:
"/
"/ Bit 24 Bit 25 Dezimal Mode
"/ 0 0 0 Stereo
"/ 0 1 1 Joint-Stereo
"/ 1 0 2 Dual-Channel
"/ 1 1 3 Mono
| index |
index := 1 + ( ( long copy bitAnd: 2r00000000000000000000000011000000 ) >> ( 32 - 26 ) ).
^ #( #Stereo #'Joint-Stereo' #'Dual-Channel' #Mono ) at: index.
!
originalHome
^ ( long bitAt: ( 32 - 29 ) ) == 1.
!
padding
^ ( long bitAt: ( 32 - 22 ) ) == 1.
!
private
^ ( long bitAt: ( 32 - 23 ) ) == 1.
!
protection
^ ( long bitAt: ( 32 - 15 ) ) == 1.
!
samplingFrequency
"/ Original table from a MP3 documentation:
"/
"/ Bit 20 Bit 21 Dezimal MPEG 1 MPEG 2
"/ 0 0 0 44100 Hz 22050 Hz
"/ 0 1 1 48000 Hz 24000 Hz
"/ 1 0 2 32000 Hz 16000 Hz
"/ 1 1 3 - -
| index |
index := 1 + ( ( long copy bitAnd: 2r00000000000000000000110000000000 ) >> ( 32 - 22 ) ).
index := index + ( 4 * ( self version - 1 ) ).
^ #( 44100 22050 48000 nil
24000 32000 16000 nil ) at: index.
!
version
"/ Original table from a MP3 documentation:
"/
"/ Bit 12 MPEG Version
"/ 0 MPEG 2
"/ 1 MPEG 1
^ 2 - ( long bitAt: ( 32 - 12 ) ).
! !
!MP3FileHeader class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libview2/ApplicationModel.st,v 1.146 2000-11-07 14:33:17 martin Exp $'
! !