/*
* 11/19/04 1.0 moved to LGPL.
*
* 18/06/01 Michael Scheerer, Fixed bugs which causes
* negative indexes in method huffmann_decode and in method
* dequanisize_sample.
*
* 16/07/01 Michael Scheerer, Catched a bug in method
* huffmann_decode, which causes an outOfIndexException.
* Cause : Indexnumber of 24 at SfBandIndex,
* which has only a length of 22. I have simply and dirty
* fixed the index to <= 22, because I'm not really be able
* to fix the bug. The Indexnumber is taken from the MP3
* file and the origin Ma-Player with the same code works
* well.
*
* 02/19/99 Java Conversion by E.B, javalayer@javazoom.net
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
/**
* Class Implementing Layer 3 Decoder.
*
* @since 0.0
*/
// @LATTICE("FS
>> 4) / 5;
new_slen[1] = (scalefac_comp >>> 4) % 5;
new_slen[2] = (scalefac_comp & 0xF) >>> 2;
new_slen[3] = (scalefac_comp & 3);
si.ch[ch].gr[gr].preflag = 0;
blocknumber = 0;
} else if (scalefac_comp < 500) {
new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5;
new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5;
new_slen[2] = (scalefac_comp - 400) & 3;
new_slen[3] = 0;
si.ch[ch].gr[gr].preflag = 0;
blocknumber = 1;
} else if (scalefac_comp < 512) {
new_slen[0] = (scalefac_comp - 500) / 3;
new_slen[1] = (scalefac_comp - 500) % 3;
new_slen[2] = 0;
new_slen[3] = 0;
si.ch[ch].gr[gr].preflag = 1;
blocknumber = 2;
}
}
if ((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) {
int_scalefac_comp = scalefac_comp >>> 1;
if (int_scalefac_comp < 180) {
new_slen[0] = int_scalefac_comp / 36;
new_slen[1] = (int_scalefac_comp % 36) / 6;
new_slen[2] = (int_scalefac_comp % 36) % 6;
new_slen[3] = 0;
si.ch[ch].gr[gr].preflag = 0;
blocknumber = 3;
} else if (int_scalefac_comp < 244) {
new_slen[0] = ((int_scalefac_comp - 180) & 0x3F) >>> 4;
new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2;
new_slen[2] = (int_scalefac_comp - 180) & 3;
new_slen[3] = 0;
si.ch[ch].gr[gr].preflag = 0;
blocknumber = 4;
} else if (int_scalefac_comp < 255) {
new_slen[0] = (int_scalefac_comp - 244) / 3;
new_slen[1] = (int_scalefac_comp - 244) % 3;
new_slen[2] = 0;
new_slen[3] = 0;
si.ch[ch].gr[gr].preflag = 0;
blocknumber = 5;
}
}
for (@LOC("THIS,LayerIIIDecoder.NS") int x = 0; x < 45; x++)
// why 45, not 54?
scalefac_buffer[x] = 0;
m = 0;
for (@LOC("THIS,LayerIIIDecoder.NS") int i = 0; i < 4; i++) {
for (@LOC("THIS,LayerIIIDecoder.NS") int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i]; j++) {
scalefac_buffer[m] = (new_slen[i] == 0) ? 0 : br.hgetbits(new_slen[i]);
m++;
} // for (unint32 j ...
} // for (uint32 i ...
}
/**
*
*/
@LATTICE("THIS sfBandIndex[sfreq].l.length - 1)
buf1 = sfBandIndex[sfreq].l.length - 1;
region1Start = sfBandIndex[sfreq].l[buf];
region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */
}
index = 0;
// Read bigvalues area
for (@LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i +=
2) {
@LOC("THIS,LayerIIIDecoder.SI2") int htIdx;
if (i < region1Start) {
htIdx = si.ch[ch].gr[gr].table_select[0];
// h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[0]];
} else if (i < region2Start) {
htIdx = si.ch[ch].gr[gr].table_select[1];
// h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
} else {
htIdx = si.ch[ch].gr[gr].table_select[2];
// h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
}
huffcodetab.huffman_decoder(htIdx, x, y, v, w, br);
// if (index >= is_1d.length)
// System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length);
is_1d[index++] = x[0];
is_1d[index++] = y[0];
CheckSumHuff = CheckSumHuff + x[0] + y[0];
// System.out.println("x = " + x[0] + " y = " + y[0]);
}
// Read count1 area
@LOC("THIS,LayerIIIDecoder.SI2") int htIdx = si.ch[ch].gr[gr].count1table_select + 32;
// h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32];
num_bits = br.hsstell();
while ((num_bits < part2_3_end) && (index < 576)) {
huffcodetab.huffman_decoder(htIdx, x, y, v, w, br);
is_1d[index++] = v[0];
is_1d[index++] = w[0];
is_1d[index++] = x[0];
is_1d[index++] = y[0];
CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0];
// System.out.println("v = "+v[0]+" w = "+w[0]);
// System.out.println("x = "+x[0]+" y = "+y[0]);
num_bits = br.hsstell();
}
if (num_bits > part2_3_end) {
br.rewindNbits(num_bits - part2_3_end);
index -= 4;
}
num_bits = br.hsstell();
// Dismiss stuffing bits
if (num_bits < part2_3_end)
br.hgetbits(part2_3_end - num_bits);
// Zero out rest
if (index < 576)
nonzero[ch] = index;
else
nonzero[ch] = 576;
if (index < 0)
index = 0;
// may not be necessary
for (; index < 576; index++)
is_1d[index] = 0;
}
@LATTICE("THIS,IN,THISLOC=THIS,RETURNLOC=THIS")
private int huffcodetab_huffman_decoder(@LOC("IN") int h) {
// TODO need to move huffmancodetab implementation here
return 0;
}
/**
*
*/
private void i_stereo_k_values(@LOC("THIS,LayerIIIDecoder.LR") int is_pos,
@LOC("THIS,LayerIIIDecoder.LR") int io_type, @LOC("THIS,LayerIIIDecoder.LR") int i) {
if (is_pos == 0) {
k[0][i] = 1.0f;
k[1][i] = 1.0f;
} else if ((is_pos & 1) != 0) {
k[0][i] = io[io_type][(is_pos + 1) >>> 1];
k[1][i] = 1.0f;
} else {
k[0][i] = 1.0f;
k[1][i] = io[io_type][is_pos >>> 1];
}
}
/**
*
*/
// @LATTICE("OUT 0)
ro[ch][quotien][reste] = g_gain * t_43[abv];
else {
if (-abv < t_43.length)
ro[ch][quotien][reste] = -g_gain * t_43[-abv];
else
ro[ch][quotien][reste] = -g_gain * (float) Math.pow(-abv, d43);
}
} else {
if (is_1d[j] > 0)
ro[ch][quotien][reste] = g_gain * (float) Math.pow(abv, d43);
else
ro[ch][quotien][reste] = -g_gain * (float) Math.pow(-abv, d43);
}
}
}
// apply formula per block type
for (j = 0; j < nonzero[ch]; j++) {
// Modif E.B 02/22/99
@LOC("THIS,LayerIIIDecoder.NZ") int reste = j % SSLIMIT;
@LOC("THIS,LayerIIIDecoder.NZ") int quotien = (int) ((j - reste) / SSLIMIT);
if (index == next_cb_boundary) { /* Adjust critical band boundary */
if ((si.ch[ch].gr[gr].window_switching_flag != 0) && (si.ch[ch].gr[gr].block_type == 2)) {
if (si.ch[ch].gr[gr].mixed_block_flag != 0) {
if (index == sfBandIndex[sfreq].l[8]) {
next_cb_boundary = sfBandIndex[sfreq].s[4];
next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
cb = 3;
cb_width = sfBandIndex[sfreq].s[4] - sfBandIndex[sfreq].s[3];
cb_begin = sfBandIndex[sfreq].s[3];
cb_begin = (cb_begin << 2) - cb_begin;
} else if (index < sfBandIndex[sfreq].l[8]) {
next_cb_boundary = sfBandIndex[sfreq].l[(++cb) + 1];
} else {
next_cb_boundary = sfBandIndex[sfreq].s[(++cb) + 1];
next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
cb_begin = sfBandIndex[sfreq].s[cb];
cb_width = sfBandIndex[sfreq].s[cb + 1] - cb_begin;
cb_begin = (cb_begin << 2) - cb_begin;
}
} else {
next_cb_boundary = sfBandIndex[sfreq].s[(++cb) + 1];
next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
cb_begin = sfBandIndex[sfreq].s[cb];
cb_width = sfBandIndex[sfreq].s[cb + 1] - cb_begin;
cb_begin = (cb_begin << 2) - cb_begin;
}
} else { // long blocks
next_cb_boundary = sfBandIndex[sfreq].l[(++cb) + 1];
}
}
// Do long/short dependent scaling operations
if ((si.ch[ch].gr[gr].window_switching_flag != 0)
&& (((si.ch[ch].gr[gr].block_type == 2) && (si.ch[ch].gr[gr].mixed_block_flag == 0)) || ((si.ch[ch].gr[gr].block_type == 2)
&& (si.ch[ch].gr[gr].mixed_block_flag != 0) && (j >= 36)))) {
t_index = (index - cb_begin) / cb_width;
/*
* xr[sb][ss] *= pow(2.0, ((-2.0 * gr_info.subblock_gain[t_index]) -(0.5
* * (1.0 + gr_info.scalefac_scale) scalefac[ch].s[t_index][cb])));
*/
@LOC("THIS,LayerIIIDecoder.SI1") int idx =
scalefac[ch].s[t_index][cb] << si.ch[ch].gr[gr].scalefac_scale;
idx += (si.ch[ch].gr[gr].subblock_gain[t_index] << 2);
ro[ch][quotien][reste] *= two_to_negative_half_pow[idx];
} else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks
/*
* xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info.scalefac_scale)
* (scalefac[ch].l[cb] + gr_info.preflag * pretab[cb]));
*/
@LOC("THIS,LayerIIIDecoder.SI1") int idx = scalefac[ch].l[cb];
if (si.ch[ch].gr[gr].preflag != 0)
idx += pretab[cb];
idx = idx << si.ch[ch].gr[gr].scalefac_scale;
ro[ch][quotien][reste] *= two_to_negative_half_pow[idx];
}
index++;
}
for (j = nonzero[ch]; j < 576; j++) {
// Modif E.B 02/22/99
@LOC("THIS,LayerIIIDecoder.NZ") int reste = j % SSLIMIT;
@LOC("THIS,LayerIIIDecoder.NZ") int quotien = (int) ((j - reste) / SSLIMIT);
if (reste < 0)
reste = 0;
if (quotien < 0)
quotien = 0;
ro[ch][quotien][reste] = 0.0f;
}
return;
}
/**
*
*/
// ssjava
// @LATTICE("THIS= 3; sfb--) {
i = sfBandIndex[sfreq].s[sfb];
lines = sfBandIndex[sfreq].s[sfb + 1] - i;
i = (i << 2) - i + (j + 1) * lines - 1;
while (lines > 0) {
if (ro[1][i / 18][i % 18] != 0.0f) {
// MDM: in java, array access is very slow.
// Is quicker to compute div and mod values.
// if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
sfbcnt = sfb;
sfb = -10;
lines = -10;
}
lines--;
i--;
} // while (lines > 0)
} // for (sfb=12 ...
sfb = sfbcnt + 1;
if (sfb > max_sfb)
max_sfb = sfb;
while (sfb < 12) {
temp = sfBandIndex[sfreq].s[sfb];
sb = sfBandIndex[sfreq].s[sfb + 1] - temp;
i = (temp << 2) - temp + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = scalefac[1].s[j][sfb];
if (is_pos[i] != 7)
if (lsf)
i_stereo_k_values(is_pos[i], io_type, i);
else
is_ratio[i] = TAN12[is_pos[i]];
i++;
} // for (; sb>0...
sfb++;
} // while (sfb < 12)
sfb = sfBandIndex[sfreq].s[10];
sb = sfBandIndex[sfreq].s[11] - sfb;
sfb = (sfb << 2) - sfb + j * sb;
temp = sfBandIndex[sfreq].s[11];
sb = sfBandIndex[sfreq].s[12] - temp;
i = (temp << 2) - temp + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = is_pos[sfb];
if (lsf) {
k[0][i] = k[0][sfb];
k[1][i] = k[1][sfb];
} else {
is_ratio[i] = is_ratio[sfb];
}
i++;
} // for (; sb > 0 ...
}
if (max_sfb <= 3) {
i = 2;
ss = 17;
sb = -1;
while (i >= 0) {
if (ro[1][i][ss] != 0.0f) {
sb = (i << 4) + (i << 1) + ss;
i = -1;
} else {
ss--;
if (ss < 0) {
i--;
ss = 17;
}
} // if (ro ...
} // while (i>=0)
i = 0;
while (sfBandIndex[sfreq].l[i] <= sb)
i++;
sfb = i;
i = sfBandIndex[sfreq].l[i];
for (; sfb < 8; sfb++) {
sb = sfBandIndex[sfreq].l[sfb + 1] - sfBandIndex[sfreq].l[sfb];
for (; sb > 0; sb--) {
is_pos[i] = scalefac[1].l[sfb];
if (is_pos[i] != 7)
if (lsf)
i_stereo_k_values(is_pos[i], io_type, i);
else
is_ratio[i] = TAN12[is_pos[i]];
i++;
} // for (; sb>0 ...
} // for (; sfb<8 ...
} // for (j=0 ...
} else { // if (gr_info.mixed_block_flag)
for (@LOC("THIS,LayerIIIDecoder.RO1") int j = 0; j < 3; j++) {
@LOC("THIS,LayerIIIDecoder.RO1") int sfbcnt;
sfbcnt = -1;
for (sfb = 12; sfb >= 0; sfb--) {
temp = sfBandIndex[sfreq].s[sfb];
lines = sfBandIndex[sfreq].s[sfb + 1] - temp;
i = (temp << 2) - temp + (j + 1) * lines - 1;
while (lines > 0) {
if (ro[1][i / 18][i % 18] != 0.0f) {
// MDM: in java, array access is very slow.
// Is quicker to compute div and mod values.
// if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
sfbcnt = sfb;
sfb = -10;
lines = -10;
}
lines--;
i--;
} // while (lines > 0) */
} // for (sfb=12 ...
sfb = sfbcnt + 1;
while (sfb < 12) {
temp = sfBandIndex[sfreq].s[sfb];
sb = sfBandIndex[sfreq].s[sfb + 1] - temp;
i = (temp << 2) - temp + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = scalefac[1].s[j][sfb];
if (is_pos[i] != 7)
if (lsf)
i_stereo_k_values(is_pos[i], io_type, i);
else
is_ratio[i] = TAN12[is_pos[i]];
i++;
} // for (; sb>0 ...
sfb++;
} // while (sfb<12)
temp = sfBandIndex[sfreq].s[10];
temp2 = sfBandIndex[sfreq].s[11];
sb = temp2 - temp;
sfb = (temp << 2) - temp + j * sb;
sb = sfBandIndex[sfreq].s[12] - temp2;
i = (temp2 << 2) - temp2 + j * sb;
for (; sb > 0; sb--) {
is_pos[i] = is_pos[sfb];
if (lsf) {
k[0][i] = k[0][sfb];
k[1][i] = k[1][sfb];
} else {
is_ratio[i] = is_ratio[sfb];
}
i++;
} // for (; sb>0 ...
} // for (sfb=12
} // for (j=0 ...
} else { // if (gr_info.window_switching_flag ...
i = 31;
ss = 17;
sb = 0;
while (i >= 0) {
if (ro[1][i][ss] != 0.0f) {
sb = (i << 4) + (i << 1) + ss;
i = -1;
} else {
ss--;
if (ss < 0) {
i--;
ss = 17;
}
}
}
i = 0;
while (sfBandIndex[sfreq].l[i] <= sb)
i++;
sfb = i;
i = sfBandIndex[sfreq].l[i];
for (; sfb < 21; sfb++) {
sb = sfBandIndex[sfreq].l[sfb + 1] - sfBandIndex[sfreq].l[sfb];
for (; sb > 0; sb--) {
is_pos[i] = scalefac[1].l[sfb];
if (is_pos[i] != 7)
if (lsf)
i_stereo_k_values(is_pos[i], io_type, i);
else
is_ratio[i] = TAN12[is_pos[i]];
i++;
}
}
sfb = sfBandIndex[sfreq].l[20];
for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i < 576); sb--) {
is_pos[i] = is_pos[sfb]; // error here : i >=576
if (lsf) {
k[0][i] = k[0][sfb];
k[1][i] = k[1][sfb];
} else {
is_ratio[i] = is_ratio[sfb];
}
i++;
} // if (gr_info.mixed_block_flag)
} // if (gr_info.window_switching_flag ...
} // if (i_stereo)
i = 0;
for (sb = 0; sb < SBLIMIT; sb++)
for (ss = 0; ss < SSLIMIT; ss++) {
if (is_pos[i] == 7) {
if (ms_stereo) {
lr[0][sb][ss] = (ro[0][sb][ss] + ro[1][sb][ss]) * 0.707106781f;
lr[1][sb][ss] = (ro[0][sb][ss] - ro[1][sb][ss]) * 0.707106781f;
} else {
lr[0][sb][ss] = ro[0][sb][ss];
lr[1][sb][ss] = ro[1][sb][ss];
}
} else if (i_stereo) {
if (lsf) {
lr[0][sb][ss] = ro[0][sb][ss] * k[0][i];
lr[1][sb][ss] = ro[0][sb][ss] * k[1][i];
} else {
lr[1][sb][ss] = ro[0][sb][ss] / (float) (1 + is_ratio[i]);
lr[0][sb][ss] = lr[1][sb][ss] * is_ratio[i];
}
}
/*
* else { System.out.println("Error in stereo processing\n"); }
*/
i++;
}
} // channels == 2
}
/**
*
*/
// @LATTICE("THIS