/****************************************************************** | |
iLBC Speech Coder ANSI-C Source Code | |
FrameClassify.c | |
Copyright (C) The Internet Society (2004). | |
All Rights Reserved. | |
******************************************************************/ | |
#include "iLBC_define.h" | |
/*---------------------------------------------------------------* | |
* Classification of subframes to localize start state | |
*--------------------------------------------------------------*/ | |
int FrameClassify( /* index to the max-energy sub-frame */ | |
iLBC_Enc_Inst_t *iLBCenc_inst, | |
/* (i/o) the encoder state structure */ | |
float *residual /* (i) lpc residual signal */ | |
) { | |
float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp; | |
int n, l, max_ssqEn_n; | |
const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9, | |
(float)1.0,(float)0.9,(float)0.8}; | |
const float sampEn_win[5]={(float)1.0/(float)6.0, | |
(float)2.0/(float)6.0, (float)3.0/(float)6.0, | |
(float)4.0/(float)6.0, (float)5.0/(float)6.0}; | |
/* init the front and back energies to zero */ | |
memset(fssqEn, 0, NSUB_MAX*sizeof(float)); | |
memset(bssqEn, 0, NSUB_MAX*sizeof(float)); | |
/* Calculate front of first seqence */ | |
n=0; | |
pp=residual; | |
for (l=0; l<5; l++) { | |
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); | |
pp++; | |
} | |
for (l=5; l<SUBL; l++) { | |
fssqEn[n] += (*pp) * (*pp); | |
pp++; | |
} | |
/* Calculate front and back of all middle sequences */ | |
for (n=1; n<iLBCenc_inst->nsub-1; n++) { | |
pp=residual+n*SUBL; | |
for (l=0; l<5; l++) { | |
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); | |
bssqEn[n] += (*pp) * (*pp); | |
pp++; | |
} | |
for (l=5; l<SUBL-5; l++) { | |
fssqEn[n] += (*pp) * (*pp); | |
bssqEn[n] += (*pp) * (*pp); | |
pp++; | |
} | |
for (l=SUBL-5; l<SUBL; l++) { | |
fssqEn[n] += (*pp) * (*pp); | |
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); | |
pp++; | |
} | |
} | |
/* Calculate back of last seqence */ | |
n=iLBCenc_inst->nsub-1; | |
pp=residual+n*SUBL; | |
for (l=0; l<SUBL-5; l++) { | |
bssqEn[n] += (*pp) * (*pp); | |
pp++; | |
} | |
for (l=SUBL-5; l<SUBL; l++) { | |
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); | |
pp++; | |
} | |
/* find the index to the weighted 80 sample with | |
most energy */ | |
if (iLBCenc_inst->mode==20) l=1; | |
else l=0; | |
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l]; | |
max_ssqEn_n=1; | |
for (n=2; n<iLBCenc_inst->nsub; n++) { | |
l++; | |
if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) { | |
max_ssqEn=(fssqEn[n-1]+bssqEn[n]) * | |
ssqEn_win[l]; | |
max_ssqEn_n=n; | |
} | |
} | |
return max_ssqEn_n; | |
} | |