enhancer.c File Reference

#include <math.h>
#include <string.h>
#include "iLBC_define.h"
#include "constants.h"
#include "filter.h"

Include dependency graph for enhancer.c:

Go to the source code of this file.

Functions

void enh_upsample (float *useq1, float *seq1, int dim1, int hfl)
void enhancer (float *odata, float *idata, int idatal, int centerStartPos, float alpha0, float *period, float *plocs, int periodl)
int enhancerInterface (float *out, float *in, iLBC_Dec_Inst_t *iLBCdec_inst)
void getsseq (float *sseq, float *idata, int idatal, int centerStartPos, float *period, float *plocs, int periodl, int hl)
void mycorr1 (float *corr, float *seq1, int dim1, const float *seq2, int dim2)
void NearestNeighbor (int *index, float *array, float value, int arlength)
void refiner (float *seg, float *updStartPos, float *idata, int idatal, int centerStartPos, float estSegPos, float period)
void smath (float *odata, float *sseq, int hl, float alpha0)
float xCorrCoef (float *target, float *regressor, int subl)


Function Documentation

void enh_upsample ( float *  useq1,
float *  seq1,
int  dim1,
int  hfl 
)

Definition at line 84 of file enhancer.c.

References ENH_UPS0, and polyphaserTbl.

Referenced by refiner().

00089     {
00090        float *pu,*ps;
00091        int i,j,k,q,filterlength,hfl2;
00092        const float *polyp[ENH_UPS0]; /* pointers to
00093                                         polyphase columns */
00094        const float *pp;
00095 
00096        /* define pointers for filter */
00097 
00098        filterlength=2*hfl+1;
00099 
00100        if ( filterlength > dim1 ) {
00101            hfl2=(int) (dim1/2);
00102            for (j=0; j<ENH_UPS0; j++) {
00103                polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2;
00104            }
00105            hfl=hfl2;
00106            filterlength=2*hfl+1;
00107        }
00108        else {
00109            for (j=0; j<ENH_UPS0; j++) {
00110                polyp[j]=polyphaserTbl+j*filterlength;
00111            }
00112        }
00113 
00114        /* filtering: filter overhangs left side of sequence */
00115 
00116        pu=useq1;
00117        for (i=hfl; i<filterlength; i++) {
00118            for (j=0; j<ENH_UPS0; j++) {
00119                *pu=0.0;
00120                pp = polyp[j];
00121                ps = seq1+i;
00122                for (k=0; k<=i; k++) {
00123                    *pu += *ps-- * *pp++;
00124                }
00125                pu++;
00126            }
00127        }
00128 
00129        /* filtering: simple convolution=inner products */
00130 
00131        for (i=filterlength; i<dim1; i++) {
00132 
00133 
00134 
00135 
00136 
00137            for (j=0;j<ENH_UPS0; j++){
00138                *pu=0.0;
00139                pp = polyp[j];
00140                ps = seq1+i;
00141                for (k=0; k<filterlength; k++) {
00142                    *pu += *ps-- * *pp++;
00143                }
00144                pu++;
00145            }
00146        }
00147 
00148        /* filtering: filter overhangs right side of sequence */
00149 
00150        for (q=1; q<=hfl; q++) {
00151            for (j=0; j<ENH_UPS0; j++) {
00152                *pu=0.0;
00153                pp = polyp[j]+q;
00154                ps = seq1+dim1-1;
00155                for (k=0; k<filterlength-q; k++) {
00156                    *pu += *ps-- * *pp++;
00157                }
00158                pu++;
00159            }
00160        }
00161    }

void enhancer ( float *  odata,
float *  idata,
int  idatal,
int  centerStartPos,
float  alpha0,
float *  period,
float *  plocs,
int  periodl 
)

Definition at line 455 of file enhancer.c.

References ENH_BLOCKL, ENH_HL, getsseq(), and smath().

Referenced by enhancerInterface().

00467     {
00468        float sseq[(2*ENH_HL+1)*ENH_BLOCKL];
00469 
00470        /* get said second sequence of segments */
00471 
00472        getsseq(sseq,idata,idatal,centerStartPos,period,
00473            plocs,periodl,ENH_HL);
00474 
00475        /* compute the smoothed output from said second sequence */
00476 
00477        smath(odata,sseq,ENH_HL,alpha0);
00478 
00479    }

int enhancerInterface ( float *  out,
float *  in,
iLBC_Dec_Inst_t iLBCdec_inst 
)

Definition at line 517 of file enhancer.c.

References iLBC_Dec_Inst_t_::blockl, DownSample(), ENH_ALPHA0, ENH_BLOCKL, ENH_BLOCKL_HALF, iLBC_Dec_Inst_t_::enh_buf, ENH_BUFL, ENH_NBLOCKS, ENH_NBLOCKS_EXTRA, ENH_NBLOCKS_TOT, iLBC_Dec_Inst_t_::enh_period, enh_plocsTbl, enhancer(), lpFilt_coefsTbl, iLBC_Dec_Inst_t_::mode, iLBC_Dec_Inst_t_::prev_enh_pl, and xCorrCoef().

Referenced by iLBC_decode().

00521     {
00522        float *enh_buf, *enh_period;
00523        int iblock, isample;
00524        int lag=0, ilag, i, ioffset;
00525        float cc, maxcc;
00526        float ftmp1, ftmp2;
00527        float *inPtr, *enh_bufPtr1, *enh_bufPtr2;
00528        float plc_pred[ENH_BLOCKL];
00529 
00530        float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2];
00531        int inLen=ENH_NBLOCKS*ENH_BLOCKL+120;
00532        int start, plc_blockl, inlag;
00533 
00534        enh_buf=iLBCdec_inst->enh_buf;
00535        enh_period=iLBCdec_inst->enh_period;
00536 
00537        memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],
00538            (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float));
00539 
00540        memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in,
00541            iLBCdec_inst->blockl*sizeof(float));
00542 
00543        if (iLBCdec_inst->mode==30)
00544            plc_blockl=ENH_BLOCKL;
00545        else
00546            plc_blockl=40;
00547 
00548        /* when 20 ms frame, move processing one block */
00549        ioffset=0;
00550        if (iLBCdec_inst->mode==20) ioffset=1;
00551 
00552        i=3-ioffset;
00553        memmove(enh_period, &enh_period[i],
00554            (ENH_NBLOCKS_TOT-i)*sizeof(float));
00555 
00556 
00557 
00558 
00559 
00560 
00561        /* Set state information to the 6 samples right before
00562           the samples to be downsampled. */
00563 
00564        memcpy(lpState,
00565            enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,
00566            6*sizeof(float));
00567 
00568        /* Down sample a factor 2 to save computations */
00569 
00570        DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120,
00571                    lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL,
00572                    lpState, downsampled);
00573 
00574        /* Estimate the pitch in the down sampled domain. */
00575        for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {
00576 
00577            lag = 10;
00578            maxcc = xCorrCoef(downsampled+60+iblock*
00579                ENH_BLOCKL_HALF, downsampled+60+iblock*
00580                ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF);
00581            for (ilag=11; ilag<60; ilag++) {
00582                cc = xCorrCoef(downsampled+60+iblock*
00583                    ENH_BLOCKL_HALF, downsampled+60+iblock*
00584                    ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF);
00585 
00586                if (cc > maxcc) {
00587                    maxcc = cc;
00588                    lag = ilag;
00589                }
00590            }
00591 
00592            /* Store the estimated lag in the non-downsampled domain */
00593            enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;
00594 
00595 
00596        }
00597 
00598 
00599        /* PLC was performed on the previous packet */
00600        if (iLBCdec_inst->prev_enh_pl==1) {
00601 
00602            inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];
00603 
00604            lag = inlag-1;
00605            maxcc = xCorrCoef(in, in+lag, plc_blockl);
00606            for (ilag=inlag; ilag<=inlag+1; ilag++) {
00607                cc = xCorrCoef(in, in+ilag, plc_blockl);
00608 
00609 
00610 
00611 
00612 
00613 
00614                if (cc > maxcc) {
00615                    maxcc = cc;
00616                    lag = ilag;
00617                }
00618            }
00619 
00620            enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;
00621 
00622            /* compute new concealed residual for the old lookahead,
00623               mix the forward PLC with a backward PLC from
00624               the new frame */
00625 
00626            inPtr=&in[lag-1];
00627 
00628            enh_bufPtr1=&plc_pred[plc_blockl-1];
00629 
00630            if (lag>plc_blockl) {
00631                start=plc_blockl;
00632            } else {
00633                start=lag;
00634            }
00635 
00636            for (isample = start; isample>0; isample--) {
00637                *enh_bufPtr1-- = *inPtr--;
00638            }
00639 
00640            enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
00641            for (isample = (plc_blockl-1-lag); isample>=0; isample--) {
00642                *enh_bufPtr1-- = *enh_bufPtr2--;
00643            }
00644 
00645            /* limit energy change */
00646            ftmp2=0.0;
00647            ftmp1=0.0;
00648            for (i=0;i<plc_blockl;i++) {
00649                ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]*
00650                    enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i];
00651                ftmp1+=plc_pred[i]*plc_pred[i];
00652            }
00653            ftmp1=(float)sqrt(ftmp1/(float)plc_blockl);
00654            ftmp2=(float)sqrt(ftmp2/(float)plc_blockl);
00655            if (ftmp1>(float)2.0*ftmp2 && ftmp1>0.0) {
00656                for (i=0;i<plc_blockl-10;i++) {
00657                    plc_pred[i]*=(float)2.0*ftmp2/ftmp1;
00658                }
00659                for (i=plc_blockl-10;i<plc_blockl;i++) {
00660                    plc_pred[i]*=(float)(i-plc_blockl+10)*
00661                        ((float)1.0-(float)2.0*ftmp2/ftmp1)/(float)(10)+
00662 
00663 
00664 
00665 
00666 
00667                        (float)2.0*ftmp2/ftmp1;
00668                }
00669            }
00670 
00671            enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
00672            for (i=0; i<plc_blockl; i++) {
00673                ftmp1 = (float) (i+1) / (float) (plc_blockl+1);
00674                *enh_bufPtr1 *= ftmp1;
00675                *enh_bufPtr1 += ((float)1.0-ftmp1)*
00676                                    plc_pred[plc_blockl-1-i];
00677                enh_bufPtr1--;
00678            }
00679        }
00680 
00681        if (iLBCdec_inst->mode==20) {
00682            /* Enhancer with 40 samples delay */
00683            for (iblock = 0; iblock<2; iblock++) {
00684                enhancer(out+iblock*ENH_BLOCKL, enh_buf,
00685                    ENH_BUFL, (5+iblock)*ENH_BLOCKL+40,
00686                    ENH_ALPHA0, enh_period, enh_plocsTbl,
00687                        ENH_NBLOCKS_TOT);
00688            }
00689        } else if (iLBCdec_inst->mode==30) {
00690            /* Enhancer with 80 samples delay */
00691            for (iblock = 0; iblock<3; iblock++) {
00692                enhancer(out+iblock*ENH_BLOCKL, enh_buf,
00693                    ENH_BUFL, (4+iblock)*ENH_BLOCKL,
00694                    ENH_ALPHA0, enh_period, enh_plocsTbl,
00695                        ENH_NBLOCKS_TOT);
00696            }
00697        }
00698 
00699        return (lag*2);
00700    }

