static int getics(faacDecHandle hDecoder, Info *info, int common_window, byte *win, byte *wshape, byte *group, byte *max_sfb, int *lpflag, int *prstflag, byte *cb_map, Float *coef, int *global_gain, int *factors, NOK_LT_PRED_STATUS *nok_ltp_status, TNS_frame_info *tns) { int nsect, i, cb, top, bot, tot_sfb; 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); }
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int huffdecode( Int id_syn_ele, BITS *pInputStream, tDec_Int_File *pVars, tDec_Int_Chan *pChVars[]) { /*---------------------------------------------------------------------------- ; Define all local variables ----------------------------------------------------------------------------*/ Int ch; Int common_window; Int hasmask; Int status = SUCCESS; Int num_channels = 0; MC_Info *pMcInfo; per_chan_share_w_fxpCoef *pChLeftShare; /* Helper pointer */ per_chan_share_w_fxpCoef *pChRightShare; /* Helper pointer */ /*---------------------------------------------------------------------------- ; Function body here ----------------------------------------------------------------------------*/ get9_n_lessbits( LEN_TAG, pInputStream); /* suppose an un-supported id_syn_ele will never be passed */ common_window = 0; if (id_syn_ele == ID_CPE) { common_window = get1bits(pInputStream); } pMcInfo = &pVars->mc_info; /* * check if provided info (num of channels) on audio config, * matches read bitstream data, if not, allow update only once. * In almost all cases it should match. */ #if 0 if ((pMcInfo->ch_info[0].cpe != id_syn_ele)) { if (pVars->mc_info.implicit_channeling) /* check done only once */ { pMcInfo->ch_info[0].cpe = id_syn_ele & 1; /* collect info from bitstream * implicit_channeling flag is locked * after 1st frame, to avoid toggling * parameter in the middle of the clip */ pMcInfo->nch = (id_syn_ele & 1) + 1; /* update number of channels */ } else { status = 1; /* ERROR break if syntax error persist */ } } #endif if (status == SUCCESS) { if (id_syn_ele == ID_SCE) { num_channels = 1; pVars->hasmask = 0; } else if (id_syn_ele == ID_CPE) { pChLeftShare = pChVars[LEFT]->pShareWfxpCoef; pChRightShare = pChVars[RIGHT]->pShareWfxpCoef; num_channels = 2; if (common_window != FALSE) { status = get_ics_info( (tMP4AudioObjectType) pVars->mc_info.audioObjectType, pInputStream, (Bool)common_window, (WINDOW_SEQUENCE *) & pChVars[LEFT]->wnd, (WINDOW_SHAPE *) & pChVars[LEFT]->wnd_shape_this_bk, pChLeftShare->group, (Int *) & pChLeftShare->max_sfb, pVars->winmap, (LT_PRED_STATUS *) & pChLeftShare->lt_status, (LT_PRED_STATUS *) & pChRightShare->lt_status); if (status == SUCCESS) { /* copy left channel info to right channel */ pChVars[RIGHT]->wnd = pChVars[LEFT]->wnd; pChVars[RIGHT]->wnd_shape_this_bk = pChVars[LEFT]->wnd_shape_this_bk; pChRightShare->max_sfb = pChLeftShare->max_sfb; pv_memcpy( pChRightShare->group, pChLeftShare->group, NSHORT*sizeof(pChLeftShare->group[0])); hasmask = getmask( pVars->winmap[pChVars[LEFT]->wnd], pInputStream, pChLeftShare->group, pChLeftShare->max_sfb, pVars->mask); if (hasmask == MASK_ERROR) { status = 1; /* ERROR code */ } pVars->hasmask = hasmask; } /* if (status == 0) */ } else { pVars->hasmask = 0; } /* if (common_window) */ } /* if (id_syn_ele) */ else if (id_syn_ele == ID_LFE) { num_channels = 1; pVars->hasmask = 0; } /* if (id_syn_ele) == ID_LFE */ } /* if (status) */ ch = 0; while ((ch < num_channels) && (status == SUCCESS)) { pChLeftShare = pChVars[ch]->pShareWfxpCoef; status = getics( pInputStream, common_window, pVars, pChVars[ch], pChLeftShare->group, &pChLeftShare->max_sfb, pChLeftShare->cb_map, &pChLeftShare->tns, pVars->winmap, &pVars->share.a.pulseInfo, pVars->share.a.sect); ch++; } /* while (ch) */ /*---------------------------------------------------------------------------- ; Return status ----------------------------------------------------------------------------*/ return status; } /* huffdecode */
/* * read and decode the data for the next 1024 output samples * return -1 if there was an error */ int huffdecode(faacDecHandle hDecoder, int id, MC_Info *mip, byte *win, Wnd_Shape *wshape, byte **cb_map, int **factors, byte **group, byte *hasmask, byte **mask, byte *max_sfb, int **lpflag, int **prstflag, NOK_LT_PRED_STATUS **nok_ltp_status, TNS_frame_info **tns, Float **coef) { int i, tag, common_window, ch, widx, first=0, last=0; int global_gain; /* not used in this routine */ Info info; tag = faad_getbits(&hDecoder->ld, LEN_TAG); switch(id) { case ID_SCE: common_window = 0; break; case ID_CPE: common_window = faad_get1bit(&hDecoder->ld); /* common_window */ break; default: /* CommonWarning("Unknown id"); */ return(-1); } if ((ch = chn_config(hDecoder, id, tag, common_window, mip)) < 0) return -1; switch(id) { case ID_SCE: widx = mip->ch_info[ch].widx; first = ch; last = ch; hasmask[widx] = 0; break; case ID_CPE: first = ch; last = mip->ch_info[ch].paired_ch; if (common_window) { widx = mip->ch_info[ch].widx; if (!get_ics_info(hDecoder, &win[widx], &wshape[widx].this_bk, group[widx], &max_sfb[widx], lpflag[widx], prstflag[widx], nok_ltp_status[widx],nok_ltp_status[mip->ch_info[ch].paired_ch], common_window)) return -1; hasmask[widx] = getmask(hDecoder, hDecoder->winmap[win[widx]], group[widx], max_sfb[widx], mask[widx]); } else { hasmask[mip->ch_info[first].widx] = 0; hasmask[mip->ch_info[last].widx] = 0; } break; } for (i=first; i<=last; i++) { widx = mip->ch_info[i].widx; SetMemory(coef[i], 0, LN2*sizeof(Float)); if(!getics(hDecoder, &info, common_window, &win[widx], &wshape[widx].this_bk, group[widx], &max_sfb[widx], lpflag[widx], prstflag[widx], cb_map[i], coef[i], &global_gain, factors[i], nok_ltp_status[widx], tns[i])) return -1; } return 0; }
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int getics( Int id_syn_ele, BITS *pInputStream, Int common_window, tDec_Int_File *pVars, tDec_Int_Chan *pChVars, Int group[], Int *pMax_sfb, Int *pCodebookMap, TNS_frame_info *pTnsFrameInfo, FrameInfo **pWinMap, PulseInfo *pPulseInfo, SectInfo sect[]) { /*---------------------------------------------------------------------------- ; Define all local variables ----------------------------------------------------------------------------*/ Int status = SUCCESS; Int nsect = 0; Int i; Int cb; Int sectWidth; Int sectStart; Int totSfb; Int *pGroup; FrameInfo *pFrameInfo; Int global_gain; /* originally passed in from huffdecode */ Bool present; /*---------------------------------------------------------------------------- ; Function body here ----------------------------------------------------------------------------*/ pGroup = group; /* read global gain from Input bitstream */ global_gain = get9_n_lessbits(LEN_SCL_PCM, pInputStream); if (common_window == FALSE) { status = get_ics_info(pVars->mc_info.audioObjectType, pInputStream, common_window, &pChVars->wnd, &pChVars->wnd_shape_this_bk, group, pMax_sfb, pWinMap, &pChVars->pShareWfxpCoef->lt_status, NULL); } pFrameInfo = pWinMap[pChVars->wnd]; /* at least, number of window should be 1 or 8 */ if ((pFrameInfo->num_win != 1) && (pFrameInfo->num_win != 8)) { status = 1; } /* First, calculate total number of scalefactor bands * for this grouping. Then, decode section data */ if (*pMax_sfb > 0) { /* calculate total number of sfb */ i = 0; totSfb = 0; do { totSfb++; } while (*pGroup++ < pFrameInfo->num_win); totSfb *= pFrameInfo->sfb_per_win[0]; /* decode section data */ nsect = huffcb(sect, pInputStream, pFrameInfo->sectbits, totSfb, pFrameInfo->sfb_per_win[0], *pMax_sfb); if (nsect == 0) { status = 1; /* decode section data error */ }/* if (nsect) */ /* generate "linear" description from section info * stored as codebook for each scalefactor band and group * when nsect == 0, for-loop does not execute */ sectStart = 0; for (i = 0; i < nsect; i++) { cb = sect[i].sect_cb; sectWidth = sect[i].sect_end - sectStart; sectStart += sectWidth; while (sectWidth > 0) { *pCodebookMap++ = cb; /* cannot use memset for Int */ sectWidth--; } } /* for (i) */ } else { /* set all sections with ZERO_HCB */ pv_memset(pCodebookMap, ZERO_HCB, MAXBANDS*sizeof(*pCodebookMap)); /* for (i=MAXBANDS; i>0; i--) { *(pCodebookMap++) = ZERO_HCB; } */ } /* if (*pMax_sfb) */ /* calculate band offsets * (because of grouping and interleaving this cannot be * a constant: store it in pFrameInfo->frame_sfb_top) */ if (pFrameInfo->islong == FALSE) { calc_gsfb_table(pFrameInfo, group); } /* decode scale factor data */ if (status == SUCCESS) { status = hufffac(pFrameInfo, pInputStream, group, nsect, sect, global_gain, pChVars->pShareWfxpCoef->factors, pVars->scratch.a.huffbook_used); } /* if (status) */ /* noiseless coding */ if (status == SUCCESS) { present = get1bits(pInputStream); pPulseInfo->pulse_data_present = present; if (present != FALSE) { if (pFrameInfo->islong == 1) { status = get_pulse_data(pPulseInfo, pInputStream); } else { /* CommonExit(1,"Pulse data not allowed for short blocks"); */ status = 1; } /* if (pFrameInfo) */ } /* if (present) */ } /* if (status) */ /* decode tns data */ if (status == SUCCESS) { present = get1bits(pInputStream); pTnsFrameInfo->tns_data_present = present; if (present != FALSE) { get_tns(pChVars->pShareWfxpCoef->max_sfb, pInputStream, pChVars->wnd, pFrameInfo, &pVars->mc_info, pTnsFrameInfo, pVars->scratch.a.tns_decode_coef); } else { for (i = pFrameInfo->num_win - 1; i >= 0 ; i--) { pTnsFrameInfo->n_filt[i] = 0; } } /* if(present) */ } /* if (status) */ /* gain control */ if (status == SUCCESS) { present = get1bits(pInputStream); if (present != FALSE) { /* CommonExit(1, "Gain control not implemented"); */ status = 1; } } /* if (status) */ if (status == SUCCESS) { /* Support Mono, Dual-Mono, or Stereo */ if ((id_syn_ele == ID_SCE) || (id_syn_ele == ID_CPE)) { status = huffspec_fxp(pFrameInfo, pInputStream, nsect, sect, pChVars->pShareWfxpCoef->factors, pChVars->fxpCoef, pVars->share.a.quantSpec, pVars->scratch.tmp_spec, pWinMap[ONLY_LONG_WINDOW], pPulseInfo, pChVars->pShareWfxpCoef->qFormat); } } /*---------------------------------------------------------------------------- ; Return status ----------------------------------------------------------------------------*/ return status; } /* getics */