2 /******************************************************************
4 iLBC Speech Coder ANSI-C Source Code
8 Copyright (C) The Internet Society (2004).
11 ******************************************************************/
17 #include "iLBC_define.h"
20 /*----------------------------------------------------------------*
21 * Compute cross correlation and pitch gain for pitch prediction
22 * of last subframe at given lag.
23 *---------------------------------------------------------------*/
26 float *cc
, /* (o) cross correlation coefficient */
27 float *gc
, /* (o) gain */
29 float *buffer
, /* (i) signal buffer */
30 int lag
, /* (i) pitch lag */
31 int bLen
, /* (i) length of buffer */
32 int sRange
/* (i) correlation search length */
37 float ftmp1
, ftmp2
, ftmp3
;
39 /* Guard against getting outside buffer */
40 if ((bLen
-sRange
-lag
)<0) {
47 for (i
=0; i
<sRange
; i
++) {
48 ftmp1
+= buffer
[bLen
-sRange
+i
] *
49 buffer
[bLen
-sRange
+i
-lag
];
50 ftmp2
+= buffer
[bLen
-sRange
+i
-lag
] *
51 buffer
[bLen
-sRange
+i
-lag
];
52 ftmp3
+= buffer
[bLen
-sRange
+i
] *
53 buffer
[bLen
-sRange
+i
];
57 *cc
= ftmp1
*ftmp1
/ftmp2
;
58 *gc
= (float)fabs(ftmp1
/ftmp2
);
59 *pm
=(float)fabs(ftmp1
)/
60 ((float)sqrt(ftmp2
)*(float)sqrt(ftmp3
));
69 /*----------------------------------------------------------------*
70 * Packet loss concealment routine. Conceals a residual signal
71 * and LP parameters. If no packet loss, update state.
72 *---------------------------------------------------------------*/
75 float *PLCresidual
, /* (o) concealed residual */
76 float *PLClpc
, /* (o) concealed LP parameters */
77 int PLI
, /* (i) packet loss indicator
79 float *decresidual
, /* (i) decoded residual */
80 float *lpc
, /* (i) decoded LPC (only used for no PL) */
81 int inlag
, /* (i) pitch lag */
82 iLBC_Dec_Inst_t
*iLBCdec_inst
83 /* (i/o) decoder instance */
88 float gain_comp
, maxcc_comp
, per
, max_per
;
92 float ftmp
, randvec
[BLOCKL_MAX
], pitchfact
, energy
;
98 iLBCdec_inst
->consPLICount
+= 1;
100 /* if previous frame not lost,
101 determine pitch pred. gain */
103 if (iLBCdec_inst
->prevPLI
!= 1) {
105 /* Search around the previous lag to find the
109 compCorr(&maxcc
, &gain
, &max_per
,
110 iLBCdec_inst
->prevResidual
,
111 lag
, iLBCdec_inst
->blockl
, 60);
112 for (i
=inlag
-2;i
<=inlag
+3;i
++) {
113 compCorr(&maxcc_comp
, &gain_comp
, &per
,
114 iLBCdec_inst
->prevResidual
,
115 i
, iLBCdec_inst
->blockl
, 60);
117 if (maxcc_comp
>maxcc
) {
127 /* previous frame lost, use recorded lag and periodicity */
130 lag
=iLBCdec_inst
->prevLag
;
131 max_per
=iLBCdec_inst
->per
;
137 if (iLBCdec_inst
->consPLICount
*iLBCdec_inst
->blockl
>320)
139 else if (iLBCdec_inst
->consPLICount
*
140 iLBCdec_inst
->blockl
>2*320)
142 else if (iLBCdec_inst
->consPLICount
*
143 iLBCdec_inst
->blockl
>3*320)
145 else if (iLBCdec_inst
->consPLICount
*
148 iLBCdec_inst
->blockl
>4*320)
151 /* mix noise and pitch repeatition */
152 ftmp
=(float)sqrt(max_per
);
154 pitchfact
=(float)1.0;
155 else if (ftmp
>(float)0.4)
156 pitchfact
=(ftmp
-(float)0.4)/((float)0.7-(float)0.4);
161 /* avoid repetition of same pitch cycle */
167 /* compute concealed residual */
170 for (i
=0; i
<iLBCdec_inst
->blockl
; i
++) {
172 /* noise component */
174 iLBCdec_inst
->seed
=(iLBCdec_inst
->seed
*69069L+1) &
176 randlag
= 50 + ((signed long) iLBCdec_inst
->seed
)%70;
181 iLBCdec_inst
->prevResidual
[
182 iLBCdec_inst
->blockl
+pick
];
184 randvec
[i
] = randvec
[pick
];
187 /* pitch repeatition component */
192 iLBCdec_inst
->prevResidual
[
193 iLBCdec_inst
->blockl
+pick
];
195 PLCresidual
[i
] = PLCresidual
[pick
];
198 /* mix random and periodicity component */
201 PLCresidual
[i
] = use_gain
*(pitchfact
*
205 ((float)1.0 - pitchfact
) * randvec
[i
]);
207 PLCresidual
[i
] = (float)0.95*use_gain
*(pitchfact
*
209 ((float)1.0 - pitchfact
) * randvec
[i
]);
211 PLCresidual
[i
] = (float)0.9*use_gain
*(pitchfact
*
213 ((float)1.0 - pitchfact
) * randvec
[i
]);
215 energy
+= PLCresidual
[i
] * PLCresidual
[i
];
218 /* less than 30 dB, use only noise */
220 if (sqrt(energy
/(float)iLBCdec_inst
->blockl
) < 30.0) {
222 for (i
=0; i
<iLBCdec_inst
->blockl
; i
++) {
223 PLCresidual
[i
] = randvec
[i
];
229 memcpy(PLClpc
,iLBCdec_inst
->prevLpc
,
230 (LPC_FILTERORDER
+1)*sizeof(float));
234 /* no packet loss, copy input */
237 memcpy(PLCresidual
, decresidual
,
238 iLBCdec_inst
->blockl
*sizeof(float));
239 memcpy(PLClpc
, lpc
, (LPC_FILTERORDER
+1)*sizeof(float));
240 iLBCdec_inst
->consPLICount
= 0;
246 iLBCdec_inst
->prevLag
= lag
;
247 iLBCdec_inst
->per
=max_per
;
250 iLBCdec_inst
->prevPLI
= PLI
;
251 memcpy(iLBCdec_inst
->prevLpc
, PLClpc
,
252 (LPC_FILTERORDER
+1)*sizeof(float));
253 memcpy(iLBCdec_inst
->prevResidual
, PLCresidual
,
254 iLBCdec_inst
->blockl
*sizeof(float));