void getsseq ( float *  sseq,
float *  idata,
int  idatal,
int  centerStartPos,
float *  period,
float *  plocs,
int  periodl,
int  hl 
)

Definition at line 372 of file enhancer.c.

References ENH_BLOCKL, ENH_BLOCKL_HALF, ENH_HL, ENH_OVERHANG, ENH_PLOCSL, NearestNeighbor(), and refiner().

Referenced by enhancer().

00382     {
00383        int i,centerEndPos,q;
00384        float blockStartPos[2*ENH_HL+1];
00385        int lagBlock[2*ENH_HL+1];
00386        float plocs2[ENH_PLOCSL];
00387        float *psseq;
00388 
00389        centerEndPos=centerStartPos+ENH_BLOCKL-1;
00390 
00391        /* present */
00392 
00393        NearestNeighbor(lagBlock+hl,plocs,
00394            (float)0.5*(centerStartPos+centerEndPos),periodl);
00395 
00396        blockStartPos[hl]=(float)centerStartPos;
00397 
00398 
00399 
00400 
00401 
00402        psseq=sseq+ENH_BLOCKL*hl;
00403        memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));
00404 
00405        /* past */
00406 
00407        for (q=hl-1; q>=0; q--) {
00408            blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];
00409            NearestNeighbor(lagBlock+q,plocs,
00410                blockStartPos[q]+
00411                ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);
00412 
00413 
00414            if (blockStartPos[q]-ENH_OVERHANG>=0) {
00415                refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata,
00416                    idatal, centerStartPos, blockStartPos[q],
00417                    period[lagBlock[q+1]]);
00418            } else {
00419                psseq=sseq+q*ENH_BLOCKL;
00420                memset(psseq, 0, ENH_BLOCKL*sizeof(float));
00421            }
00422        }
00423 
00424        /* future */
00425 
00426        for (i=0; i<periodl; i++) {
00427            plocs2[i]=plocs[i]-period[i];
00428        }
00429        for (q=hl+1; q<=2*hl; q++) {
00430            NearestNeighbor(lagBlock+q,plocs2,
00431                blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);
00432 
00433            blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]];
00434            if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) {
00435                refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata,
00436                    idatal, centerStartPos, blockStartPos[q],
00437                    period[lagBlock[q]]);
00438            }
00439            else {
00440                psseq=sseq+q*ENH_BLOCKL;
00441                memset(psseq, 0, ENH_BLOCKL*sizeof(float));
00442            }
00443        }
00444    }

void mycorr1 ( float *  corr,
float *  seq1,
int  dim1,
const float *  seq2,
int  dim2 
)

Definition at line 58 of file enhancer.c.

Referenced by refiner().

00064     {
00065        int i,j;
00066 
00067        for (i=0; i<=dim1-dim2; i++) {
00068            corr[i]=0.0;
00069            for (j=0; j<dim2; j++) {
00070                corr[i] += seq1[i+j] * seq2[j];
00071            }
00072        }
00073    }

void NearestNeighbor ( int *  index,
float *  array,
float  value,
int  arlength 
)

Definition at line 25 of file enhancer.c.

Referenced by getsseq().

00036     {
00037        int i;
00038        float bestcrit,crit;
00039 
00040        crit=array[0]-value;
00041        bestcrit=crit*crit;
00042        *index=0;
00043        for (i=1; i<arlength; i++) {
00044            crit=array[i]-value;
00045            crit=crit*crit;
00046 
00047            if (crit<bestcrit) {
00048                bestcrit=crit;
00049                *index=i;
00050            }
00051        }
00052    }

void refiner ( float *  seg,
float *  updStartPos,
float *  idata,
int  idatal,
int  centerStartPos,
float  estSegPos,
float  period 
)

Definition at line 172 of file enhancer.c.

References ENH_BLOCKL, ENH_CORRDIM, ENH_FL0, ENH_SLOP, ENH_UPS0, enh_upsample(), ENH_VECTL, mycorr1(), and polyphaserTbl.

Referenced by getsseq().

00180     {
00181        int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
00182        int tloc,tloc2,i,st,en,fraction;
00183        float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv;
00184        float corrVecUps[ENH_CORRDIM*ENH_UPS0];
00185 
00186 
00187 
00188 
00189 
00190        /* defining array bounds */
00191 
00192        estSegPosRounded=(int)(estSegPos - 0.5);
00193 
00194        searchSegStartPos=estSegPosRounded-ENH_SLOP;
00195 
00196        if (searchSegStartPos<0) {
00197            searchSegStartPos=0;
00198        }
00199        searchSegEndPos=estSegPosRounded+ENH_SLOP;
00200 
00201        if (searchSegEndPos+ENH_BLOCKL >= idatal) {
00202            searchSegEndPos=idatal-ENH_BLOCKL-1;
00203        }
00204        corrdim=searchSegEndPos-searchSegStartPos+1;
00205 
00206        /* compute upsampled correlation (corr33) and find
00207           location of max */
00208 
00209        mycorr1(corrVec,idata+searchSegStartPos,
00210            corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL);
00211        enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0);
00212        tloc=0; maxv=corrVecUps[0];
00213        for (i=1; i<ENH_UPS0*corrdim; i++) {
00214 
00215            if (corrVecUps[i]>maxv) {
00216                tloc=i;
00217                maxv=corrVecUps[i];
00218            }
00219        }
00220 
00221        /* make vector can be upsampled without ever running outside
00222           bounds */
00223 
00224        *updStartPos= (float)searchSegStartPos +
00225            (float)tloc/(float)ENH_UPS0+(float)1.0;
00226        tloc2=(int)(tloc/ENH_UPS0);
00227 
00228        if (tloc>tloc2*ENH_UPS0) {
00229            tloc2++;
00230        }
00231        st=searchSegStartPos+tloc2-ENH_FL0;
00232 
00233        if (st<0) {
00234            memset(vect,0,-st*sizeof(float));
00235            memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float));
00236        }
00237        else {
00238 
00239 
00240 
00241 
00242 
00243            en=st+ENH_VECTL;
00244 
00245            if (en>idatal) {
00246                memcpy(vect, &idata[st],
00247                    (ENH_VECTL-(en-idatal))*sizeof(float));
00248                memset(&vect[ENH_VECTL-(en-idatal)], 0,
00249                    (en-idatal)*sizeof(float));
00250            }
00251            else {
00252                memcpy(vect, &idata[st], ENH_VECTL*sizeof(float));
00253            }
00254        }
00255        fraction=tloc2*ENH_UPS0-tloc;
00256 
00257        /* compute the segment (this is actually a convolution) */
00258 
00259        mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction,
00260            2*ENH_FL0+1);
00261    }

void smath ( float *  odata,
float *  sseq,
int  hl,
float  alpha0 
)

Definition at line 267 of file enhancer.c.

References BLOCKL_MAX, cos, ENH_BLOCKL, ENH_HL, errs, and PI.

Referenced by enhancer().

00272     {
00273        int i,k;
00274        float w00,w10,w11,A,B,C,*psseq,err,errs;
00275        float surround[BLOCKL_MAX]; /* shape contributed by other than
00276                                       current */
00277        float wt[2*ENH_HL+1];       /* waveform weighting to get
00278                                       surround shape */
00279        float denom;
00280 
00281        /* create shape of contribution from all waveforms except the
00282           current one */
00283 
00284        for (i=1; i<=2*hl+1; i++) {
00285            wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2)));
00286        }
00287        wt[hl]=0.0; /* for clarity, not used */
00288        for (i=0; i<ENH_BLOCKL; i++) {
00289            surround[i]=sseq[i]*wt[0];
00290        }
00291 
00292 
00293 
00294 
00295 
00296        for (k=1; k<hl; k++) {
00297            psseq=sseq+k*ENH_BLOCKL;
00298            for(i=0;i<ENH_BLOCKL; i++) {
00299                surround[i]+=psseq[i]*wt[k];
00300            }
00301        }
00302        for (k=hl+1; k<=2*hl; k++) {
00303            psseq=sseq+k*ENH_BLOCKL;
00304            for(i=0;i<ENH_BLOCKL; i++) {
00305                surround[i]+=psseq[i]*wt[k];
00306            }
00307        }
00308 
00309        /* compute some inner products */
00310 
00311        w00 = w10 = w11 = 0.0;
00312        psseq=sseq+hl*ENH_BLOCKL; /* current block  */
00313        for (i=0; i<ENH_BLOCKL;i++) {
00314            w00+=psseq[i]*psseq[i];
00315            w11+=surround[i]*surround[i];
00316            w10+=surround[i]*psseq[i];
00317        }
00318 
00319        if (fabs(w11) < 1.0) {
00320            w11=1.0;
00321        }
00322        C = (float)sqrt( w00/w11);
00323 
00324        /* first try enhancement without power-constraint */
00325 
00326        errs=0.0;
00327        psseq=sseq+hl*ENH_BLOCKL;
00328        for (i=0; i<ENH_BLOCKL; i++) {
00329            odata[i]=C*surround[i];
00330            err=psseq[i]-odata[i];
00331            errs+=err*err;
00332        }
00333 
00334        /* if constraint violated by first try, add constraint */
00335 
00336        if (errs > alpha0 * w00) {
00337            if ( w00 < 1) {
00338                w00=1;
00339            }
00340            denom = (w11*w00-w10*w10)/(w00*w00);
00341 
00342            if (denom > 0.0001) { /* eliminates numerical problems
00343                                     for if smooth */
00344 
00345 
00346 
00347 
00348 
00349                A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom);
00350                B = -alpha0/2 - A * w10/w00;
00351                B = B+1;
00352            }
00353            else { /* essentially no difference between cycles;
00354                      smoothing not needed */
00355                A= 0.0;
00356                B= 1.0;
00357            }
00358 
00359            /* create smoothed sequence */
00360 
00361            psseq=sseq+hl*ENH_BLOCKL;
00362            for (i=0; i<ENH_BLOCKL; i++) {
00363                odata[i]=A*surround[i]+B*psseq[i];
00364            }
00365        }
00366    }

float xCorrCoef ( float *  target,
float *  regressor,
int  subl 
)

Definition at line 485 of file enhancer.c.

Referenced by enhancerInterface(), and iLBC_decode().

00489     {
00490        int i;
00491        float ftmp1, ftmp2;
00492 
00493        ftmp1 = 0.0;
00494        ftmp2 = 0.0;
00495        for (i=0; i<subl; i++) {
00496            ftmp1 += target[i]*regressor[i];
00497            ftmp2 += regressor[i]*regressor[i];
00498        }
00499 
00500        if (ftmp1 > 0.0) {
00501            return (float)(ftmp1*ftmp1/ftmp2);
00502        }
00503 
00504 
00505 
00506 
00507 
00508        else {
00509            return (float)0.0;
00510        }
00511    }


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