Блог программатора |
||||||||
| Главная | Последние правки | Поиcк | Все страницы | Редактор | Админ | Печать | ||||||||
Чтение информации о файле в формате mp3Формат очень простой. Для начала приведу таблицу с описанием заголовка (он идет сразу с сначала файла):<TABLE cellSpacing=0 cellPadding=7 width=570 border=1> <TR> <TD vAlign=top width="29%"><P><b>Name of Field</B></P></TD> <TD vAlign=top width="17%"><P><b>Bit Numbers</B></P></TD> <TD vAlign=top width="25%"><P><b>Code to Extract</B></P></TD> <TD vAlign=top width="29%"><P><b>Meaning</B></P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Frame Sync</P><P>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.</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 0 ] 0:7</P></TD> <TD vAlign=top width="25%"><P>InBuf[ 0 ]</P></TD> <TD vAlign=top width="29%"><P>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.</P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Frame Sync <I>continued</I></P></TD> <TD vAlign=top width="17%"><P>inBuf[ 1 ] 5:7</P></TD> <TD vAlign=top width="25%"><P>(InBuf[ 1 ] >> 5) & 7</P></TD> <TD vAlign=top width="29%"><P>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.</P></TD></TR> <TR> <TD vAlign=top width="29%"><P>Audio Version (phase)</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 1 ] 3:4</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 1 ] >>3) & 3</P></TD> <TD vAlign=top width="29%"><P>The next two bits tell the MPEG version:</P><UL><LI>0 = MPEG-2.5 (a non-standard extension to MPEG-2)</LI><LI>1 = reserved</LI><LI>2 = MPEG-2</LI><LI>3 = MPEG-1</LI></UL></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Layer</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 1 ] 1:2</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 1 ] >> 1) & 3</P></TD> <TD vAlign=top width="29%"><P>The next two bits tell the layer:</P><UL><LI>0 = reserved</LI><LI>1 = Layer III</LI><LI>2 = Layer II</LI><LI>3 = Layer I</LI></UL></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Protection Bit</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 1 ] 0</P></TD> <TD vAlign=top width="25%"><P>InBuf[ 1 ] & 1</P></TD> <TD vAlign=top width="29%"><P>If this bit is 0, the header is followed by two bytes of error detection bits before the audio data starts.</P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Bit Rate Index</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 2 ] 4:7</P></TD> <TD vAlign=top width="25%"><P>(InBuf[ 2 ] >> 4) & 15</P></TD> <TD vAlign=top width="29%"><P>The next four bits are a row index into a doubly subscripted arry of bit rates.</P><P>See note below.</P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Sampling Rate Index</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 2 ] 2:3</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 2 ] >>) & 3</P></TD> <TD vAlign=top width="29%"><P>For MPEG-1, the values are as follows:</P><UL><LI>0 = 44,100 Hz</LI><LI>1 = 48,000 Hz</LI><LI>2 = 32,000 Hz</LI><LI>3 = reserved</LI></UL></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Padding Bit</P></TD> <TD vAlign=top width="17%"><P>InBuf[ 2 ] 1</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 2 ] >> 1) & 1</P></TD> <TD vAlign=top width="29%"><P>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.</P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Private Bit</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 2 ] 0</P></TD> <TD vAlign=top width="25%"><P>InBuf[ 2 ] & 1</P></TD> <TD vAlign=top width="29%"><P>Different programs can interpret this bit different ways.</P></TD></TR> <TR> <TD vAlign=top width="29%"><P>Channel Mode</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 3 ] 6:7</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 3 ] >> 6) & 3</P></TD> <TD vAlign=top width="29%"><P>This two bit code tells whether the information is in stereo or not:</P><UL><LI>0 = Stereo</LI><LI>1 = Joint Stereo</LI><LI>2 = Dual Channel</LI><LI>3 = Single Channel</LI></UL></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Mode Extension</P><P>(Only if Joint Stereo)</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 3 ] 4:5</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 3 ] >> 4) & 3</P></TD> <TD vAlign=top width="29%"><P>Used internally by the decoding algorithm.</P></TD></TR> <TR> <TD vAlign=top width="29%"><P>Copyright</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 3 ] 3</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 3 ] >> 3) & 1</P></TD> <TD vAlign=top width="29%"><P>If this bit is set, the audio material is copyrighted.</P></TD></TR> <TR> <TD vAlign=top width="29%"><P>Original</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 3 ] 2</P></TD> <TD vAlign=top width="25%"><P>(inBuf[ 3 ] >> 2) & 1</P></TD> <TD vAlign=top width="29%"><P>If this bit is set, this file is the orginal media used to hold the audio information.</P></TD> </TR> <TR> <TD vAlign=top width="29%"><P>Emphasis</P></TD> <TD vAlign=top width="17%"><P>inBuf[ 3 ] 0:1</P></TD> <TD vAlign=top width="25%"><P>InBuf[ 3 ] & 3</P></TD> <TD vAlign=top width="29%"><P>Used internally by the decoding algorithm.</P></TD> </TR></TABLE> <BR> <TABLE cellSpacing=0 cellPadding=7 width=409 border=1> <TR> <TD vAlign=top><I><P align=center>Notes on the Bit Rate Table:</I></P></TD> </TR> <TR> <TD vAlign=top height=232><P>The column index for the Bit Rate table is derived from the combination of the phase and layer as follows:</P><DIR><DIR><P>0 Phase 1, Layer I</P><P>1 Phase 1, Later II</P><P>2 Phase 1, Layer III</P><P>3 Phase 2 or 2.5, Layer I</P><P>4 Phase 2 or 2.5, Layer II or III</P></DIR></DIR></TD> </TR> <TR> <TD vAlign=top><P>The row index should never equal fifteen.</P></TD> </TR> <TR> <TD vAlign=top><P>The Bit Rate Table is avalable as a public array of <I>int</I> named <FONT face=Arial>bitRateTable</FONT> in class MP3header.</P></TD> </TR></TABLE> Информация о исполнителе, альбоме, годе, жанре храниться в последних 128 байтах файла. Следующая таблица описывает формат к котором она храниться: <TABLE cellSpacing=0 cellPadding=7 width=216 border=1> <TR> <TD vAlign=top width="31%"><P align=center><B>Bytes</B></P></TD> <TD vAlign=top width="69%"><P align=center><B>Meaning</B></P></TD> </TR> <TR> <TD vAlign=top width="31%"><P>0:2</P></TD> <TD vAlign=top width="69%"><P>Must be "TAG".<BR>If not, there is no ID3 tag in this file</P></TD> </TR> <TR> <TD vAlign=top width="31%"><P>3:32</P></TD> <TD vAlign=top width="69%"><P>Song Title</P></TD> </TR> <TR> <TD vAlign=top width="31%"><P>33:62</P></TD> <TD vAlign=top width="69%"><P>Performer's Name</P></TD></TR> <TR> <TD vAlign=top width="31%"><P>63:92</P></TD> <TD vAlign=top width="69%"><P>Name of the Album</P></TD> </TR> <TR> <TD vAlign=top width="31%"><P>93:96</P></TD> <TD vAlign=top width="69%"><P>Year</P></TD></TR> <TR> <TD vAlign=top width="31%"><P>97:126</P></TD> <TD vAlign=top width="69%"><P>Comment</P></TD> </TR> <TR> <TD vAlign=top width="31%"><P>127</P></TD> <TD vAlign=top width="69%"><P>Genre</P></TD> </TR></TABLE> Пример класса, вычитывающий информацию из 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);
}
}
}Таблица жанров: public final String[] genreNames = {
"Blues", "Classic Rock", "Country",
"Dance", "Disco", "Funk",
"Grunge", "Hip-Hop", "Jazz",
"Metal", "New Age", "Oldies",
"Other", "Pop", "R&B",
"Rap", "Reggae", "Rock",
"Techno", "Industrial", "Alternative",
"Ska", "Death Metal", "Pranks",
"Soundtrack", "Euro-Techno", "Ambient",
"Trip-Hop", "Vocal", "Jazz+Funk",
"Fusion", "Trance", "Classical",
"Instrumental", "Acid", "House",
"Game", "Sound Clip", "Gospel",
"Noise", "AlternRock", "Bass",
"Soul", "Punk", "Space",
"Meditative", "Instrumental Pop", "Instrumental Rock",
"Ethnic", "Gothic", "Darkwave",
"Techno-Industrial", "Electronic", "Pop-Folk",
"Eurodance", "Dream", "Southern Rock",
"Comedy", "Cult", "Gangsta",
"Top 40", "Christian Rap", "Pop/Funk",
"Jungle", "Native American", "Cabaret",
"New Wave", "Psychadelic", "Rave",
"Show Tune", "Trailer", "Lo-Fi",
"Tribal", "Acid Punk", "Acid Jazz",
"Polka", "Retro", "Musical",
"Rock & Roll", "Hard Rock",
};
|
Главная Софт Хард Политеги SimpleWiki ![]() Почта ![]() Мой номер ICQ 456824974 ![]() Архив: 01.2010 02.2010 03.2010 04.2010 05.2010 06.2010 07.2010 Радио «Анонимус» ![]()
Blog ![]() Add bookmark: |
|||||||
|
© Komenda Viacheslav |
||||||||