/*
* Layer3.java -- MPEG 1.0/2.0/2.5 Audio Layer III (MP3) 解码
* Copyright (C) 2010
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
*
* If you would like to negotiate alternate licensing terms, you may do
* so by contacting the author: <http://jmp123.sourceforge.net/>
*/
package jmp123.decoder;
public final class Layer3 implements IFrame123 {
private static Header objHeader;
private static Synthesis objFilter;
private static BitStream bsMainInfo;
private static int maxGr;
private static int intChannels;
private static int[] intSfbIdxLong;
private static int[] intSfbIdxShort;
private static boolean isMPEG1;
private static boolean isIntensityStereo; //true:强度立体声
public Layer3(BitStream bs,Header h) {
bsMainInfo = bs;
objHeader = h;
intChannels = objHeader.getChannels();
objFilter = new Synthesis(intChannels);
isMPEG1 = objHeader.getVersion() == Header.MPEG1 ? true : false;
maxGr = isMPEG1 ? 2 : 1;
objSI = new SideInfo();
objHuffBits = new HuffmanBits(bsMainInfo);
bsSI = new BitStream(36);
scfL = new int[2][23];
scfS = new int[2][3][13];
is = new int[32 * 18 + 4];
xr = new float[2][32][18];
intWidthLong = new int[22];
intWidthShort = new int[13];
floatRawOut = new float[36];
floatPrevBlck = new float[2][32][18];
cs = new float[] { 0.85749293f, 0.8817420f, 0.94962865f, 0.98331459f,
0.99551782f, 0.99916056f, 0.99989920f, 0.99999316f };
ca = new float[] { -0.51449576f, -0.47173197f, -0.31337745f, -0.18191320f,
-0.09457419f, -0.04096558f, -0.0141986f, -3.69997467e-3f};
int i;
/*
* floatPowIS[]:用于查表求 v^(4/3),v是经哈夫曼解码出的一个(正)值,该值的范围是0..8191
*/
floatPowIS = new float[8207];
for (i = 0; i < 8207; i++)
floatPowIS[i] = (float) Math.pow(i, 4.0 / 3.0);
/*
* pow_2[] -- 用于查表求 2 ^ exp, exp 是长块(long block)逆量化的指数
*/
floatPow2 = new float[256 + 118 + 4];
for (i = -256; i < 118 + 4; i++)
floatPow2[i + 256] = (float) Math.pow(2.0, -0.25 * (i + 210));
//---------------------------------------------------------------------
//待解码文件的不同特征用到不同的变量.初始化:
//---------------------------------------------------------------------
int intSfreq = objHeader.getSampleFrequency();
intSfreq += isMPEG1 ? 0 : ((objHeader.getVersion() == Header.MPEG2) ? 3 : 6);
/*
* ANNEX B,Table 3-B.8. Layer III scalefactor bands
*/
switch (intSfreq) {
case 0:
/* MPEG 1, sampling_frequency=0, 44.1kHz */
intSfbIdxLong = new int[] { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44,
52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 16, 22, 30, 40, 52, 66,
84, 106, 136, 192 };
break;
case 1:
/* MPEG 1, sampling_frequency=1, 48kHz */
intSfbIdxLong = new int[] { 0, 4, 8, 12, 16, 20, 24, 30, 36, 42,
50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 16, 22, 28, 38, 50, 64,
80, 100, 126, 192 };
break;
case 2:
/* MPEG 1, sampling_frequency=2, 32kHz */
intSfbIdxLong = new int[] { 0, 4, 8, 12, 16, 20, 24, 30, 36, 44,
54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 16, 22, 30, 42, 58, 78,
104, 138, 180, 192 };
break;
case 3:
/* MPEG 2, sampling_frequency=0, 22.05kHz */
intSfbIdxLong = new int[] { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66,
80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 18, 24, 32, 42, 56, 74,
100, 132, 174, 192 };
break;
case 4:
/* MPEG 2, sampling_frequency=1, 24kHz */
intSfbIdxLong = new int[] { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66,
80, 96, 114, 136, 162, 194, 232, 278, 330, 394, 464, 540, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,
104, 136, 180, 192 };
break;
case 5:
/* MPEG 2, sampling_frequency=2, 16kHz */
intSfbIdxLong = new int[] { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66,
80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,
104, 134, 174, 192 };
break;
case 6:
/* MPEG 2.5, sampling_frequency=0, 11.025kHz */
intSfbIdxLong = new int[] { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66,
80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,
104, 134, 174, 192 };
break;
case 7:
/* MPEG 2.5, sampling_frequency=1, 12kHz */
intSfbIdxLong = new int[] { 0, 6, 12, 18, 24, 30, 36, 44, 54, 66,
80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576 };
intSfbIdxShort = new int[] { 0, 4, 8, 12, 18, 26, 36, 48, 62, 80,
104, 134, 174, 192 };
break;
case 8:
/* MPEG 2.5, sampling_frequency=2, 8kHz */
intSfbIdxLong = new int[] { 0, 12, 24, 36, 48, 60, 72, 88, 108, 132,
160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576 };
intSfbIdxShort = new int[] { 0, 8, 16, 24, 36, 52, 72, 96, 124,
160, 162, 164, 166, 192 };
break;
}
for (i = 0; i < 22; i++)
intWidthLong[i] = intSfbIdxLong[i + 1] - intSfbIdxLong[i];
for (i = 0; i < 13; i++)
intWidthShort[i] = intSfbIdxShort[i + 1] - intSfbIdxShort[i];
//---------------------------------------------------------------------
//强度立体声:
isIntensityStereo = objHeader.isIntensity();
if(isIntensityStereo) {
if (isMPEG1) //MPEG 1.0
is_coef = new float[] { 0.0f, 0.211324865f, 0.366025404f, 0.5f,
0.633974596f, 0.788675135f, 1.0f };
else //MPEG 2.0/2.5
lsf_is_coef = new float[][] {
{ 0.840896415f, 0.707106781f, 0.594603558f, 0.5f, 0.420448208f,
0.353553391f, 0.297301779f, 0.25f, 0.210224104f, 0.176776695f,
0.148650889f, 0.125f, 0.105112052f, 0.088388348f, 0.074325445f },
{ 0.707106781f, 0.5f, 0.353553391f, 0.25f, 0.176776695f, 0.125f,
0.088388348f, 0.0625f, 0.044194174f, 0.03125f, 0.022097087f,
0.015625f, 0.011048543f, 0.0078125f, 0.005524272f } };
}
//-----------------------------------------------------------------
//MPEG 2.0/2.5
if (!isMPEG1) {
i_slen2 = new int[256]; // MPEG 2.0 slen for intensity stereo
n_slen2 = new int[512]; // MPEG 2.0 slen for 'normal' mode
nr_of_sfb = new byte[][][] {
//ISO/IEC 13818-3 subclause 2.4.3.2 nr_of_sfbx x=1..4
{ { 6, 5, 5, 5 }, { 6, 5, 7, 3 }, { 11, 10, 0, 0 },
{ 7, 7, 7, 0 }, { 6, 6, 6, 3 }, { 8, 8, 5, 0 } },
{ { 9, 9, 9, 9 }, { 9, 9, 12, 6 }, { 18, 18, 0, 0 },
{ 12, 12, 12, 0 }, { 12, 9, 9, 6 }, { 15, 12, 9, 0 } },
{ { 6, 9, 9, 9 }, { 6, 9, 12, 6 }, { 15, 18, 0, 0 },
{ 6, 15, 12, 0 }, { 6, 12, 9, 6 }, { 6, 18, 9, 0 } } };
//ISO/IEC 13818-3 subclause 2.4.3.2 slenx x=1..4
int j, k, l, n;
for (i = 0; i < 5; i++)
for (j = 0; j < 6; j++)
for (k = 0; k < 6; k++) {
n = k + j * 6 + i * 36;
i_slen2[n] = i | (j << 3) | (k << 6) | (3 << 12);
}
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++) {
n = k + (j << 2) + (i << 4);
i_slen2[n + 180] = i | (j << 3) | (k << 6) | (4 << 12);
}
for (i = 0; i < 4