15 #include "iLBC_define.h"
16 #include "constants.h"
43 for (i=1; i<arlength; i++) {
67 for (i=0; i<=dim1-dim2; i++) {
69 for (j=0; j<dim2; j++) {
70 corr[i] += seq1[i+j] * seq2[j];
91 int i,j,k,q,filterlength,hfl2;
92 const float *polyp[ENH_UPS0];
100 if ( filterlength > dim1 ) {
102 for (j=0; j<ENH_UPS0; j++) {
103 polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2;
106 filterlength=2*hfl+1;
109 for (j=0; j<ENH_UPS0; j++) {
110 polyp[j]=polyphaserTbl+j*filterlength;
117 for (i=hfl; i<filterlength; i++) {
118 for (j=0; j<ENH_UPS0; j++) {
122 for (k=0; k<=i; k++) {
123 *pu += *ps-- * *pp++;
131 for (i=filterlength; i<dim1; i++) {
137 for (j=0;j<ENH_UPS0; j++){
141 for (k=0; k<filterlength; k++) {
142 *pu += *ps-- * *pp++;
150 for (q=1; q<=hfl; q++) {
151 for (j=0; j<ENH_UPS0; j++) {
155 for (k=0; k<filterlength-q; k++) {
156 *pu += *ps-- * *pp++;
181 int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
182 int tloc,tloc2,i,st,en,fraction;
183 float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv;
184 float corrVecUps[ENH_CORRDIM*ENH_UPS0];
192 estSegPosRounded=(int)(estSegPos - 0.5);
194 searchSegStartPos=estSegPosRounded-ENH_SLOP;
196 if (searchSegStartPos<0) {
199 searchSegEndPos=estSegPosRounded+ENH_SLOP;
201 if (searchSegEndPos+ENH_BLOCKL >= idatal) {
202 searchSegEndPos=idatal-ENH_BLOCKL-1;
204 corrdim=searchSegEndPos-searchSegStartPos+1;
209 mycorr1(corrVec,idata+searchSegStartPos,
210 corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL);
211 enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0);
212 tloc=0; maxv=corrVecUps[0];
213 for (i=1; i<ENH_UPS0*corrdim; i++) {
215 if (corrVecUps[i]>maxv) {
224 *updStartPos= (float)searchSegStartPos +
225 (
float)tloc/(float)ENH_UPS0+(
float)1.0;
226 tloc2=(int)(tloc/ENH_UPS0);
228 if (tloc>tloc2*ENH_UPS0) {
231 st=searchSegStartPos+tloc2-ENH_FL0;
234 memset(vect,0,-st*
sizeof(
float));
235 memcpy(&vect[-st],idata, (ENH_VECTL+st)*
sizeof(
float));
246 memcpy(vect, &idata[st],
247 (ENH_VECTL-(en-idatal))*
sizeof(
float));
248 memset(&vect[ENH_VECTL-(en-idatal)], 0,
249 (en-idatal)*
sizeof(
float));
252 memcpy(vect, &idata[st], ENH_VECTL*
sizeof(
float));
255 fraction=tloc2*ENH_UPS0-tloc;
259 mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction,
274 float w00,w10,w11,A,B,C,*psseq,err,errs;
275 float surround[BLOCKL_MAX];
277 float wt[2*ENH_HL+1];
284 for (i=1; i<=2*hl+1; i++) {
285 wt[i-1] = (float)0.5*(1 - (
float)cos(2*PI*i/(2*hl+2)));
288 for (i=0; i<ENH_BLOCKL; i++) {
289 surround[i]=sseq[i]*wt[0];
296 for (k=1; k<hl; k++) {
297 psseq=sseq+k*ENH_BLOCKL;
298 for(i=0;i<ENH_BLOCKL; i++) {
299 surround[i]+=psseq[i]*wt[k];
302 for (k=hl+1; k<=2*hl; k++) {
303 psseq=sseq+k*ENH_BLOCKL;
304 for(i=0;i<ENH_BLOCKL; i++) {
305 surround[i]+=psseq[i]*wt[k];
311 w00 = w10 = w11 = 0.0;
312 psseq=sseq+hl*ENH_BLOCKL;
313 for (i=0; i<ENH_BLOCKL;i++) {
314 w00+=psseq[i]*psseq[i];
315 w11+=surround[i]*surround[i];
316 w10+=surround[i]*psseq[i];
319 if (fabs(w11) < 1.0) {
322 C = (float)sqrt( w00/w11);
327 psseq=sseq+hl*ENH_BLOCKL;
328 for (i=0; i<ENH_BLOCKL; i++) {
329 odata[i]=C*surround[i];
330 err=psseq[i]-odata[i];
336 if (errs > alpha0 * w00) {
340 denom = (w11*w00-w10*w10)/(w00*w00);
342 if (denom > 0.0001) {
349 A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom);
350 B = -alpha0/2 - A * w10/w00;
361 psseq=sseq+hl*ENH_BLOCKL;
362 for (i=0; i<ENH_BLOCKL; i++) {
363 odata[i]=A*surround[i]+B*psseq[i];
383 int i,centerEndPos,q;
384 float blockStartPos[2*ENH_HL+1];
385 int lagBlock[2*ENH_HL+1];
386 float plocs2[ENH_PLOCSL];
389 centerEndPos=centerStartPos+ENH_BLOCKL-1;
393 NearestNeighbor(lagBlock+hl,plocs,
394 (
float)0.5*(centerStartPos+centerEndPos),periodl);
396 blockStartPos[hl]=(float)centerStartPos;
402 psseq=sseq+ENH_BLOCKL*hl;
403 memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*
sizeof(
float));
407 for (q=hl-1; q>=0; q--) {
408 blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];
409 NearestNeighbor(lagBlock+q,plocs,
411 ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);
414 if (blockStartPos[q]-ENH_OVERHANG>=0) {
415 refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata,
416 idatal, centerStartPos, blockStartPos[q],
417 period[lagBlock[q+1]]);
419 psseq=sseq+q*ENH_BLOCKL;
420 memset(psseq, 0, ENH_BLOCKL*
sizeof(
float));
426 for (i=0; i<periodl; i++) {
427 plocs2[i]=plocs[i]-period[i];
429 for (q=hl+1; q<=2*hl; q++) {
430 NearestNeighbor(lagBlock+q,plocs2,
431 blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);
433 blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]];
434 if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) {
435 refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata,
436 idatal, centerStartPos, blockStartPos[q],
437 period[lagBlock[q]]);
440 psseq=sseq+q*ENH_BLOCKL;
441 memset(psseq, 0, ENH_BLOCKL*
sizeof(
float));
468 float sseq[(2*ENH_HL+1)*ENH_BLOCKL];
472 getsseq(sseq,idata,idatal,centerStartPos,period,
473 plocs,periodl,ENH_HL);
477 smath(odata,sseq,ENH_HL,alpha0);
495 for (i=0; i<subl; i++) {
496 ftmp1 += target[i]*regressor[i];
497 ftmp2 += regressor[i]*regressor[i];
501 return (
float)(ftmp1*ftmp1/ftmp2);
517 int enhancerInterface(
522 float *enh_buf, *enh_period;
524 int lag=0, ilag, i, ioffset;
527 float *inPtr, *enh_bufPtr1, *enh_bufPtr2;
528 float plc_pred[ENH_BLOCKL];
530 float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2];
531 int inLen=ENH_NBLOCKS*ENH_BLOCKL+120;
532 int start, plc_blockl, inlag;
534 enh_buf=iLBCdec_inst->enh_buf;
535 enh_period=iLBCdec_inst->enh_period;
537 memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],
538 (ENH_BUFL-iLBCdec_inst->blockl)*
sizeof(
float));
540 memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in,
541 iLBCdec_inst->blockl*
sizeof(
float));
543 if (iLBCdec_inst->mode==30)
544 plc_blockl=ENH_BLOCKL;
550 if (iLBCdec_inst->mode==20) ioffset=1;
553 memmove(enh_period, &enh_period[i],
554 (ENH_NBLOCKS_TOT-i)*
sizeof(
float));
565 enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,
570 DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120,
571 lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL,
572 lpState, downsampled);
575 for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {
578 maxcc = xCorrCoef(downsampled+60+iblock*
579 ENH_BLOCKL_HALF, downsampled+60+iblock*
580 ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF);
581 for (ilag=11; ilag<60; ilag++) {
582 cc = xCorrCoef(downsampled+60+iblock*
583 ENH_BLOCKL_HALF, downsampled+60+iblock*
584 ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF);
593 enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;
600 if (iLBCdec_inst->prev_enh_pl==1) {
602 inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];
605 maxcc = xCorrCoef(in, in+lag, plc_blockl);
606 for (ilag=inlag; ilag<=inlag+1; ilag++) {
607 cc = xCorrCoef(in, in+ilag, plc_blockl);
620 enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;
628 enh_bufPtr1=&plc_pred[plc_blockl-1];
630 if (lag>plc_blockl) {
636 for (isample = start; isample>0; isample--) {
637 *enh_bufPtr1-- = *inPtr--;
640 enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
641 for (isample = (plc_blockl-1-lag); isample>=0; isample--) {
642 *enh_bufPtr1-- = *enh_bufPtr2--;
648 for (i=0;i<plc_blockl;i++) {
649 ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]*
650 enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i];
651 ftmp1+=plc_pred[i]*plc_pred[i];
653 ftmp1=(float)sqrt(ftmp1/(
float)plc_blockl);
654 ftmp2=(float)sqrt(ftmp2/(
float)plc_blockl);
655 if (ftmp1>(
float)2.0*ftmp2 && ftmp1>0.0) {
656 for (i=0;i<plc_blockl-10;i++) {
657 plc_pred[i]*=(float)2.0*ftmp2/ftmp1;
659 for (i=plc_blockl-10;i<plc_blockl;i++) {
660 plc_pred[i]*=(float)(i-plc_blockl+10)*
661 ((float)1.0-(
float)2.0*ftmp2/ftmp1)/(
float)(10)+
667 (
float)2.0*ftmp2/ftmp1;
671 enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
672 for (i=0; i<plc_blockl; i++) {
673 ftmp1 = (float) (i+1) / (float) (plc_blockl+1);
674 *enh_bufPtr1 *= ftmp1;
675 *enh_bufPtr1 += ((float)1.0-ftmp1)*
676 plc_pred[plc_blockl-1-i];
681 if (iLBCdec_inst->mode==20) {
683 for (iblock = 0; iblock<2; iblock++) {
684 enhancer(out+iblock*ENH_BLOCKL, enh_buf,
685 ENH_BUFL, (5+iblock)*ENH_BLOCKL+40,
686 ENH_ALPHA0, enh_period, enh_plocsTbl,
689 }
else if (iLBCdec_inst->mode==30) {
691 for (iblock = 0; iblock<3; iblock++) {
692 enhancer(out+iblock*ENH_BLOCKL, enh_buf,
693 ENH_BUFL, (4+iblock)*ENH_BLOCKL,
694 ENH_ALPHA0, enh_period, enh_plocsTbl,