?? ilbc_decoder.java
字號:
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 + -