📄 specrec.c
字号:
{
ics->sect_sfb_offset[0][i] = swb_offset_512_window[sf_index][i];
ics->swb_offset[i] = swb_offset_512_window[sf_index][i];
}
} else /* if (hDecoder->frameLength == 480) */ {
for (i = 0; i < ics->num_swb; i++)
{
ics->sect_sfb_offset[0][i] = swb_offset_480_window[sf_index][i];
ics->swb_offset[i] = swb_offset_480_window[sf_index][i];
}
}
ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
} else {
#endif
for (i = 0; i < ics->num_swb; i++)
{
ics->group[0].sfb[i].sect_sfb_offset = swb_offset_1024_window[sf_index][i];
ics->swb_offset[i] = swb_offset_1024_window[sf_index][i];
}
ics->group[0].sfb[ics->num_swb].sect_sfb_offset = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
#ifdef LD_DEC
}
#endif
return 0;
case EIGHT_SHORT_SEQUENCE:
ics->num_windows = 8;
ics->group_end = ics->group+1;
ics->group[0].window_group_length = 1;
ics->num_swb = num_swb_128_window[sf_index];
for (i = 0; i < ics->num_swb; i++)
ics->swb_offset[i] = swb_offset_128_window[sf_index][i];
ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8;
for (i = 0; i < ics->num_windows-1; i++) {
if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
{
ics->group_end->window_group_length = 1;
++ics->group_end;
} else {
ics->group_end[-1].window_group_length += 1;
}
}
/* preparation of sect_sfb_offset for short blocks */
for (g = ics->group; g != ics->group_end; g++)
{
uint16_t width;
uint8_t sect_sfb = 0;
uint16_t offset = 0;
for (i = 0; i < ics->num_swb; i++)
{
if (i+1 == ics->num_swb)
{
width = (hDecoder->frameLength/8) - swb_offset_128_window[sf_index][i];
} else {
width = swb_offset_128_window[sf_index][i+1] -
swb_offset_128_window[sf_index][i];
}
width *= g->window_group_length;
g->sfb[sect_sfb++].sect_sfb_offset = offset;
offset += width;
}
g->sfb[sect_sfb].sect_sfb_offset = offset;
}
return 0;
default:
return 1;
}
}
/* iquant() *
/* output = sign(input)*abs(input)^(4/3) */
/**/
static INLINE real_t iquant(int16_t q, const real_t *tab, uint8_t *error)
{
#ifdef FIXED_POINT
/* For FIXED_POINT the iq_table is prescaled by 3 bits (iq_table[]/8) */
/* BIG_IQ_TABLE allows you to use the full 8192 value table, if this is not
* defined a 1026 value table and interpolation will be used
*/
#ifndef BIG_IQ_TABLE
static const real_t errcorr[] = {
REAL_CONST(0), REAL_CONST(1.0/8.0), REAL_CONST(2.0/8.0), REAL_CONST(3.0/8.0),
REAL_CONST(4.0/8.0), REAL_CONST(5.0/8.0), REAL_CONST(6.0/8.0), REAL_CONST(7.0/8.0),
REAL_CONST(0)
};
real_t x1, x2;
#endif
int16_t sgn = 1;
if (q < 0)
{
q = -q;
sgn = -1;
}
if (q < IQ_TABLE_SIZE)
{
//#define IQUANT_PRINT
#ifdef IQUANT_PRINT
//printf("0x%.8X\n", sgn * tab[q]);
printf("%d\n", sgn * tab[q]);
#endif
return sgn * tab[q];
}
#ifndef BIG_IQ_TABLE
if (q >= 8192)
{
*error = 17;
return 0;
}
/* linear interpolation */
x1 = tab[q>>3];
x2 = tab[(q>>3) + 1];
return sgn * 16 * (MUL_R(errcorr[q&7],(x2-x1)) + x1);
#else
*error = 17;
return 0;
#endif
#else
if (q < 0)
{
/* tab contains a value for all possible q [0,8192] */
if (-q < IQ_TABLE_SIZE)
return -tab[-q];
*error = 17;
return 0;
} else {
/* tab contains a value for all possible q [0,8192] */
if (q < IQ_TABLE_SIZE)
return tab[q];
*error = 17;
return 0;
}
#endif
}
#ifndef FIXED_POINT
ALIGN static const real_t pow2sf_tab[] = {
2.9802322387695313E-008, 5.9604644775390625E-008, 1.1920928955078125E-007,
2.384185791015625E-007, 4.76837158203125E-007, 9.5367431640625E-007,
1.9073486328125E-006, 3.814697265625E-006, 7.62939453125E-006,
1.52587890625E-005, 3.0517578125E-005, 6.103515625E-005,
0.0001220703125, 0.000244140625, 0.00048828125,
0.0009765625, 0.001953125, 0.00390625,
0.0078125, 0.015625, 0.03125,
0.0625, 0.125, 0.25,
0.5, 1.0, 2.0,
4.0, 8.0, 16.0, 32.0,
64.0, 128.0, 256.0,
512.0, 1024.0, 2048.0,
4096.0, 8192.0, 16384.0,
32768.0, 65536.0, 131072.0,
262144.0, 524288.0, 1048576.0,
2097152.0, 4194304.0, 8388608.0,
16777216.0, 33554432.0, 67108864.0,
134217728.0, 268435456.0, 536870912.0,
1073741824.0, 2147483648.0, 4294967296.0,
8589934592.0, 17179869184.0, 34359738368.0,
68719476736.0, 137438953472.0, 274877906944.0
};
#endif
/* quant_to_spec: perform dequantisation and scaling
* and in case of short block it also does the deinterleaving
*/
/*
For ONLY_LONG_SEQUENCE windows (num_window_groups = 1,
window_group_length[0] = 1) the spectral data is in ascending spectral
order.
For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the
grouping in the following manner:
- Groups are ordered sequentially
- Within a group, a scalefactor band consists of the spectral data of all
grouped SHORT_WINDOWs for the associated scalefactor window band. To
clarify via example, the length of a group is in the range of one to eight
SHORT_WINDOWs.
- If there are eight groups each with length one (num_window_groups = 8,
window_group_length[0..7] = 1), the result is a sequence of eight spectra,
each in ascending spectral order.
- If there is only one group with length eight (num_window_groups = 1,
window_group_length[0] = 8), the result is that spectral data of all eight
SHORT_WINDOWs is interleaved by scalefactor window bands.
- Within a scalefactor window band, the coefficients are in ascending
spectral order.
*/
static uint8_t quant_to_spec(NeAACDecHandle hDecoder,
ic_stream *ics, int16_t *quant_data,
uint16_t frame_len)
{
ALIGN static const real_t pow2_table[] =
{
COEF_CONST(1.0),
COEF_CONST(1.1892071150027210667174999705605), /* 2^0.25 */
COEF_CONST(1.4142135623730950488016887242097), /* 2^0.5 */
COEF_CONST(1.6817928305074290860622509524664) /* 2^0.75 */
};
const real_t *tab = iq_table;
real_t *spec_data = ics->buffer;
uint8_t sfb, win;
uint16_t width, bin, k, gindex, wa, wb;
uint8_t error = 0; /* Init error flag */
#ifndef FIXED_POINT
real_t scf;
#endif
ic_group *g;
k = 0;
gindex = 0;
for (g = ics->group; g != ics->group_end; g++)
{
uint16_t j = 0;
uint16_t gincrease = 0;
uint16_t win_inc = ics->swb_offset[ics->num_swb];
for (sfb = 0; sfb < ics->num_swb; sfb++)
{
int32_t exp, frac;
width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb];
/* this could be scalefactor for IS or PNS, those can be negative or bigger then 255 */
/* just ignore them */
if (g->sfb[sfb].scale_factors < 0 || g->sfb[sfb].scale_factors > 255)
{
exp = 0;
frac = 0;
} else {
/* ics->scale_factors[g][sfb] must be between 0 and 255 */
exp = (g->sfb[sfb].scale_factors /* - 100 */) >> 2;
/* frac must always be > 0 */
frac = (g->sfb[sfb].scale_factors /* - 100 */) & 3;
}
#ifdef FIXED_POINT
exp -= 25;
/* IMDCT pre-scaling */
if (hDecoder->object_type == LD)
{
exp -= 6 /*9*/;
} else {
if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
exp -= 4 /*7*/;
else
exp -= 7 /*10*/;
}
#endif
wa = gindex + j;
#ifndef FIXED_POINT
scf = pow2sf_tab[exp/*+25*/] * pow2_table[frac];
#endif
for (win = 0; win < g->window_group_length; win++)
{
for (bin = 0; bin < width; bin += 4)
{
#ifndef FIXED_POINT
wb = wa + bin;
spec_data[wb+0] = iquant(quant_data[k+0], tab, &error) * scf;
spec_data[wb+1] = iquant(quant_data[k+1], tab, &error) * scf;
spec_data[wb+2] = iquant(quant_data[k+2], tab, &error) * scf;
spec_data[wb+3] = iquant(quant_data[k+3], tab, &error) * scf;
#else
real_t iq0 = iquant(quant_data[k+0], tab, &error);
real_t iq1 = iquant(quant_data[k+1], tab, &error);
real_t iq2 = iquant(quant_data[k+2], tab, &error);
real_t iq3 = iquant(quant_data[k+3], tab, &error);
wb = wa + bin;
if (exp < 0)
{
spec_data[wb+0] = iq0 >>= -exp;
spec_data[wb+1] = iq1 >>= -exp;
spec_data[wb+2] = iq2 >>= -exp;
spec_data[wb+3] = iq3 >>= -exp;
} else {
spec_data[wb+0] = iq0 <<= exp;
spec_data[wb+1] = iq1 <<= exp;
spec_data[wb+2] = iq2 <<= exp;
spec_data[wb+3] = iq3 <<= exp;
}
if (frac != 0)
{
spec_data[wb+0] = MUL_C(spec_data[wb+0],pow2_table[frac]);
spec_data[wb+1] = MUL_C(spec_data[wb+1],pow2_table[frac]);
spec_data[wb+2] = MUL_C(spec_data[wb+2],pow2_table[frac]);
spec_data[wb+3] = MUL_C(spec_data[wb+3],pow2_table[frac]);
}
//#define SCFS_PRINT
#ifdef SCFS_PRINT
printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+0]);
printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+1]);
printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+2]);
printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+3]);
//printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+0]);
//printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+1]);
//printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+2]);
//printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+3]);
#endif
#endif
k += 4;
}
wa += win_inc;
}
j += width;
gincrease += width * g->window_group_length;
}
gindex += gincrease;
}
return error;
}
static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
uint8_t output_channels)
{
uint8_t mul = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -