📄 huffdec.c
字号:
/************************* MPEG-2 NBC Audio Decoder ************************** * *"This software module was originally developed byAT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS and edited byYoshiaki Oikawa (Sony Corporation),Mitsuyuki Hatanaka (Sony Corporation)in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,14496-1,2 and 3. This software module is an implementation of a part of one or moreMPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audiostandards free license to this software module or modifications thereof for use inhardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4Audio standards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existing patents.The original developer of this software module and his/her company, the subsequenteditors and their companies, and ISO/IEC have no liability for use of this softwaremodule or modifications thereof in an implementation. Copyright is not released fornon MPEG-2 NBC/MPEG-4 Audio conforming products.The original developerretains full right to use the code for his/her own purpose, assign or donate thecode to a third party and to inhibit third party from using the code for nonMPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice mustbe included in all copies or derivative works."Copyright(c)1996. * * ****************************************************************************//* * $Id$ */#include "all.h"#include "port.h"#include "bits.h"#include "util.h"// wmay - add staticsstatic int extension_payload(faacDecHandle hDecoder, int cnt, byte *data);static int getescape(faacDecHandle hDecoder, int q);static void getgroup(faacDecHandle hDecoder, Info *info, byte *group);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);static int get_ics_info(faacDecHandle hDecoder, byte *win, byte *wshape,byte *group, byte *max_sfb,int *lpflag, int *prstflag,NOK_LT_PRED_STATUS *nok_ltp_status,NOK_LT_PRED_STATUS *nok_ltp_status_right,int stereo_flag);static int getmask(faacDecHandle hDecoder, Info *info, byte *group, byte max_sfb, byte *mask);static void get_sign_bits(faacDecHandle hDecoder, int *q, int n);static int huffcb(faacDecHandle hDecoder, byte *sect, int *sectbits, int tot_sfb, int sfb_per_sbk, byte max_sfb);static int hufffac(faacDecHandle hDecoder, Info *info, byte *group, int nsect, byte *sect, int global_gain, int *factors);static int huffspec(faacDecHandle hDecoder, Info *info, int nsect, byte *sect, int *factors, Float *coef);void getfill(faacDecHandle hDecoder, byte *data){ int cnt; if ((cnt = faad_getbits(&hDecoder->ld, LEN_F_CNT)) == (1<<LEN_F_CNT)-1) cnt += faad_getbits(&hDecoder->ld, LEN_F_ESC) - 1; while (cnt > 0) cnt -= extension_payload(hDecoder, cnt, data);}int getdata(faacDecHandle hDecoder, int *tag, int *dt_cnt, byte *data_bytes){ int i, align_flag, cnt; *tag = faad_getbits(&hDecoder->ld, LEN_TAG); align_flag = faad_getbits(&hDecoder->ld, LEN_D_ALIGN); if ((cnt = faad_getbits(&hDecoder->ld, LEN_D_CNT)) == (1<<LEN_D_CNT)-1) cnt += faad_getbits(&hDecoder->ld, LEN_D_ESC); *dt_cnt = cnt; if (align_flag) faad_byte_align(&hDecoder->ld); for (i=0; i<cnt; i++) data_bytes[i] = faad_getbits(&hDecoder->ld, LEN_BYTE); return 0;}static int extension_payload(faacDecHandle hDecoder, int cnt, byte *data){ int type, i; /* fill bytes should not emulate any EX types below! */ type = faad_getbits(&hDecoder->ld, LEN_EX_TYPE); switch(type) { case EX_FILL_DATA: faad_getbits(&hDecoder->ld, LEN_NIBBLE); for (i=0; i<cnt-1; i++) data[i] = faad_getbits(&hDecoder->ld, LEN_BYTE); return cnt; default: faad_getbits(&hDecoder->ld, LEN_NIBBLE); for (i=0; i<cnt-1; i++) faad_getbits(&hDecoder->ld, LEN_BYTE); return cnt; }}/* * 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;}static int get_ics_info(faacDecHandle hDecoder, byte *win, byte *wshape, byte *group, byte *max_sfb, int *lpflag, int *prstflag, NOK_LT_PRED_STATUS *nok_ltp_status, NOK_LT_PRED_STATUS *nok_ltp_status_right, int stereo_flag){ Info *info; int i, j; int max_pred_sfb = pred_max_bands(hDecoder); faad_get1bit(&hDecoder->ld); /* reserved bit */ *win = (unsigned char)faad_getbits(&hDecoder->ld, LEN_WIN_SEQ); *wshape = (unsigned char)faad_get1bit(&hDecoder->ld); /* window shape */ if ((info = hDecoder->winmap[*win]) == NULL) /* CommonExit(1, "bad window code"); */ return 0; /* * max scale factor, scale factor grouping and prediction flags */ prstflag[0] = 0; if (info->islong) { *max_sfb = (unsigned char)faad_getbits(&hDecoder->ld, LEN_MAX_SFBL); group[0] = 1; if (hDecoder->mc_info.object_type != AACLTP) { if ((lpflag[0] = faad_getbits(&hDecoder->ld, LEN_PRED_PRES))) { if ((prstflag[0] = faad_getbits(&hDecoder->ld, LEN_PRED_RST))) { for(i=1; i<LEN_PRED_RSTGRP+1; i++) prstflag[i] = faad_getbits(&hDecoder->ld, LEN_PRED_RST); } j = ( (*max_sfb < max_pred_sfb) ? *max_sfb : max_pred_sfb ) + 1; for (i = 1; i < j; i++) lpflag[i] = faad_getbits(&hDecoder->ld, LEN_PRED_ENAB); for ( ; i < max_pred_sfb+1; i++) lpflag[i] = 0; } } else { /* AAC LTP */ if(faad_get1bit(&hDecoder->ld)) { nok_lt_decode(hDecoder, *max_sfb, nok_ltp_status->sbk_prediction_used, nok_ltp_status->sfb_prediction_used, &nok_ltp_status->weight, nok_ltp_status->delay); if(stereo_flag) nok_lt_decode(hDecoder, *max_sfb, nok_ltp_status_right->sbk_prediction_used, nok_ltp_status_right->sfb_prediction_used, &nok_ltp_status_right->weight, nok_ltp_status_right->delay); } else { nok_ltp_status->sbk_prediction_used[0] = 0; if(stereo_flag) nok_ltp_status_right->sbk_prediction_used[0] = 0; } } } else { *max_sfb = (unsigned char)faad_getbits(&hDecoder->ld, LEN_MAX_SFBS); getgroup(hDecoder, info, group); lpflag[0] = 0; nok_ltp_status->sbk_prediction_used[0] = 0; if(stereo_flag) nok_ltp_status_right->sbk_prediction_used[0] = 0; } return 1;}static void deinterleave(int inptr[], int outptr[], int ngroups, int nsubgroups[], int ncells[], int cellsize[]){ int i, j, k, l; int *start_inptr, *start_subgroup_ptr, *subgroup_ptr; int cell_inc, subgroup_inc; start_subgroup_ptr = outptr; for (i = 0; i < ngroups; i++) { cell_inc = 0; start_inptr = inptr; /* Compute the increment size for the subgroup pointer */ subgroup_inc = 0; for (j = 0; j < ncells[i]; j++) { subgroup_inc += cellsize[j]; } /* Perform the deinterleaving across all subgroups in a group */ for (j = 0; j < ncells[i]; j++) { subgroup_ptr = start_subgroup_ptr; for (k = 0; k < nsubgroups[i]; k++) { outptr = subgroup_ptr + cell_inc; for (l = 0; l < cellsize[j]; l++) { *outptr++ = *inptr++; } subgroup_ptr += subgroup_inc; } cell_inc += cellsize[j]; } start_subgroup_ptr += (inptr - start_inptr); }}static void calc_gsfb_table(Info *info, byte *group){ int group_offset; int group_idx; int offset; int *group_offset_p; int sfb,len; /* first calc the group length*/ if (info->islong){ return; } else { group_offset = 0; group_idx =0; do { info->group_len[group_idx] = group[group_idx]-group_offset; group_offset=group[group_idx]; group_idx++; } while (group_offset<8); info->num_groups=group_idx; group_offset_p = info->bk_sfb_top; offset=0; for (group_idx=0;group_idx<info->num_groups;group_idx++){ len = info->group_len[group_idx]; for (sfb=0;sfb<info->sfb_per_sbk[group_idx];sfb++){ offset += info->sfb_width_128[sfb] * len; *group_offset_p++ = offset; } } }}static void getgroup(faacDecHandle hDecoder, Info *info, byte *group){ int i, j, first_short; first_short=1; for (i = 0; i < info->nsbk; i++) { if (info->bins_per_sbk[i] > SN2) { /* non-short windows are always their own group */ *group++ = i+1; } else { /* only short-window sequences are grouped! */ if (first_short) { /* first short window is always a new group */ first_short=0; } else { if((j = faad_get1bit(&hDecoder->ld)) == 0) { *group++ = i; } } } } *group = i;}/* * read a synthesis mask * uses EXTENDED_MS_MASK * and grouped mask */static int getmask(faacDecHandle hDecoder, Info *info, byte *group, byte max_sfb, byte *mask){ int b, i, mp; mp = faad_getbits(&hDecoder->ld, LEN_MASK_PRES); /* special EXTENDED_MS_MASK cases */ if(mp == 0) { /* no ms at all */ return 0; } if(mp == 2) {/* MS for whole spectrum on, mask bits set to 1 */ for(b = 0; b < info->nsbk; b = *group++) for(i = 0; i < info->sfb_per_sbk[b]; i ++) *mask++ = 1; return 2; } /* otherwise get mask */ for(b = 0; b < info->nsbk; b = *group++){ for(i = 0; i < max_sfb; i ++) { *mask = (byte)faad_get1bit(&hDecoder->ld); mask++; } for( ; i < info->sfb_per_sbk[b]; i++){ *mask = 0; mask++; } } return 1;}static void clr_tns( Info *info, TNS_frame_info *tns_frame_info ){ int s; tns_frame_info->n_subblocks = info->nsbk; for (s=0; s<tns_frame_info->n_subblocks; s++) tns_frame_info->info[s].n_filt = 0;}static int get_tns(faacDecHandle hDecoder, Info *info, TNS_frame_info *tns_frame_info){ int f, t, top, res, res2, compress; int short_flag, s; int *sp, tmp, s_mask, n_mask; TNSfilt *tns_filt; TNSinfo *tns_info; static int sgn_mask[] = { 0x2, 0x4, 0x8 }; static int neg_mask[] = { 0xfffc, 0xfff8, 0xfff0 }; short_flag = (!info->islong); tns_frame_info->n_subblocks = info->nsbk; for (s=0; s<tns_frame_info->n_subblocks; s++) { tns_info = &tns_frame_info->info[s]; if (!(tns_info->n_filt = faad_getbits(&hDecoder->ld, short_flag ? 1 : 2))) continue; tns_info -> coef_res = res = faad_get1bit(&hDecoder->ld) + 3; top = info->sfb_per_sbk[s]; tns_filt = &tns_info->filt[ 0 ]; for (f=tns_info->n_filt; f>0; f--) { tns_filt->stop_band = top; top = tns_filt->start_band = top - faad_getbits(&hDecoder->ld, short_flag ? 4 : 6); tns_filt->order = faad_getbits(&hDecoder->ld, short_flag ? 3 : 5); if (tns_filt->order) { tns_filt->direction = faad_get1bit(&hDecoder->ld); compress = faad_get1bit(&hDecoder->ld); res2 = res - compress; s_mask = sgn_mask[ res2 - 2 ]; n_mask = neg_mask[ res2 - 2 ]; sp = tns_filt->coef; for (t=tns_filt->order; t>0; t--) { tmp = (short)faad_getbits(&hDecoder->ld, res2); *sp++ = (tmp & s_mask) ? (short)(tmp | n_mask) : (short)tmp; } } tns_filt++; } } /* subblock loop */ return 1;}static void get_pulse_nc(faacDecHandle hDecoder, struct Pulse_Info *pulse_info){ int i; pulse_info->number_pulse = faad_getbits(&hDecoder->ld, LEN_NPULSE); pulse_info->pulse_start_sfb = faad_getbits(&hDecoder->ld, LEN_PULSE_ST_SFB); for(i = 0; i < pulse_info->number_pulse + 1; i++) { pulse_info->pulse_offset[i] = faad_getbits(&hDecoder->ld, LEN_POFF); pulse_info->pulse_amp[i] = faad_getbits(&hDecoder->ld, LEN_PAMP); }}static void pulse_nc(faacDecHandle hDecoder, int *coef, struct Pulse_Info *pulse_info){ int i, k; k = hDecoder->only_long_info.sbk_sfb_top[0][pulse_info->pulse_start_sfb]; for(i = 0; i <= pulse_info->number_pulse; i++) { k += pulse_info->pulse_offset[i]; if (coef[k]>0) coef[k] += pulse_info->pulse_amp[i]; else coef[k] -= pulse_info->pulse_amp[i]; }}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) ];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -