Asterisk - The Open Source Telephony Project GIT-master-f36a736
doCPLC.c
Go to the documentation of this file.
1
2 /******************************************************************
3
4 iLBC Speech Coder ANSI-C Source Code
5
6 doCPLC.c
7
8 Copyright (C) The Internet Society (2004).
9 All Rights Reserved.
10
11 ******************************************************************/
12
13 #include <math.h>
14 #include <string.h>
15 #include <stdio.h>
16
17
18
19
20
21 #include "iLBC_define.h"
22
23 /*----------------------------------------------------------------*
24 * Compute cross correlation and pitch gain for pitch prediction
25 * of last subframe at given lag.
26 *---------------------------------------------------------------*/
27
29 float *cc, /* (o) cross correlation coefficient */
30 float *gc, /* (o) gain */
31 float *pm,
32 float *buffer, /* (i) signal buffer */
33 int lag, /* (i) pitch lag */
34 int bLen, /* (i) length of buffer */
35 int sRange /* (i) correlation search length */
36 ){
37 int i;
38 float ftmp1, ftmp2, ftmp3;
39
40 /* Guard against getting outside buffer */
41 if ((bLen-sRange-lag)<0) {
42 sRange=bLen-lag;
43 }
44
45 ftmp1 = 0.0;
46 ftmp2 = 0.0;
47 ftmp3 = 0.0;
48 for (i=0; i<sRange; i++) {
49 ftmp1 += buffer[bLen-sRange+i] *
50 buffer[bLen-sRange+i-lag];
51 ftmp2 += buffer[bLen-sRange+i-lag] *
52 buffer[bLen-sRange+i-lag];
53 ftmp3 += buffer[bLen-sRange+i] *
54 buffer[bLen-sRange+i];
55 }
56
57 if (ftmp2 > 0.0) {
58 *cc = ftmp1*ftmp1/ftmp2;
59 *gc = (float)fabs(ftmp1/ftmp2);
60 *pm=(float)fabs(ftmp1)/
61 ((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
62 }
63 else {
64 *cc = 0.0;
65 *gc = 0.0;
66 *pm=0.0;
67 }
68 }
69
70
71
72
73
74 /*----------------------------------------------------------------*
75 * Packet loss concealment routine. Conceals a residual signal
76 * and LP parameters. If no packet loss, update state.
77 *---------------------------------------------------------------*/
78
80 float *PLCresidual, /* (o) concealed residual */
81 float *PLClpc, /* (o) concealed LP parameters */
82 int PLI, /* (i) packet loss indicator
83 0 - no PL, 1 = PL */
84 float *decresidual, /* (i) decoded residual */
85 float *lpc, /* (i) decoded LPC (only used for no PL) */
86 int inlag, /* (i) pitch lag */
87 iLBC_Dec_Inst_t *iLBCdec_inst
88 /* (i/o) decoder instance */
89 ){
90 int lag=20, randlag;
91 float gain, maxcc;
92 float use_gain;
93 float gain_comp, maxcc_comp, per, max_per=0;
94 int i, pick, use_lag;
95 float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
96
97 /* Packet Loss */
98
99 if (PLI == 1) {
100
101 iLBCdec_inst->consPLICount += 1;
102
103 /* if previous frame not lost,
104 determine pitch pred. gain */
105
106 if (iLBCdec_inst->prevPLI != 1) {
107
108 /* Search around the previous lag to find the
109 best pitch period */
110
111 lag=inlag-3;
112 compCorr(&maxcc, &gain, &max_per,
113 iLBCdec_inst->prevResidual,
114 lag, iLBCdec_inst->blockl, 60);
115 for (i=inlag-2;i<=inlag+3;i++) {
116 compCorr(&maxcc_comp, &gain_comp, &per,
117 iLBCdec_inst->prevResidual,
118 i, iLBCdec_inst->blockl, 60);
119
120 if (maxcc_comp>maxcc) {
121 maxcc=maxcc_comp;
122
123
124
125
126
127 gain=gain_comp;
128 lag=i;
129 max_per=per;
130 }
131 }
132
133 }
134
135 /* previous frame lost, use recorded lag and periodicity */
136
137 else {
138 lag=iLBCdec_inst->prevLag;
139 max_per=iLBCdec_inst->per;
140 }
141
142 /* downscaling */
143
144 use_gain=1.0;
145 if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)
146 use_gain=(float)0.9;
147 else if (iLBCdec_inst->consPLICount*
148 iLBCdec_inst->blockl>2*320)
149 use_gain=(float)0.7;
150 else if (iLBCdec_inst->consPLICount*
151 iLBCdec_inst->blockl>3*320)
152 use_gain=(float)0.5;
153 else if (iLBCdec_inst->consPLICount*
154 iLBCdec_inst->blockl>4*320)
155 use_gain=(float)0.0;
156
157 /* mix noise and pitch repeatition */
158 ftmp=(float)sqrt(max_per);
159 if (ftmp>(float)0.7)
160 pitchfact=(float)1.0;
161 else if (ftmp>(float)0.4)
162 pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
163 else
164 pitchfact=0.0;
165
166
167 /* avoid repetition of same pitch cycle */
168 use_lag=lag;
169 if (lag<80) {
170 use_lag=2*lag;
171 }
172
173 /* compute concealed residual */
174
175
176
177
178
179
180 energy = 0.0;
181 for (i=0; i<iLBCdec_inst->blockl; i++) {
182
183 /* noise component */
184
185 iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
186 (0x80000000L-1);
187 randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
188 pick = i - randlag;
189
190 if (pick < 0) {
191 randvec[i] =
192 iLBCdec_inst->prevResidual[
193 iLBCdec_inst->blockl+pick];
194 } else {
195 randvec[i] = randvec[pick];
196 }
197
198 /* pitch repeatition component */
199 pick = i - use_lag;
200
201 if (pick < 0) {
202 PLCresidual[i] =
203 iLBCdec_inst->prevResidual[
204 iLBCdec_inst->blockl+pick];
205 } else {
206 PLCresidual[i] = PLCresidual[pick];
207 }
208
209 /* mix random and periodicity component */
210
211 if (i<80)
212 PLCresidual[i] = use_gain*(pitchfact *
213 PLCresidual[i] +
214 ((float)1.0 - pitchfact) * randvec[i]);
215 else if (i<160)
216 PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
217 PLCresidual[i] +
218 ((float)1.0 - pitchfact) * randvec[i]);
219 else
220 PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
221 PLCresidual[i] +
222 ((float)1.0 - pitchfact) * randvec[i]);
223
224 energy += PLCresidual[i] * PLCresidual[i];
225 }
226
227 /* less than 30 dB, use only noise */
228
229
230
231
232
233
234 if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
235 gain=0.0;
236 for (i=0; i<iLBCdec_inst->blockl; i++) {
237 PLCresidual[i] = randvec[i];
238 }
239 }
240
241 /* use old LPC */
242
243 memcpy(PLClpc,iLBCdec_inst->prevLpc,
244 (LPC_FILTERORDER+1)*sizeof(float));
245
246 }
247
248 /* no packet loss, copy input */
249
250 else {
251 memcpy(PLCresidual, decresidual,
252 iLBCdec_inst->blockl*sizeof(float));
253 memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
254 iLBCdec_inst->consPLICount = 0;
255 }
256
257 /* update state */
258
259 if (PLI) {
260 iLBCdec_inst->prevLag = lag;
261 iLBCdec_inst->per=max_per;
262 }
263
264 iLBCdec_inst->prevPLI = PLI;
265 memcpy(iLBCdec_inst->prevLpc, PLClpc,
266 (LPC_FILTERORDER+1)*sizeof(float));
267 memcpy(iLBCdec_inst->prevResidual, PLCresidual,
268 iLBCdec_inst->blockl*sizeof(float));
269 }
void doThePLC(float *PLCresidual, float *PLClpc, int PLI, float *decresidual, float *lpc, int inlag, iLBC_Dec_Inst_t *iLBCdec_inst)
Definition: doCPLC.c:79
void compCorr(float *cc, float *gc, float *pm, float *buffer, int lag, int bLen, int sRange)
Definition: doCPLC.c:28
#define BLOCKL_MAX
Definition: iLBC_define.h:21
#define LPC_FILTERORDER
Definition: iLBC_define.h:40
unsigned long seed
Definition: iLBC_define.h:195
float prevResidual[NSUB_MAX *SUBL]
Definition: iLBC_define.h:193
float prevLpc[LPC_FILTERORDER+1]
Definition: iLBC_define.h:192