doCPLC.c File Reference

#include <math.h>
#include <string.h>
#include <stdio.h>
#include "iLBC_define.h"

Include dependency graph for doCPLC.c:

Go to the source code of this file.

Functions

void compCorr (float *cc, float *gc, float *pm, float *buffer, int lag, int bLen, int sRange)
void doThePLC (float *PLCresidual, float *PLClpc, int PLI, float *decresidual, float *lpc, int inlag, iLBC_Dec_Inst_t *iLBCdec_inst)


Function Documentation

void compCorr ( float *  cc,
float *  gc,
float *  pm,
float *  buffer,
int  lag,
int  bLen,
int  sRange 
)

Definition at line 28 of file doCPLC.c.

Referenced by doThePLC().

00036     {
00037        int i;
00038        float ftmp1, ftmp2, ftmp3;
00039 
00040        /* Guard against getting outside buffer */
00041        if ((bLen-sRange-lag)<0) {
00042            sRange=bLen-lag;
00043        }
00044 
00045        ftmp1 = 0.0;
00046        ftmp2 = 0.0;
00047        ftmp3 = 0.0;
00048        for (i=0; i<sRange; i++) {
00049            ftmp1 += buffer[bLen-sRange+i] *
00050                buffer[bLen-sRange+i-lag];
00051            ftmp2 += buffer[bLen-sRange+i-lag] *
00052                    buffer[bLen-sRange+i-lag];
00053            ftmp3 += buffer[bLen-sRange+i] *
00054                    buffer[bLen-sRange+i];
00055        }
00056 
00057        if (ftmp2 > 0.0) {
00058            *cc = ftmp1*ftmp1/ftmp2;
00059            *gc = (float)fabs(ftmp1/ftmp2);
00060            *pm=(float)fabs(ftmp1)/
00061                ((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
00062        }
00063        else {
00064            *cc = 0.0;
00065            *gc = 0.0;
00066            *pm=0.0;
00067        }
00068    }

void doThePLC ( float *  PLCresidual,
float *  PLClpc,
int  PLI,
float *  decresidual,
float *  lpc,
int  inlag,
iLBC_Dec_Inst_t iLBCdec_inst 
)

Definition at line 79 of file doCPLC.c.

References iLBC_Dec_Inst_t_::blockl, BLOCKL_MAX, compCorr(), iLBC_Dec_Inst_t_::consPLICount, LPC_FILTERORDER, iLBC_Dec_Inst_t_::per, iLBC_Dec_Inst_t_::prevLag, iLBC_Dec_Inst_t_::prevLpc, iLBC_Dec_Inst_t_::prevPLI, iLBC_Dec_Inst_t_::prevResidual, and iLBC_Dec_Inst_t_::seed.

Referenced by iLBC_decode().

00089     {
00090        int lag=20, randlag;
00091        float gain, maxcc;
00092        float use_gain;
00093        float gain_comp, maxcc_comp, per, max_per=0;
00094        int i, pick, use_lag;
00095        float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
00096 
00097        /* Packet Loss */
00098 
00099        if (PLI == 1) {
00100 
00101            iLBCdec_inst->consPLICount += 1;
00102 
00103            /* if previous frame not lost,
00104               determine pitch pred. gain */
00105 
00106            if (iLBCdec_inst->prevPLI != 1) {
00107 
00108                /* Search around the previous lag to find the
00109                   best pitch period */
00110 
00111                lag=inlag-3;
00112                compCorr(&maxcc, &gain, &max_per,
00113                    iLBCdec_inst->prevResidual,
00114                    lag, iLBCdec_inst->blockl, 60);
00115                for (i=inlag-2;i<=inlag+3;i++) {
00116                    compCorr(&maxcc_comp, &gain_comp, &per,
00117                        iLBCdec_inst->prevResidual,
00118                        i, iLBCdec_inst->blockl, 60);
00119 
00120                    if (maxcc_comp>maxcc) {
00121                        maxcc=maxcc_comp;
00122 
00123 
00124 
00125 
00126 
00127                        gain=gain_comp;
00128                        lag=i;
00129                        max_per=per;
00130                    }
00131                }
00132 
00133            }
00134 
00135            /* previous frame lost, use recorded lag and periodicity */
00136 
00137            else {
00138                lag=iLBCdec_inst->prevLag;
00139                max_per=iLBCdec_inst->per;
00140            }
00141 
00142            /* downscaling */
00143 
00144            use_gain=1.0;
00145            if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)
00146                use_gain=(float)0.9;
00147            else if (iLBCdec_inst->consPLICount*
00148                            iLBCdec_inst->blockl>2*320)
00149                use_gain=(float)0.7;
00150            else if (iLBCdec_inst->consPLICount*
00151                            iLBCdec_inst->blockl>3*320)
00152                use_gain=(float)0.5;
00153            else if (iLBCdec_inst->consPLICount*
00154                            iLBCdec_inst->blockl>4*320)
00155                use_gain=(float)0.0;
00156 
00157            /* mix noise and pitch repeatition */
00158            ftmp=(float)sqrt(max_per);
00159            if (ftmp>(float)0.7)
00160                pitchfact=(float)1.0;
00161            else if (ftmp>(float)0.4)
00162                pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
00163            else
00164                pitchfact=0.0;
00165 
00166 
00167            /* avoid repetition of same pitch cycle */
00168            use_lag=lag;
00169            if (lag<80) {
00170                use_lag=2*lag;
00171            }
00172 
00173            /* compute concealed residual */
00174 
00175 
00176 
00177 
00178 
00179 
00180            energy = 0.0;
00181            for (i=0; i<iLBCdec_inst->blockl; i++) {
00182 
00183                /* noise component */
00184 
00185                iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
00186                    (0x80000000L-1);
00187                randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
00188                pick = i - randlag;
00189 
00190                if (pick < 0) {
00191                    randvec[i] =
00192                        iLBCdec_inst->prevResidual[
00193                                    iLBCdec_inst->blockl+pick];
00194                } else {
00195                    randvec[i] =  randvec[pick];
00196                }
00197 
00198                /* pitch repeatition component */
00199                pick = i - use_lag;
00200 
00201                if (pick < 0) {
00202                    PLCresidual[i] =
00203                        iLBCdec_inst->prevResidual[
00204                                    iLBCdec_inst->blockl+pick];
00205                } else {
00206                    PLCresidual[i] = PLCresidual[pick];
00207                }
00208 
00209                /* mix random and periodicity component */
00210 
00211                if (i<80)
00212                    PLCresidual[i] = use_gain*(pitchfact *
00213                                PLCresidual[i] +
00214                                ((float)1.0 - pitchfact) * randvec[i]);
00215                else if (i<160)
00216                    PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
00217                                PLCresidual[i] +
00218                                ((float)1.0 - pitchfact) * randvec[i]);
00219                else
00220                    PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
00221                                PLCresidual[i] +
00222                                ((float)1.0 - pitchfact) * randvec[i]);
00223 
00224                energy += PLCresidual[i] * PLCresidual[i];
00225            }
00226 
00227            /* less than 30 dB, use only noise */
00228 
00229 
00230 
00231 
00232 
00233 
00234            if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
00235                gain=0.0;
00236                for (i=0; i<iLBCdec_inst->blockl; i++) {
00237                    PLCresidual[i] = randvec[i];
00238                }
00239            }
00240 
00241            /* use old LPC */
00242 
00243            memcpy(PLClpc,iLBCdec_inst->prevLpc,
00244                (LPC_FILTERORDER+1)*sizeof(float));
00245 
00246        }
00247 
00248        /* no packet loss, copy input */
00249 
00250        else {
00251            memcpy(PLCresidual, decresidual,
00252                iLBCdec_inst->blockl*sizeof(float));
00253            memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
00254            iLBCdec_inst->consPLICount = 0;
00255        }
00256 
00257        /* update state */
00258 
00259        if (PLI) {
00260            iLBCdec_inst->prevLag = lag;
00261            iLBCdec_inst->per=max_per;
00262        }
00263 
00264        iLBCdec_inst->prevPLI = PLI;
00265        memcpy(iLBCdec_inst->prevLpc, PLClpc,
00266            (LPC_FILTERORDER+1)*sizeof(float));
00267        memcpy(iLBCdec_inst->prevResidual, PLCresidual,
00268            iLBCdec_inst->blockl*sizeof(float));
00269    }


Generated on Thu Apr 16 06:30:46 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6