📄 aac_back_pred.c
字号:
/********************************************************************* * * aac_back_pred.c - AAC 后向预测程序 * ***********************************************************************//**********************************************************************INPUT:" act_spec[]表示当前帧要编码的频谱成分;
" last_spec[]表示前一帧的量化频谱误差;
" btype为当前帧的窗口类型;
" ]nsfb为比例因子频带的数目;
" isfb_width[]为比例因子带宽。
OUTPUT:" act_spec[]为当前要编码帧的频谱误差;
" pred_global_flag为全局预测使能/禁止标志;
" pred_sbf_glag[]为每个比例因子通带的使能和禁止标志;
" reset_group为其余组的数目,如果为-1则表示没有其余的组。
***********************************************************************/#include "aac_back_pred.h"static int psy_init_mc[MAX_TIME_CHANNELS];static float dr_mc[MAX_TIME_CHANNELS][LPC][FLEN_LONG/2],e_mc[MAX_TIME_CHANNELS][LPC+1+1][FLEN_LONG/2];static float K_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2], R_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2];static float VAR_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2], KOR_mc[MAX_TIME_CHANNELS][LPC+1][FLEN_LONG/2];static float sb_samples_pred_mc[MAX_TIME_CHANNELS][FLEN_LONG/2];static int thisLineNeedsResetting_mc[MAX_TIME_CHANNELS][FLEN_LONG/2];static int reset_count_mc[MAX_TIME_CHANNELS];void PredInit() { int i; for (i=0;i<MAX_TIME_CHANNELS;i++) { psy_init_mc[i] = 0; reset_count_mc[i] = 0; }} void PredCalcPrediction( double *act_spec, double *last_spec, int btype, int nsfb, int *isfb_width, short *pred_global_flag, int *pred_sfb_flag, int *reset_group , int chanNum) { int i, k, j, cb_long; float num_bit, snr[SBMAX_L]; float energy[FLEN_LONG/2], snr_p[FLEN_LONG/2], temp1, temp2; /* 为指定的信道设定指针*/
int *psy_init; float (*dr)[FLEN_LONG/2],(*e)[FLEN_LONG/2]; float (*K)[FLEN_LONG/2], (*R)[FLEN_LONG/2]; float (*VAR)[FLEN_LONG/2], (*KOR)[FLEN_LONG/2]; float *sb_samples_pred; int *thisLineNeedsResetting; /* int reset_count; */ int *reset_count; /* psy_init = psy_init_mc[chanNum]; */ psy_init = &psy_init_mc[chanNum]; dr = &dr_mc[chanNum][0]; e = &e_mc[chanNum][0]; K = &K_mc[chanNum][0]; R = &R_mc[chanNum][0]; VAR = &VAR_mc[chanNum][0]; KOR = &KOR_mc[chanNum][0]; sb_samples_pred = &sb_samples_pred_mc[chanNum][0]; thisLineNeedsResetting = &thisLineNeedsResetting_mc[chanNum][0]; reset_count = &reset_count_mc[chanNum]; *psy_init = (*psy_init && (btype!=2)); if((*psy_init) == 0) { for (j=0; j<FLEN_LONG/2; j++) { thisLineNeedsResetting[j]=1; } *psy_init = 1; } if (btype==2) { pred_global_flag[0]=0; *reset_count = ((*reset_count) / RESET_FRAME) * RESET_FRAME; return; } /**************************************************/ /* 计算使用last_spec 的状态 */ /**************************************************/ for (i=0;i<FLEN_LONG/2;i++) { /* e[0][i]=last_spec[i]; */ e[0][i]=last_spec[i]+sb_samples_pred[i]; for(j=1;j<=LPC;j++) e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i]; for(j=1;j<LPC;j++) dr[j][i] = K[j][i]*e[j-1][i]; for(j=1;j<=LPC;j++) { VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]); KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i]; } for(j=LPC-1;j>=1;j--) R[j][i] = A*(R[j-1][i]-dr[j][i]); R[0][i] = A*e[0][i]; } /**************************************************/ /* 在这里重置状态*/ /**************************************************/ for (i=0;i<FLEN_LONG/2;i++) { if (thisLineNeedsResetting[i]) { for (j = 0; j <= LPC; j++) { K[j][i] = 0.0; dr[j][i] = 0.0; e[j][i] = 0.0; R[j][i] = 0.0; VAR[j][i] = 1.0; KOR[j][i] = 0.0; } } } /**************************************************/ /* 计算预测器系数和预测数据*/ /**************************************************/ for (i=0;i<FLEN_LONG/2;i++) { for(j=1;j<=LPC;j++) { if(VAR[j][i]>MINVAR) K[j][i] = KOR[j][i]/VAR[j][i]*B; else K[j][i] = 0; } } for (k=0; k<FLEN_LONG/2; k++) { sb_samples_pred[k]=0.0; for (i=1; i<=LPC; i++) sb_samples_pred[k]+=K[i][k]*R[i-1][k]; } /**************************************************/ /* 判断是否使能或禁止预测*/ /**************************************************/ for (k=0; k<FLEN_LONG/2; k++) {energy[k]=act_spec[k]*act_spec[k]; snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]); } cb_long=0; for (i=0; i<nsfb; i++) { pred_sfb_flag[i]=1; temp1=0.0; temp2=0.0; for (j=cb_long; j<cb_long+isfb_width[i]; j++) {temp1+=energy[j]; temp2+=snr_p[j];} if(temp2<1.e-20) temp2=1.e-20; if(temp1!=0.0) {snr[i]=-10.*log10((double ) temp2/temp1);} else snr[i]=0.0; if(snr[i]<=0.0) {pred_sfb_flag[i]=0; for (j=cb_long; j<cb_long+isfb_width[i]; j++) sb_samples_pred[j]=0.0; } cb_long+=isfb_width[i]; } /* Disable prediction for bands nsfb through SBMAX_L */ for (i=j;i<FLEN_LONG/2;i++) { sb_samples_pred[i]=0.0; } for (i=nsfb;i<SBMAX_L;i++) { pred_sfb_flag[i]=0; } num_bit=0.0; for (i=0; i<nsfb; i++) if(snr[i]>0.0) num_bit+=snr[i]/6.*isfb_width[i]; pred_global_flag[0]=1; if(num_bit<100 /*50*/) { pred_global_flag[0]=0; num_bit=0.0; for (j=0; j<FLEN_LONG/2; j++) sb_samples_pred[j]=0.0; } for (j=0; j<FLEN_LONG/2; j++) act_spec[j]-=sb_samples_pred[j]; (*reset_count)++; /* Reset the frame counter */ for (i=0;i<FLEN_LONG/2;i++) { thisLineNeedsResetting[i]=0; } if (*reset_count >= 31 * RESET_FRAME) *reset_count = RESET_FRAME; if (*reset_count % RESET_FRAME == 0) { /* Send a reset in this frame */ *reset_group = *reset_count / 8; for (i = *reset_group - 1; i < FLEN_LONG / 2; i += 30) { thisLineNeedsResetting[i]=1; } } else *reset_group = -1; /* Ensure that prediction data is sent when there is a prediction * reset. */ if (*reset_group != -1 && pred_global_flag[0] == 0) { pred_global_flag[0] = 1; for (i = 0; i < nsfb; i++) pred_sfb_flag[i] = 0; } /* End of code segment */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -