📄 enhancer.cxx
字号:
odata[i]=C*surround[i]; err=psseq[i]-odata[i]; errs+=err*err; } /* if constraint violated by first try, add constraint */ if( errs > alpha0 * w00){ if( w00 < 1) { w00=1; } denom = (w11*w00-w10*w10)/(w00*w00); if( denom > 0.0001){ /* eliminates numerical problems for if smooth */ A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom); B = -alpha0/2 - A * w10/w00; B = B+1; } else{ /* essentially no difference between cycles; smoothing not needed */ A= 0.0; B= 1.0; } /* create smoothed sequence */ psseq=sseq+hl*ENH_BLOCKL; for(i=0;i<ENH_BLOCKL;i++) { odata[i]=A*surround[i]+B*psseq[i]; } } } /*----------------------------------------------------------------* * get the pitch-synchronous sample sequence *---------------------------------------------------------------*/ void getsseq( float *sseq, /* (o) the pitch-synchronous sequence */ float *idata, /* (i) original data */ int idatal, /* (i) dimension of data */ int centerStartPos, /* (i) where current block starts */ float *period, /* (i) rough-pitch-period array */ float *plocs, /* (i) where periods of period array are taken */ int periodl, /* (i) dimension period array */ int hl /* (i)( 2*hl+1 is the number of sequences */ ){ int i,centerEndPos,q; float blockStartPos[2*ENH_HL+1]; int lagBlock[2*ENH_HL+1]; float plocs2[ENH_PLOCSL]; float *psseq; centerEndPos=centerStartPos+ENH_BLOCKL-1; /* present */ NearestNeighbor(lagBlock+hl,plocs, (float)0.5*(centerStartPos+centerEndPos),periodl); blockStartPos[hl]=(float)centerStartPos; psseq=sseq+ENH_BLOCKL*hl; memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float)); /* past */ for(q=hl-1;q>=0;q--) { blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; NearestNeighbor(lagBlock+q,plocs, blockStartPos[q]+ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl); if(blockStartPos[q]-ENH_OVERHANG>=0) { refiner(sseq+q*ENH_BLOCKL,blockStartPos+q,idata,idatal, centerStartPos,blockStartPos[q], period[lagBlock[q+1]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } /* future */ for(i=0;i<periodl;i++) { plocs2[i]=plocs[i]-period[i]; } for(q=hl+1;q<=2*hl;q++) { NearestNeighbor(lagBlock+q,plocs2, blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl); blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; if( blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) { refiner(sseq+ENH_BLOCKL*q,blockStartPos+q,idata,idatal, centerStartPos,blockStartPos[q],period[lagBlock[q]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } } /*----------------------------------------------------------------* * perform enhancement on idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 *---------------------------------------------------------------*/ void enhancer( float *odata, /* (o) smoothed block, dimension blockl */ float *idata, /* (i) data buffer used for enhancing */ int idatal, /* (i) dimension idata */ int centerStartPos, /* (i) first sample current block within idata */ float alpha0, /* (i) max correction-energy-fraction (in [0,1]) */ float *period, /* (i) pitch period array */ float *plocs, /* (i) locations where period array values valid */ int periodl /* (i) dimension of period and plocs */ ){ float sseq[(2*ENH_HL+1)*ENH_BLOCKL]; /* get said second sequence of segments */ getsseq(sseq,idata,idatal,centerStartPos,period, plocs,periodl,ENH_HL); /* compute the smoothed output from said second sequence */ smath(odata,sseq,ENH_HL,alpha0); } /*----------------------------------------------------------------* * cross correlation *---------------------------------------------------------------*/ float xCorrCoef( float *target, /* (i) first array */ float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */ ){ int i; float ftmp1, ftmp2; ftmp1 = 0.0; ftmp2 = 0.0; for (i=0; i<subl; i++) { ftmp1 += target[i]*regressor[i]; ftmp2 += regressor[i]*regressor[i]; } if (ftmp1 > 0.0) { return (float)(ftmp1*ftmp1/ftmp2); } else { return (float)0.0; } } /*----------------------------------------------------------------* * interface for enhancer *---------------------------------------------------------------*/ int enhancerInterface( float *out, /* (o) enhanced signal */ float *in, /* (i) unenhanced signal */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */ ){ float *enh_buf, *enh_period; int iblock, isample; int lag, ilag, i; float cc, maxcc; float ftmp1, ftmp2, gain; float *inPtr, *enh_bufPtr1, *enh_bufPtr2; float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2]; int inLen=ENH_NBLOCKS*ENH_BLOCKL+120; int start; enh_buf=iLBCdec_inst->enh_buf; enh_period=iLBCdec_inst->enh_period; memmove(enh_buf, &enh_buf[ENH_NBLOCKS*ENH_BLOCKL], (ENH_NBLOCKS_EXTRA*ENH_BLOCKL)*sizeof(float)); memcpy(&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL], in, (ENH_NBLOCKS*ENH_BLOCKL)*sizeof(float)); if (iLBCdec_inst->prev_enh_pl==1) { /* PLC was performed on the previous packet */ lag = 20; maxcc = xCorrCoef(in, in+lag, ENH_BLOCKL); for (ilag=21; ilag<120; ilag++) { cc = xCorrCoef(in, in+ilag, ENH_BLOCKL); if (cc > maxcc) { maxcc = cc; lag = ilag; } } ftmp1 = 0.0; ftmp2 = 0.0; for (i=0; i<ENH_BLOCKL; i++) { ftmp1 += in[i]*in[i+lag]; ftmp2 += in[i+lag]*in[i+lag]; } if (ftmp1 > 0.0) { gain=(float)(ftmp1/ftmp2); } else { gain=(float)0.0; } if (gain>1.0) { gain=1.0; } else if (gain<-1.0) { gain=-1.0; } inPtr=&in[lag-1]; enh_bufPtr1=&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL-1]; if (lag>ENH_BLOCKL) { start=ENH_BLOCKL; } else { start=lag; } for (isample = start; isample>0; isample--) { *enh_bufPtr1-- = gain*(*inPtr--); } enh_bufPtr2=&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL-1]; for (isample = (ENH_BLOCKL-1-lag); isample>=0; isample--) { *enh_bufPtr1-- = gain*(*enh_bufPtr2--); } } memmove(enh_period, &enh_period[ENH_NBLOCKS], ENH_NBLOCKS_EXTRA*sizeof(float)); /* Set state information to the 6 samples right before the samples to be downsampled. */ memcpy(lpState, enh_buf+ENH_NBLOCKS_EXTRA*ENH_BLOCKL-126, 6*sizeof(float)); /* Down sample a factor 2 to save computations */ DownSample(enh_buf+ENH_NBLOCKS_EXTRA*ENH_BLOCKL-120, lpFilt_coefsTbl, inLen, lpState, downsampled); /* Estimate the pitch in the down sampled domain. */ for(iblock = 0; iblock<ENH_NBLOCKS; iblock++){ lag = 10; maxcc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF); for (ilag=11; ilag<60; ilag++) { cc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF); if (cc > maxcc) { maxcc = cc; lag = ilag; } } /* Store the estimated lag in the non-downsampled domain */ enh_period[iblock+ENH_NBLOCKS_EXTRA] = (float)lag*2; } for(iblock = 0; iblock<2; iblock++){ enhancer(out+iblock*ENH_BLOCKL, enh_buf, ENH_BUFL, (5+iblock)*ENH_BLOCKL+40, ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_NBLOCKS_TOT); } return (lag*2); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -