📄 monopred.c
字号:
/************************* MPEG-2 NBC Audio Decoder ************************** * *"This software module was originally developed by Bernd Edler and Hendrik Fuchs, University of Hannover 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 more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non 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 the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice mustbe included in all copies or derivative works." Copyright(c)1996. * * ****************************************************************************//* Minor modifications by Pierre Lauber, Fraunhofer Institute Erlangen *//*********************************************************************************** * MONOPRED * * * * Contains the core functions for an intra channel (or mono) predictor * * using a backward adaptive lattice predictor. * * * * init_pred_stat(): initialisation of all predictor parameters * * monopred(): calculation of a predicted value from * * preceeding (quantised) samples * * predict(): carry out prediction for all spectral lines * * predict_reset(): carry out cyclic predictor reset mechanism * * (long blocks) resp. full reset (short blocks) * * * * Internal Functions: * * reset_pred_state(): reset the predictor state variables * * * **********************************************************************************/#include <math.h>#include <stdio.h>#include "block.h" /* handler, defines, enums */#include "buffersHandle.h" /* handler, defines, enums */#include "concealmentHandle.h" /* handler, defines, enums */#include "interface.h" /* handler, defines, enums */#include "mod_bufHandle.h" /* handler, defines, enums */#include "monopredHandle.h" /* handler, defines, enums */#include "resilienceHandle.h" /* handler, defines, enums */#include "reorderspecHandle.h" /* handler, defines, enums */#include "tf_mainHandle.h" /* handler, defines, enums */#include "all.h" /* structs */#include "monopredStruct.h" /* structs */#include "nok_ltp_common.h" /* structs */#include "nok_prediction.h" /* structs */#include "tf_mainStruct.h" /* structs */#include "tns.h" /* structs */#include "allVariables.h" /* variables */#include "port.h"#include "common_m4a.h"#define GRAD PRED_ORDERstatic float ALPHA;static float A;static float B;static float mnt_table[128];static float exp_table[256];static int last_rstgrp_num = 0;#ifdef NOT_USEDstatic voidflt_trunc(float *pf){ ulong tmp; float *pt = (float *)&tmp; *pt = *pf; tmp &= (ulong)0xffff0000; *pf = *pt;}#endif/* this works for all float values, * but does not conform to IEEE conventions of * round to nearest, even *//* Schuyler's bug fix */static voidflt_round(float *pf){ int flg; ulong tmp; float *pt = (float *)&tmp; *pt = *pf; flg = tmp & (ulong)0x00008000; tmp &= (ulong)0xffff0000; *pf = *pt; /* round 1/2 lsb toward infinity */ if (flg) { tmp &= (ulong)0xff800000; /* extract exponent and sign */ tmp |= (ulong)0x00010000; /* insert 1 lsb */ *pf += *pt; /* add 1 lsb and elided one */ tmp &= (ulong)0xff800000; /* extract exponent and sign */ *pf -= *pt; /* subtract elided one */ }}/* This only works for 1.0 < float < 2.0 - 2^-24 ! * * Comparison of the performance of the two rounding routines: * old (above) new (below) * Max error 0.00385171 0.00179992 * RMS error 0.00194603 0.00109221 *//* New bug fixed version */static voidinv_table_flt_round(float *ftmp){ int exp; double mnt; float descale; mnt = frexp((double)*ftmp, &exp); descale = (float)ldexp(1.0, exp + 15); *ftmp += descale; *ftmp -= descale;}static voidmake_inv_tables(void){ int i; ulong tmp1, tmp; float *pf = (float *)&tmp; float ftmp; *pf = 1.0; tmp1 = tmp; /* float 1.0 */ for (i=0; i<128; i++) { tmp = tmp1 + (i<<16); /* float 1.m, 7 msb only */ ftmp = B / *pf; inv_table_flt_round(&ftmp); /* round to 16 bits */ mnt_table[i] = ftmp; /* printf("%3d %08x %f\n", i, tmp, ftmp); */ } for (i=0; i<256; i++) { tmp = (i<<23); /* float 1.0 * 2^exp */ if (*pf > MINVAR) { ftmp = 1.0 / *pf; } else { ftmp = 0; } exp_table[i] = ftmp; /* printf("%3d %08x %g\n", i, tmp, ftmp); */ }}/* Bug-fixed version (big-little endian problem) */voidinv_quant_pred_state(TMP_PRED_STATUS *tmp_psp, PRED_STATUS *psp){ int i; short *p2; ulong *p1_tmp; p1_tmp = (ulong *)tmp_psp; p2 = (short *) psp; for (i=0; i<MAX_PRED_BINS*6; i++) p1_tmp[i] = ((ulong)p2[i])<<16;}static void InverseQuantisationPredictorState(TMP_PRED_STATUS *tmp_psp, PRED_STATUS *psp){ int i; short *p; ulong *p_tmp; p_tmp = (ulong *) tmp_psp; p = (short *) psp; for (i = 0; i < 6; i++) p_tmp[i] = ((ulong)p[i]) << 16;}#define FAST_QUANT/* Bug-fixed version (big-little endian problem) */static voidquant_pred_state(PRED_STATUS *psp, TMP_PRED_STATUS *tmp_psp){ int i; short *p1; ulong *p2_tmp;#ifdef FAST_QUANT p1 = (short *) psp; p2_tmp = (ulong *)tmp_psp; for (i=0; i<MAX_PRED_BINS*6;i++) p1[i] = (short) (p2_tmp[i]>>16); #else for (i=0; i<MAX_PRED_BINS; i++) { p1 = (short *) &psp[i]; p2_tmp = (ulong *)tmp_psp; { int j for (j=0; j<6; j++) p1[j] = (short) (p2_tmp[i]>>16); /* Is this a bug?!: p2_tmp[i] is wrong. p2_tmp[i][j] is right. P. Lauber */ } }#endif}static void QuantisationPredictorState(PRED_STATUS *psp, TMP_PRED_STATUS *tmp_psp){ int i; short *p; ulong *p_tmp; p_tmp = (ulong *) tmp_psp; p = (short *) psp; for (i = 0; i < 6; i++) p[i] = (short) (p_tmp[i] >> 16);}/******************************************************************************** *** FUNCTION: reset_pred_state() * *** * *** reset predictor state variables * *** * ********************************************************************************/voidreset_pred_state(PRED_STATUS *psp){ psp->r[0] = Q_ZERO; psp->r[1] = Q_ZERO; psp->kor[0] = Q_ZERO; psp->kor[1] = Q_ZERO; psp->var[0] = Q_ONE; psp->var[1] = Q_ONE;}/******************************************************************************** *** FUNCTION: init_pred_stat() * *** * *** initialisation of all predictor parameter * *** * ********************************************************************************/voidinit_pred_stat(PRED_STATUS *psp, int grad, float alpha, float a, float b){ static int first_time = 1; /* Test of parameters */ if(grad<0 || grad>MAX_PGRAD) { fprintf(stderr,"\n\n ****** error in routine init_pred_stat ******\n"); fprintf(stderr,"\nwrong predictor order: %d\n",grad); fprintf(stderr,"range of allowed values: 0 ... %d (=MAX_PGRAD)\n\n",MAX_PGRAD); CommonExit(1,""); } if(alpha<0 || alpha>=1) { fprintf(stderr,"\n\n ****** error in routine init_pred_stat ******\n"); fprintf(stderr,"\nwrong time constant alpha: %e\n",alpha); fprintf(stderr,"range of allowed values: 0 ... 1\n\n"); CommonExit(1,""); } if(a<0 || a>1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -