📄 audio.java
字号:
/*
* @(#)AUDIO.java - parse Audioheaders
*
* Copyright (c) 2003-2005 by dvb.matt, All Rights Reserved.
*
* This file is part of X, a free Java based demux utility.
* X is intended for educational purposes only, as a non-commercial test project.
* It may not be used otherwise. Most parts are only experimental.
*
* The part of audio parsing was derived from the MPEG/Audio
* Software Simulation Group's audio codec and ATSC A/52 in a special modified manner.
*
*
* This program is free software; you can redistribute it free of charge
* and/or modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.sourceforge.dvb.projectx.audio;
import java.io.*; //DM24012004 081.6 int11 add
public class Audio
{
int ID=0;
public int Layer=0;
int Protection_bit=0;
public int Bitrate=0;
public int Sampling_frequency=0;
int Padding_bit=0;
int Private_bit=0;
public int Mode=0;
int Mode_extension=0;
int Copyright=0;
int Original=0;
int Channel=0;
public int Emphasis=0;
public int Size=0;
public int Size_base=0;
int Bound=0; //DM10042004 081.7 int01 add
int Sblimit; //DM10042004 081.7 int01 add
public double Time_length=0.0;
int nID=0;
int nLayer=0;
int nProtection_bit=0;
int nBitrate=0;
int nSampling_frequency=0;
int nPadding_bit=0;
int nPrivate_bit=0;
int nMode=0;
int nMode_extension=0;
int nCopyright=0;
int nOriginal=0;
int nChannel=0;
int nEmphasis=0;
int nSize=0;
int nSize_base=0;
double nTime_length=0;
int lID=0;
int lLayer=0;
int lProtection_bit=0;
int lBitrate=0;
int lSampling_frequency=0;
int lPadding_bit=0;
int lPrivate_bit=0;
int lMode=0;
public int lMode_extension=0;
int lCopyright=0;
int lOriginal=0;
int lChannel=0;
int lEmphasis=0;
int lSize=0;
int lSize_base=0;
double lTime_length=0;
int bitrate_index[][][] = {{
{-1,8000,16000,24000,32000,40000,48000,56000,64000,
80000,96000,112000,128000,144000,160000,0 }, //MPG-2, L3
{-1,8000,16000,24000,32000,40000,48000,56000,64000,
80000,96000,112000,128000,144000,160000,0 }, //MPG-2, L2
{-1,32000,48000,56000,64000,80000,96000,112000,128000,
144000,160000,176000,192000,224000,256000,0 } //MPG-2, L1
},{
{-1,32000,40000,48000,56000,64000,80000,96000,
112000,128000,160000,192000,224000,256000,320000, 0 }, //MPG-1, L3
{-1,32000,48000,56000,64000,80000,96000,112000,
128000,160000,192000,224000,256000,320000,384000, 0 }, //MPG-1, L2
{-1,32000,64000,96000,128000,160000,192000,224000,
256000,288000,320000,352000,384000,416000,448000,0 } //MPG-1, L1
},{
{-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L3??
28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 },
{-1, 6000, 8000, 10000, 12000, 16000, 20000, 24000, //MPG-2.5, L2
28000, 320000, 40000, 48000, 56000, 64000, 80000, 0 },
{-1, 8000, 12000, 16000, 20000, 24000, 32000, 40000, //MPG-2.5, L1
48000, 560000, 64000, 80000, 96000, 112000, 128000, 0 }
}};
int frequency_index[][] = {
{ 22050,24000,16000,0 }, //MPG2 - 22.05,24,16khz
{ 44100,48000,32000,0 }, //MPG1 - 44.1 ,48,32khz
{ 11025,12000,8000,0 } //MPG2.5 - 11.025,12,8khz
};
double time_index[] = { 0.0,103680000.0,103680000.0,34560000.0 }; //L3,L2,L1 * 90
String[] dID = {
"MPEG-2","MPEG-1","MPEG-2.5"
};
String[] dLayer = {
"n.a.","Layer3","Layer2","Layer1"
};
String[] dCRC = {
"noCRC","CRC"
};
String[] dMode = {
"stereo","jstereo","dual","mono"
};
/*** parse mpa Header ***/
//DM10042004 081.7 int01 changed
public int MPA_parseHeader(byte[] frame, int pos)
{
int sblimit = 32;
if ( (0xFF&frame[pos])!=0xFF || (0xF0&frame[pos+1])!=0xF0 )
return -1;
ID = 1&frame[pos+1]>>>3;
Emphasis = 3&frame[pos+3];
if (ID==1 && Emphasis==2)
ID = 2;
if ( (Layer = 3&frame[pos+1]>>>1) < 1)
return -2;
Protection_bit = (1&frame[pos+1]) ^ 1;
if ( (Bitrate = bitrate_index[ID][Layer-1][0xF&frame[pos+2]>>>4]) < 1)
return -3;
if ( (Sampling_frequency = frequency_index[ID][3&frame[pos+2]>>>2]) == 0)
return -4;
Padding_bit = 1&frame[pos+2]>>>1;
Private_bit = 1&frame[pos+2];
Mode = 3&frame[pos+3]>>>6;
Mode_extension = 3&frame[pos+3]>>>4;
if (Mode==0)
Mode_extension=0;
Bound = Mode==1 ? ((Mode_extension + 1) << 2) : sblimit;
Channel = Mode==3 ? 1: 2;
Copyright = 1&frame[pos+3]>>>3;
Original = 1&frame[pos+3]>>>2;
Time_length = time_index[Layer]/Sampling_frequency;
if (ID==1 && Layer==2) { // MPEG-1, L2 restrictions
if(Bitrate/Channel < 32000)
return -5; /* unsupported bitrate */
if(Bitrate/Channel > 192000)
return -6; /* unsupported bitrate */
if (Bitrate < 56000)
{
if(Sampling_frequency == 32000)
Sblimit = 12;
else
Sblimit = 8;
}
else if (Bitrate < 96000)
Sblimit = 27;
else
{
if (Sampling_frequency == 48000)
Sblimit = 27;
else
Sblimit = 30;
}
if (Bound > Sblimit)
Bound = Sblimit;
}
else if (Layer==2) // MPEG-2
{
Sblimit = 30;
}
if (Layer<3) {
if (Bound > Sblimit)
Bound = Sblimit;
Size = (Size_base = 144*Bitrate/Sampling_frequency) + Padding_bit;
return 1;
} else {
Sblimit = 32;
Size = (Size_base = (12*Bitrate/Sampling_frequency)*4) + (4*Padding_bit);
return 2;
}
}
/*** parse next mpa Header ***/
public int MPA_parseNextHeader(byte[] frame, int pos) {
if ( (0xFF&frame[pos])!=0xFF || (0xF0&frame[pos+1])!=0xF0 )
return -1;
nID = 1&frame[pos+1]>>>3;
nEmphasis = 3&frame[pos+3];
if (nID==1 && nEmphasis==2)
nID = 2;
if ( (nLayer = 3&frame[pos+1]>>>1) < 1)
return -2;
nProtection_bit = (1&frame[pos+1]) ^ 1;
if ( (nBitrate = bitrate_index[nID][nLayer-1][0xF&frame[pos+2]>>>4]) < 1)
return -3;
if ( (nSampling_frequency = frequency_index[nID][3&frame[pos+2]>>>2]) == 0)
return -4;
nPadding_bit = 1&frame[pos+2]>>>1;
nPrivate_bit = 1&frame[pos+2];
nMode = 3&frame[pos+3]>>>6;
nMode_extension = 3&frame[pos+3]>>>4;
if (nMode==0)
nMode_extension=0;
nChannel = (nMode==3) ? 1: 2;
nCopyright = 1&frame[pos+3]>>>3;
nOriginal = 1&frame[pos+3]>>>2;
nTime_length = time_index[nLayer]/nSampling_frequency;
if (nID==1 && nLayer==2) { // MPEG-1,L2 restrictions
if(nBitrate/Channel < 32000)
return -5; /* unsupported bitrate */
if(nBitrate/Channel > 192000)
return -6; /* unsupported bitrate */
}
if (nLayer<3) {
nSize = (nSize_base = 144*nBitrate/nSampling_frequency) + nPadding_bit;
return 1;
} else {
nSize = (nSize_base = (12*nBitrate/nSampling_frequency)*4) + (4*nPadding_bit);
return 2;
}
}
/*** save last mpa header ***/
public void saveHeader() {
lID=ID;
lLayer=Layer;
lProtection_bit=Protection_bit;
lBitrate=Bitrate;
lSampling_frequency=Sampling_frequency;
lPadding_bit=Padding_bit;
lPrivate_bit=Private_bit;
lMode=Mode;
lMode_extension=Mode_extension;
lCopyright=Copyright;
lOriginal=Original;
lChannel=Channel;
lEmphasis=Emphasis;
lSize=Size;
lSize_base=Size_base;
lTime_length=Time_length;
}
/*** verify current & last mpa header ***/
public int MPA_compareHeader() {
if (lID!=ID)
return 1;
else if (lLayer!=Layer)
return 2;
else if (lBitrate!=Bitrate)
return 3;
else if (lSampling_frequency!=Sampling_frequency)
return 4;
else if (lProtection_bit!=Protection_bit)
return 5;
else if (lMode!=Mode){ //DM01112003 081.5++ fix
if (Mode+lMode<2)
return 6;
else
return 7;
}else
return 0;
}
/*** display last mpa header ***/
public String MPA_displayHeader() {
return ("" + dID[lID] + ", " + dLayer[lLayer] + ", " + lSampling_frequency + "Hz, " + dMode[lMode] + ", "+ (lBitrate/1000) + "kbps, " + dCRC[lProtection_bit]);
}
/*** display last mpa header ***/
public String MPA_saveAnddisplayHeader() {
saveHeader();
return MPA_displayHeader();
}
/**
* remove CRC from mpa
**/
public byte[] MPA_deleteCRC(byte[] frame)
{
MPA_removePrivateBit(frame);
if ( (frame[1] & 1) == 1)
return frame;
byte[] newframe = new byte[frame.length];
System.arraycopy(frame, 0, newframe, 0, 4);
System.arraycopy(frame, 6, newframe, 4, frame.length - 6);
newframe[1] |= 1;
Protection_bit = 1;
return newframe;
}
/**
* remove private Bit from mpa
**/
private void MPA_removePrivateBit(byte[] frame)
{
if ( (frame[2] & 1) == 0)
return;
frame[2] &= ~1;
Private_bit = 0;
}
int ac3_frequency_index[] = {
48000,44100,32000,0
};
int ac3_bitrate_index[] = {
32000,40000,48000,56000,64000,80000,96000,
112000,128000,160000,192000,224000,256000,
320000,384000,448000,512000,576000,640000,
0,0,0,0,0,0,0,0,0,0,0,0,0 // (fix4)
};
int ac3_size_table[][] = {
{ 128,160,192,224,256,320,384,448,512,640,768,896,1024,1280,1536,1792,2080,2304,2560 },
{ 138,174,208,242,278,348,416,486,556,696,834,974,1114,1392,1670,1950,2228,2506,2786 },
{ 192,240,288,336,384,480,576,672,768,960,1152,1344,1536,1920,2304,2688,3120,3456,3840 }
};
String bsmod[] = {
", CM" , ", ME" , ", K:VI" , ", K:HI" , ", K:D" , ", K:C" , ", K:E" , ", K:VO"
};
String cmixlev[] = {
"", ", cm-3.0dB", ", cm-4.5dB", ", cm-6.0dB", ", cm-4.5dB"
};
String surmixlev[] = {
"", ", sm-3dB", ", sm-6dB", ", sm 0dB", ", sm-6dB"
};
String dsurmod[] = {
"" , ", notDS" , ", DS" , ""
};
String acmod[] = {
"1+1","1/0","2/0","3/0","2/1","3/1","2/2","3/2"
};
int ac3_channels[] = {
2,1,2,3,3,4,4,5
};
String lfe[][] = {
{ ".0",".1" },
{ "","lfe" }
};
/*** parse ac3 Header ***/
public int AC3_parseHeader(byte[] frame, int pos)
{
if ( (0xFF & frame[pos]) != 0xB || (0xFF & frame[pos+1]) != 0x77 )
return -1;
ID = 0;
Emphasis = 0;
Private_bit = 0;
Protection_bit = 0 ^ 1;
if ( (Sampling_frequency = ac3_frequency_index[3 & frame[pos+4]>>>6]) < 1)
return -4;
if ( (Bitrate = ac3_bitrate_index[0x1F & frame[pos+4]>>>1]) < 1)
return -3;
Layer = 7 & frame[pos+5]; //bsmod
Padding_bit = 1 & frame[pos+4];
Mode = 7 & frame[pos+6]>>>5;
Mode_extension = 0;
int mode = (0xFF & frame[pos+6])<<8 | (0xFF & frame[pos+7]);
int skip=0;
if ( (Mode & 1) > 0 && Mode != 1) // cmix
{
Emphasis = 1 + (3 & frame[pos+6]>>>3);
skip++;
}
if ( (Mode & 4) > 0) //surmix
{
Private_bit = 1 + (3 & frame[pos+6]>>>(skip > 0 ? 1 : 3));
skip++;
}
if ( Mode == 2 )
{
Mode_extension |= 6 & mode>>>(10 - (2 * skip)); //DS
skip++;
}
switch (skip)
{ //lfe
case 0:
Mode_extension |= 1 & mode>>>12;
break;
case 1:
Mode_extension |= 1 & mode>>>10;
break;
case 2:
Mode_extension |= 1 & mode>>>8;
break;
case 3:
Mode_extension |= 1 & mode>>>6;
}
Channel = ac3_channels[Mode] + (1 & Mode_extension);
Copyright = 0;
Original = 0;
Time_length = 138240000.0 / Sampling_frequency;
Size = (Size_base = ac3_size_table[3 & frame[pos+4]>>>6][0x1F & frame[pos+4]>>>1]) + Padding_bit * 2;
return 1;
}
/*** parse ac3 Header ***/
public int AC3_parseNextHeader(byte[] frame, int pos)
{
if ( (0xFF & frame[pos]) != 0xB || (0xFF & frame[pos+1]) != 0x77 )
return -1;
nID = 0;
nEmphasis = 0;
nPrivate_bit = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -