private void dequantize_sample(float[][] xr, int ch, int gr)
{
gr_info_s gr_info = (si.ch[ch].gr[gr]);
int cb = 0;
int next_cb_boundary;
int cb_begin = 0;
int cb_width = 0;
int index = 0, t_index, j;
float g_gain;
float[][] xr_1d = xr;
// choose correct scalefactor band per block type, initalize boundary
if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2))
{
if (gr_info.mixed_block_flag != 0)
next_cb_boundary = sfBandIndex[sfreq].l[1];
// LONG blocks: 0,1,3
else
{
cb_width = sfBandIndex[sfreq].s[1];
next_cb_boundary = (cb_width << 2) - cb_width;
cb_begin = 0;
}
}
else
{
next_cb_boundary = sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3
}
// Compute overall (global) scaling.
g_gain = (float) System.Math.Pow(2.0, (0.25 * (gr_info.global_gain - 210.0)));
for (j = 0; j < nonzero[ch]; j++)
{
// Modif E.B 02/22/99
int reste = j % SSLIMIT;
int quotien = (int) ((j - reste) / SSLIMIT);
if (is_1d[j] == 0)
xr_1d[quotien][reste] = 0.0f;
else
{
int abv = is_1d[j];
if (is_1d[j] > 0)
xr_1d[quotien][reste] = g_gain * t_43[abv];
else
xr_1d[quotien][reste] = - g_gain * t_43[- abv];
}
}
// apply formula per block type
for (j = 0; j < nonzero[ch]; j++)
{
// Modif E.B 02/22/99
int reste = j % SSLIMIT;
int quotien = (int) ((j - reste) / SSLIMIT);
if (index == next_cb_boundary)
{
/* Adjust critical band boundary */
if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2))
{
if (gr_info.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 ((gr_info.window_switching_flag != 0) && (((gr_info.block_type == 2) && (gr_info.mixed_block_flag == 0)) || ((gr_info.block_type == 2) && (gr_info.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]))); */
int idx = scalefac[ch].s[t_index][cb] << gr_info.scalefac_scale;
idx += (gr_info.subblock_gain[t_index] << 2);
xr_1d[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])); */
int idx = scalefac[ch].l[cb];
if (gr_info.preflag != 0)
idx += pretab[cb];
idx = idx << gr_info.scalefac_scale;
xr_1d[quotien][reste] *= two_to_negative_half_pow[idx];
}
index++;
}
for (j = nonzero[ch]; j < 576; j++)
{
// Modif E.B 02/22/99
int reste = j % SSLIMIT;
int quotien = (int) ((j - reste) / SSLIMIT);
if (reste < 0)
reste = 0;
if (quotien < 0)
quotien = 0;
xr_1d[quotien][reste] = 0.0f;
}
return ;
}