Формат очень простой. Для начала приведу таблицу с описанием заголовка
(он идет сразу с сначала файла):
Name of Field
Bit Numbers
Code to Extract
Meaning
Frame Sync
A frame can, in principle, start at an arbitray byte offset into the audio stream. The beginning of a frame header is indicated by 11 ones, starting at the beginning of a byte.
inBuf[ 0 ] 0:7
InBuf[ 0 ]
Since the first 11 bits of a header are all 1s, inBuf[ 0 ] must have a decimal value of 255, which is eight ones in binary.
Frame Sync continued
inBuf[ 1 ] 5:7
(InBuf[ 1 ] >> 5) & 7
If inBuf[ 0 ] is 255, and if the first three bits of the next byte have the value 7 (three 1s in binary), the beginning of a valid MP3 header has been found.
Audio Version (phase)
inBuf[ 1 ] 3:4
(inBuf[ 1 ] >>3) & 3
The next two bits tell the MPEG version:
0 = MPEG-2.5 (a non-standard extension to MPEG-2)
1 = reserved
2 = MPEG-2
3 = MPEG-1
Layer
inBuf[ 1 ] 1:2
(inBuf[ 1 ] >> 1) & 3
The next two bits tell the layer:
0 = reserved
1 = Layer III
2 = Layer II
3 = Layer I
Protection Bit
inBuf[ 1 ] 0
InBuf[ 1 ] & 1
If this bit is 0, the header is followed by two bytes of error detection bits before the audio data starts.
Bit Rate Index
inBuf[ 2 ] 4:7
(InBuf[ 2 ] >> 4) & 15
The next four bits are a row index into a doubly subscripted arry of bit rates.
See note below.
Sampling Rate Index
inBuf[ 2 ] 2:3
(inBuf[ 2 ] >>) & 3
For MPEG-1, the values are as follows:
0 = 44,100 Hz
1 = 48,000 Hz
2 = 32,000 Hz
3 = reserved
Padding Bit
InBuf[ 2 ] 1
(inBuf[ 2 ] >> 1) & 1
If this bit is a 1 and the layer is III, the frame has an extra (unused) byte at the end. For layers I and II the padding amount, if present, is four bytes.
Private Bit
inBuf[ 2 ] 0
InBuf[ 2 ] & 1
Different programs can interpret this bit different ways.
Channel Mode
inBuf[ 3 ] 6:7
(inBuf[ 3 ] >> 6) & 3
This two bit code tells whether the information is in stereo or not:
0 = Stereo
1 = Joint Stereo
2 = Dual Channel
3 = Single Channel
Mode Extension
(Only if Joint Stereo)
inBuf[ 3 ] 4:5
(inBuf[ 3 ] >> 4) & 3
Used internally by the decoding algorithm.
Copyright
inBuf[ 3 ] 3
(inBuf[ 3 ] >> 3) & 1
If this bit is set, the audio material is copyrighted.
Original
inBuf[ 3 ] 2
(inBuf[ 3 ] >> 2) & 1
If this bit is set, this file is the orginal media used to hold the audio information.
Emphasis
inBuf[ 3 ] 0:1
InBuf[ 3 ] & 3
Used internally by the decoding algorithm.
Notes on the Bit Rate Table:
The column index for the Bit Rate table is derived from the combination of the phase and layer as follows:
0 Phase 1, Layer I
1 Phase 1, Later II
2 Phase 1, Layer III
3 Phase 2 or 2.5, Layer I
4 Phase 2 or 2.5, Layer II or III
The row index should never equal fifteen.
The Bit Rate Table is avalable as a public array of int named bitRateTable in class MP3header.
Информация о исполнителе, альбоме, годе, жанре храниться в последних 128 байтах файла. Следующая таблица описывает формат к котором она храниться:
Bytes
Meaning
0:2
Must be "TAG". If not, there is no ID3 tag in this file
3:32
Song Title
33:62
Performer's Name
63:92
Name of the Album
93:96
Year
97:126
Comment
127
Genre
Пример класса, вычитывающий информацию из ID3V1 TAGS:
import java.io.*;
public class MP3header
{
private String Artist="";
private String Album="";
private String Song="";
private String fname="";
private long bitrate=0;
private long year=0;
private long stereo=0;
private long fsize=0;
static private int[][] bitRateTable =
{
// Ph 1L-I Ph1 L-II Ph1 L-III Ph2 L-I Ph2 L-II&III
{ 0, 0, 0, 0, 0 },
{ 32000, 32000, 32000, 32000, 8000 },
{ 64000, 48000, 40000, 48000, 16000 },
{ 96000, 56000, 48000, 56000, 24000 },
{ 128000, 64000, 56000, 64000, 32000 },
{ 160000, 80000, 64000, 80000, 40000 },
{ 192000, 96000, 80000, 96000, 48000 },
{ 224000, 112000, 96000, 112000, 56000 },
{ 256000, 128000, 112000, 128000, 64000 },
{ 288000, 160000, 128000, 144000, 80000 },
{ 320000, 192000, 160000, 160000, 96000 },
{ 352000, 224000, 192000, 176000, 112000 },
{ 384000, 256000, 224000, 192000, 128000 },
{ 416000, 320000, 256000, 224000, 144000 },
{ 448000, 384000, 320000, 256000, 160000 },
{ -1, -1, -1, -1, -1 },
};
public void setArtist(String s)
{ Artist=s.trim();
}
public String getArtist()
{ return(Artist.trim());
}
public void setAlbum(String s)
{ Album=s.trim();
}
public String getAlbum()
{ return(Album.trim());
}
public void setSong(String s)
{ Song=s.trim();
}
public String getSong()
{ return(Song.trim());
}
public String getFName()
{ return(fname.trim());
}
public long getFSize()
{ return(fsize);
}
public void setYear(long y)
{ year=y;
}
public long getYear()
{ return(year);
}
public void setBitrate(long b)
{ bitrate=b/1000;
}
public long getBitrate()
{ return(bitrate);
}
public void setStereo(long b)
{ stereo=b;
}
public long getStereo()
{ return(stereo);
}
public void loadInfo(String fname)
{ try{ this.fname=fname;
File f = new File(fname);
long len=f.length();
fsize=len;
byte[] buf=new byte[128];
FileInputStream fis;
fis = new FileInputStream(f);
fis.read(buf,0,128);
fis.close();
int lay=(buf[ 1 ] >> 1) & 3;
int mpeg=(buf[ 1 ] >> 3) & 3;
switch(mpeg)
{
// mpg-1.0
case 3:
switch(lay)
{ case 3: mpeg=0;
break;
case 2: mpeg=1;
break;
case 1: mpeg=2;
break;
}
break;
// mpg-2.0
case 0:
case 2:
switch(lay)
{ case 3: mpeg=3;
break;
case 2:
case 1: mpeg=4;
break;
}
break;
}
int btr=((buf[2]>>4) & 15);
setBitrate(bitRateTable[btr][mpeg]);
setStereo((buf[ 3 ] >> 6) & 3);
fis = new FileInputStream(f);
fis.skip(len-128);
fis.read(buf,0,128);
setSong(new String(buf,3,29));
setArtist(new String(buf,33,30));
setAlbum(new String(buf,63,30));
try{ setYear(Long.parseLong(new String(buf,93,4)));
} catch(Exception e) { setYear(2001);}
fis.close();
} catch(Exception e)
{ System.out.println(""+e);
}
}
}