📄 huffdec.c
字号:
byte sect[ 2*(MAXBANDS+1) ];
memset(sect, 0, sizeof(sect));
/*
* global gain
*/
*global_gain = (short)faad_getbits(&hDecoder->ld, LEN_SCL_PCM);
if (!common_window) {
if (!get_ics_info(hDecoder, win, wshape, group, max_sfb, lpflag, prstflag,
nok_ltp_status, NULL, 0))
return 0;
}
CopyMemory(info, hDecoder->winmap[*win], sizeof(Info));
/* calculate total number of sfb for this grouping */
if (*max_sfb == 0) {
tot_sfb = 0;
}
else {
i=0;
tot_sfb = info->sfb_per_sbk[0];
while (group[i++] < info->nsbk) {
tot_sfb += info->sfb_per_sbk[0];
}
}
/*
* section data
*/
nsect = huffcb(hDecoder, sect, info->sectbits, tot_sfb, info->sfb_per_sbk[0], *max_sfb);
if(nsect==0 && *max_sfb>0)
return 0;
/* generate "linear" description from section info
* stored as codebook for each scalefactor band and group
*/
if (nsect) {
bot = 0;
for (i=0; i<nsect; i++) {
cb = sect[2*i];
top = sect[2*i + 1];
for (; bot<top; bot++)
*cb_map++ = cb;
bot = top;
}
} else {
for (i=0; i<MAXBANDS; i++)
cb_map[i] = 0;
}
/* calculate band offsets
* (because of grouping and interleaving this cannot be
* a constant: store it in info.bk_sfb_top)
*/
calc_gsfb_table(info, group);
/*
* scale factor data
*/
if(!hufffac(hDecoder, info, group, nsect, sect, *global_gain, factors))
return 0;
/*
* Pulse coding
*/
if ((hDecoder->pulse_info.pulse_data_present = faad_get1bit(&hDecoder->ld))) { /* pulse data present */
if (info->islong) {
get_pulse_nc(hDecoder, &hDecoder->pulse_info);
} else {
/* CommonExit(1,"Pulse data not allowed for short blocks"); */
return 0;
}
}
/*
* tns data
*/
if (faad_get1bit(&hDecoder->ld)) { /* tns present */
get_tns(hDecoder, info, tns);
}
else {
clr_tns(info, tns);
}
if (faad_get1bit(&hDecoder->ld)) { /* gain control present */
/* CommonExit(1, "Gain control not implemented"); */
return 0;
}
return huffspec(hDecoder, info, nsect, sect, factors, coef);
}
/*
* read the codebook and boundaries
*/
static int huffcb(faacDecHandle hDecoder, byte *sect, int *sectbits,
int tot_sfb, int sfb_per_sbk, byte max_sfb)
{
int nsect, n, base, bits, len;
bits = sectbits[0];
len = (1 << bits) - 1;
nsect = 0;
for(base = 0; base < tot_sfb && nsect < tot_sfb; ) {
*sect++ = (byte)faad_getbits(&hDecoder->ld, LEN_CB);
n = faad_getbits(&hDecoder->ld, bits);
while(n == len && base < tot_sfb) {
base += len;
n = faad_getbits(&hDecoder->ld, bits);
}
base += n;
*sect++ = base;
nsect++;
/* insert a zero section for regions above max_sfb for each group */
if ((sect[-1] % sfb_per_sbk) == max_sfb) {
base += (sfb_per_sbk - max_sfb);
*sect++ = 0;
*sect++ = base;
nsect++;
}
}
if(base != tot_sfb || nsect > tot_sfb)
return 0;
return nsect;
}
/*
* get scale factors
*/
static int hufffac(faacDecHandle hDecoder, Info *info, byte *group, int nsect, byte *sect,
int global_gain, int *factors)
{
Huffscl *hcw;
int i, b, bb, t, n, sfb, top, fac, is_pos;
int factor_transmitted[MAXBANDS], *fac_trans;
int noise_pcm_flag = 1;
int noise_nrg;
/* clear array for the case of max_sfb == 0 */
SetMemory(factor_transmitted, 0, MAXBANDS*sizeof(int));
SetMemory(factors, 0, MAXBANDS*sizeof(int));
sfb = 0;
fac_trans = factor_transmitted;
for(i = 0; i < nsect; i++){
top = sect[1]; /* top of section in sfb */
t = sect[0]; /* codebook for this section */
sect += 2;
for(; sfb < top; sfb++) {
fac_trans[sfb] = t;
}
}
/* scale factors are dpcm relative to global gain
* intensity positions are dpcm relative to zero
*/
fac = global_gain;
is_pos = 0;
noise_nrg = global_gain - NOISE_OFFSET;
/* get scale factors */
hcw = bookscl;
bb = 0;
for(b = 0; b < info->nsbk; ){
n = info->sfb_per_sbk[b];
b = *group++;
for(i = 0; i < n; i++){
switch (fac_trans[i]) {
case ZERO_HCB: /* zero book */
break;
default: /* spectral books */
/* decode scale factor */
t = decode_huff_cw_scl(hDecoder, hcw);
fac += t - MIDFAC; /* 1.5 dB */
if(fac >= 2*TEXP || fac < 0)
return 0;
factors[i] = fac;
break;
case BOOKSCL: /* invalid books */
return 0;
case INTENSITY_HCB: /* intensity books */
case INTENSITY_HCB2:
/* decode intensity position */
t = decode_huff_cw_scl(hDecoder, hcw);
is_pos += t - MIDFAC;
factors[i] = is_pos;
break;
case NOISE_HCB: /* noise books */
/* decode noise energy */
if (noise_pcm_flag) {
noise_pcm_flag = 0;
t = faad_getbits(&hDecoder->ld, NOISE_PCM_BITS) - NOISE_PCM_OFFSET;
} else
t = decode_huff_cw_scl(hDecoder, hcw) - MIDFAC;
noise_nrg += t;
factors[i] = noise_nrg;
break;
}
}
/* expand short block grouping */
if (!(info->islong)) {
for(bb++; bb < b; bb++) {
for (i=0; i<n; i++) {
factors[i+n] = factors[i];
}
factors += n;
}
}
fac_trans += n;
factors += n;
}
return 1;
}
__inline float esc_iquant(faacDecHandle hDecoder, int q)
{
if (q > 0) {
if (q < MAX_IQ_TBL) {
return((float)hDecoder->iq_exp_tbl[q]);
} else {
return((float)pow(q, 4./3.));
}
} else {
q = -q;
if (q < MAX_IQ_TBL) {
return((float)(-hDecoder->iq_exp_tbl[q]));
} else {
return((float)(-pow(q, 4./3.)));
}
}
}
static int huffspec(faacDecHandle hDecoder, Info *info, int nsect, byte *sect,
int *factors, Float *coef)
{
Hcb *hcb;
Huffman *hcw;
int i, j, k, table, step, stop, bottom, top;
int *bands, *bandp;
int *quant, *qp;
int *tmp_spec;
int *quantPtr;
int *tmp_specPtr;
quant = AllocMemory(LN2*sizeof(int));
tmp_spec = AllocMemory(LN2*sizeof(int));
quantPtr = quant;
tmp_specPtr = tmp_spec;
#ifndef WIN32
SetMemory(quant, 0, LN2*sizeof(int));
#endif
bands = info->bk_sfb_top;
bottom = 0;
k = 0;
bandp = bands;
for(i = nsect; i; i--) {
table = sect[0];
top = sect[1];
sect += 2;
if( (table == 0) || (table == NOISE_HCB) ||
(table == INTENSITY_HCB) || (table == INTENSITY_HCB2) ) {
bandp = bands+top;
k = bandp[-1];
bottom = top;
continue;
}
if(table < BY4BOOKS+1) {
step = 4;
} else {
step = 2;
}
hcb = &book[table];
hcw = hcb->hcw;
qp = quant+k;
for(j = bottom; j < top; j++) {
stop = *bandp++;
while(k < stop) {
decode_huff_cw(hDecoder, hcw, qp, hcb);
if (!hcb->signed_cb)
get_sign_bits(hDecoder, qp, step);
if(table == ESCBOOK){
qp[0] = getescape(hDecoder, qp[0]);
qp[1] = getescape(hDecoder, qp[1]);
}
qp += step;
k += step;
}
}
bottom = top;
}
/* pulse coding reconstruction */
if ((info->islong) && (hDecoder->pulse_info.pulse_data_present))
pulse_nc(hDecoder, quant, &hDecoder->pulse_info);
if (!info->islong) {
deinterleave (quant,tmp_spec,
(short)info->num_groups,
info->group_len,
info->sfb_per_sbk,
info->sfb_width_128);
for (i = LN2/16 - 1; i >= 0; --i)
{
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
*quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++;
}
}
/* inverse quantization */
for (i=0; i<info->bins_per_bk; i++) {
coef[i] = esc_iquant(hDecoder, quant[i]);
}
/* rescaling */
{
int sbk, nsbk, sfb, nsfb, fac, top;
Float *fp, scale;
i = 0;
fp = coef;
nsbk = info->nsbk;
for (sbk=0; sbk<nsbk; sbk++) {
nsfb = info->sfb_per_sbk[sbk];
k=0;
for (sfb=0; sfb<nsfb; sfb++) {
top = info->sbk_sfb_top[sbk][sfb];
fac = factors[i++]-SF_OFFSET;
if (fac >= 0 && fac < TEXP) {
scale = hDecoder->exptable[fac];
}
else {
if (fac == -SF_OFFSET) {
scale = 0;
}
else {
scale = (float)pow(2.0, 0.25*fac);
}
}
for ( ; k<top; k++) {
*fp++ *= scale;
}
}
}
}
if (quant) FreeMemory(quant);
if (tmp_spec) FreeMemory(tmp_spec);
return 1;
}
/*
* initialize the Hcb structure and sort the Huffman
* codewords by length, shortest (most probable) first
*/
void hufftab(Hcb *hcb, Huffman *hcw, int dim, int signed_cb)
{
hcb->dim = dim;
hcb->signed_cb = signed_cb;
hcb->hcw = hcw;
}
__inline void decode_huff_cw(faacDecHandle hDecoder, Huffman *h, int *qp, Hcb *hcb)
{
int i, j;
unsigned long cw;
i = h->len;
cw = faad_getbits_fast(&hDecoder->ld, i);
while (cw != h->cw)
{
h++;
j = h->len-i;
if (j!=0) {
i += j;
while (j--)
cw = (cw<<1)|faad_get1bit(&hDecoder->ld);
}
}
if(hcb->dim == 4)
{
qp[0] = h->x;
qp[1] = h->y;
qp[2] = h->v;
qp[3] = h->w;
} else {
qp[0] = h->x;
qp[1] = h->y;
}
}
__inline int decode_huff_cw_scl(faacDecHandle hDecoder, Huffscl *h)
{
int i, j;
long cw;
i = h->len;
cw = faad_getbits_fast(&hDecoder->ld, i);
while ((unsigned long)cw != h->cw)
{
h++;
j = h->len-i;
if (j!=0) {
i += j;
while (j--)
cw = (cw<<1)|faad_get1bit(&hDecoder->ld);
}
}
return h->scl;
}
/* get sign bits */
static void get_sign_bits(faacDecHandle hDecoder, int *q, int n)
{
int i;
for(i=0; i < n; i++)
{
if(q[i])
{
if(faad_get1bit(&hDecoder->ld) & 1)
{
/* 1 signals negative, as in 2's complement */
q[i] = -q[i];
}
}
}
}
static int getescape(faacDecHandle hDecoder, int q)
{
int i, off, neg;
if(q < 0){
if(q != -16)
return q;
neg = 1;
} else{
if(q != +16)
return q;
neg = 0;
}
for(i=4;; i++){
if(faad_get1bit(&hDecoder->ld) == 0)
break;
}
if(i > 16){
off = faad_getbits(&hDecoder->ld, i-16) << 16;
off |= faad_getbits(&hDecoder->ld, 16);
} else
off = faad_getbits(&hDecoder->ld, i);
i = off + (1<<i);
if(neg)
i = -i;
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -