⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ilbc_decoder.java

📁 java的ilbc语音编码器,实现了其全部功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			       int arlength)/* (i) dimension of data array */
    {
	int i;
	float bestcrit,crit;
	int index;

	crit = array[0] - value;
	bestcrit = crit * crit;
	index = 0;
	for (i = 1; i < arlength; i++) {
	    crit = array[i] - value;
	    crit = crit * crit;

	    if (crit < bestcrit) {
		bestcrit = crit;
		index = i;
	    }
	}
	return index;
    }

    /*----------------------------------------------------------------*
     * compute cross correlation between sequences
     *---------------------------------------------------------------*/

    public void mycorr1(
		 float corr[],    /* (o) correlation of seq1 and seq2 */
		 int corr_idx,
		 float seq1[],    /* (i) first sequence */
		 int seq1_idx,
		 int dim1,           /* (i) dimension first seq1 */
		 float seq2[],  /* (i) second sequence */
		 int seq2_idx,
		 int dim2)        /* (i) dimension seq2 */
    {
	int i,j;

// 	System.out.println("longueur 1 : " + seq1.length);
// 	System.out.println("distance 1 : " + seq1_idx);
// 	System.out.println("longueur 2 : " + seq2.length);
// 	System.out.println("distance 2 : " + seq2_idx);

// 	System.out.println("dimensions : " + dim1 + " et " + dim2);

// BUG in ILBC ???

	for (i=0; i<=dim1-dim2; i++) {
	    if ((corr_idx+i) < corr.length)
		corr[corr_idx+i]=0.0f;
	    for (j=0; j<dim2; j++) {
		corr[corr_idx+i] += seq1[seq1_idx+i+j] * seq2[seq2_idx+j];
	    }
	}
    }

    /*----------------------------------------------------------------*
     * upsample finite array assuming zeros outside bounds
     *---------------------------------------------------------------*/

    public void enh_upsample(
			  float useq1[],   /* (o) upsampled output sequence */
			  float seq1[],/* (i) unupsampled sequence */
			  int dim1,       /* (i) dimension seq1 */
			  int hfl)         /* (i) polyphase filter length=2*hfl+1 */
    {
	//	float *pu,*ps;
	int pu, ps;
	int i,j,k,q,filterlength,hfl2;
	int [] polyp = new int[ilbc_constants.ENH_UPS0]; /* pointers to
					 polyphase columns */
	//	const float *pp;
	int pp;

	/* define pointers for filter */

	filterlength=2*hfl+1;

	if ( filterlength > dim1 ) {
	    hfl2=(int) (dim1/2);
	    for (j=0; j<ilbc_constants.ENH_UPS0; j++) {
		polyp[j]=j*filterlength+hfl-hfl2;
	    }
	    hfl=hfl2;
	    filterlength=2*hfl+1;
	}
	else {
	    for (j=0; j<ilbc_constants.ENH_UPS0; j++) {
		polyp[j]=j*filterlength;
	    }
	}

	/* filtering: filter overhangs left side of sequence */

	//	pu=useq1;
	pu = 0;
	for (i=hfl; i<filterlength; i++) {
	    for (j=0; j<ilbc_constants.ENH_UPS0; j++) {
		//		*pu=0.0f;
		useq1[pu] = 0.0f;
		//		pp = polyp[j];
		pp = polyp[j];
		//		ps = seq1+i;
		ps = i;
		for (k=0; k<=i; k++) {
		    useq1[pu] += seq1[ps] * ilbc_constants.polyphaserTbl[pp];
		    ps--;
		    pp++;
		}
		pu++;
	    }
	}

	/* filtering: simple convolution=inner products */

	for (i=filterlength; i<dim1; i++) {
		for (j=0;j < ilbc_constants.ENH_UPS0; j++){
		    //		    *pu=0.0f;
		    useq1[pu] = 0.0f;
		    //		    pp = polyp[j];
		    pp = polyp[j];
		    //		    ps = seq1+i;
		    ps = i;
		    for (k=0; k<filterlength; k++) {
			//			*pu += *ps-- * *pp++;
			useq1[pu] += seq1[ps] * ilbc_constants.polyphaserTbl[pp];
			ps--;
			pp++;
		    }
		    pu++;
		}
	}

	/* filtering: filter overhangs right side of sequence */

	for (q=1; q<=hfl; q++) {
	    for (j=0; j<ilbc_constants.ENH_UPS0; j++) {
		//		*pu=0.0f;
		useq1[pu] = 0.0f;
		//		pp = polyp[j]+q;
		pp = polyp[j]+q;
		//		ps = seq1+dim1-1;
		ps = dim1 - 1;
		for (k=0; k<filterlength-q; k++) {
		    useq1[pu] += seq1[ps] * ilbc_constants.polyphaserTbl[pp];
		    ps--;
		    pp++;
		    //		    *pu += *ps-- * *pp++;
		}
		pu++;
	    }
	}
    }


    /*----------------------------------------------------------------*
     * find segment starting near idata+estSegPos that has highest
     * correlation with idata+centerStartPos through
     * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a
     * resolution of ENH_UPSO times the original of the original
     * sampling rate
     *---------------------------------------------------------------*/

    public float refiner(
		 float seg[],         /* (o) segment array */
		 int seg_idx,
		 float idata[],       /* (i) original data buffer */
		 int idatal,         /* (i) dimension of idata */
		 int centerStartPos, /* (i) beginning center segment */
		 float estSegPos,/* (i) estimated beginning other segment */
		 float period)    /* (i) estimated pitch period */
    {
	int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim;
	int tloc,tloc2,i,st,en,fraction;
	float [] vect = new float[ilbc_constants.ENH_VECTL];
	float [] corrVec = new float[ilbc_constants.ENH_CORRDIM];
	float maxv;
	float [] corrVecUps = new float[ilbc_constants.ENH_CORRDIM*ilbc_constants.ENH_UPS0];
	float updStartPos = 0.0f;

	/* defining array bounds */

	estSegPosRounded=(int)(estSegPos - 0.5);

	searchSegStartPos=estSegPosRounded-ilbc_constants.ENH_SLOP;

	if (searchSegStartPos<0) {
	    searchSegStartPos=0;
	}
	searchSegEndPos=estSegPosRounded+ilbc_constants.ENH_SLOP;

	if (searchSegEndPos+ilbc_constants.ENH_BLOCKL >= idatal) {
	    searchSegEndPos=idatal-ilbc_constants.ENH_BLOCKL-1;
	}
	corrdim=searchSegEndPos-searchSegStartPos+1;

	/* compute upsampled correlation (corr33) and find
	   location of max */
// 	System.out.println("appel 1");
	mycorr1(corrVec, 0, idata, searchSegStartPos,
		corrdim+ilbc_constants.ENH_BLOCKL-1,
		idata,centerStartPos,ilbc_constants.ENH_BLOCKL);
	enh_upsample(corrVecUps,corrVec,corrdim,ilbc_constants.ENH_FL0);
	tloc=0; maxv=corrVecUps[0];
	for (i=1; i<ilbc_constants.ENH_UPS0*corrdim; i++) {

	    if (corrVecUps[i]>maxv) {
		tloc=i;
		maxv=corrVecUps[i];
	    }
	}

	/* make vector can be upsampled without ever running outside
	   bounds */

	updStartPos= (float)searchSegStartPos +
	    (float)tloc/(float)ilbc_constants.ENH_UPS0+(float)1.0f;
	tloc2=(int)(tloc/ilbc_constants.ENH_UPS0);

	if (tloc>tloc2*ilbc_constants.ENH_UPS0) {
	    tloc2++;
	}
	st=searchSegStartPos+tloc2-ilbc_constants.ENH_FL0;

	if (st<0) {
	    for (int li = 0; li < -st; li++)
		vect[li] = 0.0f;
// 	    memset(vect,0,-st*sizeof(float));
	    System.arraycopy(idata, 0, vect, -st, (ilbc_constants.ENH_VECTL+st));
// 	    memcpy(&vect[-st],idata, (ilbc_constants.ENH_VECTL+st)*sizeof(float));
	}
	else {
	    en=st+ilbc_constants.ENH_VECTL;

	    if (en>idatal) {
		System.arraycopy(idata, st, vect, 0, (ilbc_constants.ENH_VECTL-(en-idatal)));
// 		memcpy(vect, &idata[st],
// 		       (ilbc_constants.ENH_VECTL-(en-idatal))*sizeof(float));
		for (int li = 0; li < en-idatal; li++)
		    vect[ilbc_constants.ENH_VECTL-(en-idatal)+li] = 0.0f;
// 		memset(&vect[ilbc_constants.ENH_VECTL-(en-idatal)], 0,
// 		       (en-idatal)*sizeof(float));
	    }
	    else {
		System.arraycopy(idata, st, vect, 0, ilbc_constants.ENH_VECTL);
// 		memcpy(vect, &idata[st], ilbc_constants.ENH_VECTL*sizeof(float));
	    }
	}
	fraction=tloc2*ilbc_constants.ENH_UPS0-tloc;

	/* compute the segment (this is actually a convolution) */

// 	System.out.println("appel 2");
// 	System.out.println("longueur 1 : " + vect.length);
// 	System.out.println("distance 1 : " + 0);
// 	System.out.println("longueur 2 : " + ilbc_constants.polyphaserTbl.length);
// 	System.out.println("distance 2 : " + (2*ilbc_constants.ENH_FL0+1)*fraction);
// 	System.out.println("dimension 1 : " + ilbc_constants.ENH_VECTL);
// 	System.out.println("dimension 2 : " + (2 * ilbc_constants.ENH_FL0+1));
// 	System.out.println("correlations de dimension " + seg.length);
	mycorr1(seg, seg_idx, vect, 0, ilbc_constants.ENH_VECTL,
		ilbc_constants.polyphaserTbl,
		(2*ilbc_constants.ENH_FL0+1)*fraction,
		2*ilbc_constants.ENH_FL0+1);

	return updStartPos;
    }

    /*----------------------------------------------------------------*
     * find the smoothed output data
     *---------------------------------------------------------------*/

    public void smath(
	       float odata[],   /* (o) smoothed output */
	       int odata_idx,
	       float sseq[],/* (i) said second sequence of waveforms */
	       int hl,         /* (i) 2*hl+1 is sseq dimension */
	       float alpha0)/* (i) max smoothing energy fraction */
    {
	int i,k;
	float w00,w10,w11,A,B,C,err,errs;
	float [] surround = new float[ilbc_constants.BLOCKL_MAX]; /* shape contributed by other than
				       current */
	float [] wt = new float[2*ilbc_constants.ENH_HL+1];       /* waveform weighting to get
				       surround shape */
	float denom;
	int psseq;

	/* create shape of contribution from all waveforms except the
	   current one */

	for (i=1; i<=2*hl+1; i++) {
	    wt[i-1] = (float)0.5*(1 - (float)(float)Math.cos(2*ilbc_constants.PI*i/(2*hl+2)));
	}
	wt[hl]=0.0f; /* for clarity, not used */
	for (i=0; i<ilbc_constants.ENH_BLOCKL; i++) {
	    surround[i]=sseq[i]*wt[0];
	}
	for (k=1; k<hl; k++) {
	    psseq=k*ilbc_constants.ENH_BLOCKL;
	    for(i=0;i<ilbc_constants.ENH_BLOCKL; i++) {
		surround[i]+=sseq[psseq+i]*wt[k];
	    }
	    }
	for (k=hl+1; k<=2*hl; k++) {
	    psseq=k*ilbc_constants.ENH_BLOCKL;
	    for(i=0;i<ilbc_constants.ENH_BLOCKL; i++) {
		surround[i]+=sseq[psseq+i]*wt[k];
	    }
	}

	/* compute some inner products */

	w00 = w10 = w11 = 0.0f;
	psseq=hl*ilbc_constants.ENH_BLOCKL; /* current block  */
	for (i=0; i<ilbc_constants.ENH_BLOCKL;i++) {
	    w00+=sseq[psseq+i]*sseq[psseq+i];
	    w11+=surround[i]*surround[i];
	    w10+=surround[i]*sseq[psseq+i];
	}

	if ((float)Math.abs(w11) < 1.0f) {
	    w11=1.0f;
	}
	C = (float)(float)Math.sqrt( w00/w11);

	/* first try enhancement without power-constraint */

	errs=0.0f;
	psseq=hl*ilbc_constants.ENH_BLOCKL;
	for (i=0; i<ilbc_constants.ENH_BLOCKL; i++) {
	    odata[odata_idx+i]=C*surround[i];
	    err=sseq[psseq+i]-odata[odata_idx+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.0001f) { /* eliminates numerical problems
				     for if smooth */
		A = (float)(float)Math.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.0f;
		B= 1.0f;
	    }

	    /* create smoothed sequence */

	    psseq=hl*ilbc_constants.ENH_BLOCKL;
	    for (i=0; i<ilbc_constants.ENH_BLOCKL; i++) {
		odata[odata_idx + i]=A*surround[i]+B*sseq[psseq+i];
	    }
	}
    }

    /*----------------------------------------------------------------*
     * get the pitch-synchronous sample sequence
     *---------------------------------------------------------------*/

    public 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 = new float[2*ilbc_constants.ENH_HL+1];
	int [] lagBlock = new int[2*ilbc_constants.ENH_HL+1];
	float [] plocs2 = new float[ilbc_constants.ENH_PLOCSL];
	//	float *psseq;
	int psseq;

	centerEndPos=centerStartPos+ilbc_constants.ENH_BLOCKL-1;

	/* present */

	lagBlock[hl] = NearestNeighbor(plocs,
			(float)0.5*(centerStartPos+centerEndPos),periodl);

	blockStartPos[hl]=(float)centerStartPos;

	psseq=ilbc_constants.ENH_BLOCKL*hl;
// 	psseq=sseq+ENH_BLOCKL*hl;
	System.arraycopy(idata, centerStartPos, sseq, psseq, ilbc_constants.ENH_BLOCKL);
//	memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));

	/* past */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -