📄 huffdec.c
字号:
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 + -