/src/pjsip/third_party/ilbc/doCPLC.c
Line | Count | Source |
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 | | |
28 | | void compCorr( |
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 | 0 | ){ |
37 | 0 | int i; |
38 | 0 | float ftmp1, ftmp2, ftmp3; |
39 | | |
40 | | /* Guard against getting outside buffer */ |
41 | 0 | if ((bLen-sRange-lag)<0) { |
42 | 0 | sRange=bLen-lag; |
43 | 0 | } |
44 | |
|
45 | 0 | ftmp1 = 0.0; |
46 | 0 | ftmp2 = 0.0; |
47 | 0 | ftmp3 = 0.0; |
48 | 0 | for (i=0; i<sRange; i++) { |
49 | 0 | ftmp1 += buffer[bLen-sRange+i] * |
50 | 0 | buffer[bLen-sRange+i-lag]; |
51 | 0 | ftmp2 += buffer[bLen-sRange+i-lag] * |
52 | 0 | buffer[bLen-sRange+i-lag]; |
53 | 0 | ftmp3 += buffer[bLen-sRange+i] * |
54 | 0 | buffer[bLen-sRange+i]; |
55 | 0 | } |
56 | |
|
57 | 0 | if (ftmp2 > 0.0) { |
58 | 0 | *cc = ftmp1*ftmp1/ftmp2; |
59 | 0 | *gc = (float)fabs(ftmp1/ftmp2); |
60 | 0 | *pm=(float)fabs(ftmp1)/ |
61 | 0 | ((float)sqrt(ftmp2)*(float)sqrt(ftmp3)); |
62 | 0 | } |
63 | 0 | else { |
64 | 0 | *cc = 0.0; |
65 | 0 | *gc = 0.0; |
66 | 0 | *pm=0.0; |
67 | 0 | } |
68 | 0 | } |
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 | | |
79 | | void doThePLC( |
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 | 215 | ){ |
90 | 215 | int lag=20, randlag; |
91 | 215 | float gain, maxcc; |
92 | 215 | float use_gain; |
93 | 215 | float gain_comp, maxcc_comp, per, max_per=0; |
94 | 215 | int i, pick, use_lag; |
95 | 215 | float ftmp, randvec[BLOCKL_MAX], pitchfact, energy; |
96 | | |
97 | | /* Packet Loss */ |
98 | | |
99 | 215 | if (PLI == 1) { |
100 | |
|
101 | 0 | iLBCdec_inst->consPLICount += 1; |
102 | | |
103 | | /* if previous frame not lost, |
104 | | determine pitch pred. gain */ |
105 | |
|
106 | 0 | if (iLBCdec_inst->prevPLI != 1) { |
107 | | |
108 | | /* Search around the previous lag to find the |
109 | | best pitch period */ |
110 | |
|
111 | 0 | lag=inlag-3; |
112 | 0 | compCorr(&maxcc, &gain, &max_per, |
113 | 0 | iLBCdec_inst->prevResidual, |
114 | 0 | lag, iLBCdec_inst->blockl, 60); |
115 | 0 | for (i=inlag-2;i<=inlag+3;i++) { |
116 | 0 | compCorr(&maxcc_comp, &gain_comp, &per, |
117 | 0 | iLBCdec_inst->prevResidual, |
118 | 0 | i, iLBCdec_inst->blockl, 60); |
119 | |
|
120 | 0 | if (maxcc_comp>maxcc) { |
121 | 0 | maxcc=maxcc_comp; |
122 | | |
123 | | |
124 | | |
125 | | |
126 | |
|
127 | 0 | gain=gain_comp; |
128 | 0 | lag=i; |
129 | 0 | max_per=per; |
130 | 0 | } |
131 | 0 | } |
132 | |
|
133 | 0 | } |
134 | | |
135 | | /* previous frame lost, use recorded lag and periodicity */ |
136 | | |
137 | 0 | else { |
138 | 0 | lag=iLBCdec_inst->prevLag; |
139 | 0 | max_per=iLBCdec_inst->per; |
140 | 0 | } |
141 | | |
142 | | /* downscaling */ |
143 | |
|
144 | 0 | use_gain=1.0; |
145 | 0 | if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) |
146 | 0 | use_gain=(float)0.9; |
147 | 0 | else if (iLBCdec_inst->consPLICount* |
148 | 0 | iLBCdec_inst->blockl>2*320) |
149 | 0 | use_gain=(float)0.7; |
150 | 0 | else if (iLBCdec_inst->consPLICount* |
151 | 0 | iLBCdec_inst->blockl>3*320) |
152 | 0 | use_gain=(float)0.5; |
153 | 0 | else if (iLBCdec_inst->consPLICount* |
154 | 0 | iLBCdec_inst->blockl>4*320) |
155 | 0 | use_gain=(float)0.0; |
156 | | |
157 | | /* mix noise and pitch repeatition */ |
158 | 0 | ftmp=(float)sqrt(max_per); |
159 | 0 | if (ftmp>(float)0.7) |
160 | 0 | pitchfact=(float)1.0; |
161 | 0 | else if (ftmp>(float)0.4) |
162 | 0 | pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4); |
163 | 0 | else |
164 | 0 | pitchfact=0.0; |
165 | | |
166 | | |
167 | | /* avoid repetition of same pitch cycle */ |
168 | 0 | use_lag=lag; |
169 | 0 | if (lag<80) { |
170 | 0 | use_lag=2*lag; |
171 | 0 | } |
172 | | |
173 | | /* compute concealed residual */ |
174 | | |
175 | | |
176 | | |
177 | | |
178 | | |
179 | |
|
180 | 0 | energy = 0.0; |
181 | 0 | for (i=0; i<iLBCdec_inst->blockl; i++) { |
182 | | |
183 | | /* noise component */ |
184 | |
|
185 | 0 | iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) & |
186 | 0 | (0x80000000L-1); |
187 | 0 | randlag = 50 + ((signed long) iLBCdec_inst->seed)%70; |
188 | 0 | pick = i - randlag; |
189 | |
|
190 | 0 | if (pick < 0) { |
191 | 0 | randvec[i] = |
192 | 0 | iLBCdec_inst->prevResidual[ |
193 | 0 | iLBCdec_inst->blockl+pick]; |
194 | 0 | } else { |
195 | 0 | randvec[i] = randvec[pick]; |
196 | 0 | } |
197 | | |
198 | | /* pitch repeatition component */ |
199 | 0 | pick = i - use_lag; |
200 | |
|
201 | 0 | if (pick < 0) { |
202 | 0 | PLCresidual[i] = |
203 | 0 | iLBCdec_inst->prevResidual[ |
204 | 0 | iLBCdec_inst->blockl+pick]; |
205 | 0 | } else { |
206 | 0 | PLCresidual[i] = PLCresidual[pick]; |
207 | 0 | } |
208 | | |
209 | | /* mix random and periodicity component */ |
210 | |
|
211 | 0 | if (i<80) |
212 | 0 | PLCresidual[i] = use_gain*(pitchfact * |
213 | 0 | PLCresidual[i] + |
214 | 0 | ((float)1.0 - pitchfact) * randvec[i]); |
215 | 0 | else if (i<160) |
216 | 0 | PLCresidual[i] = (float)0.95*use_gain*(pitchfact * |
217 | 0 | PLCresidual[i] + |
218 | 0 | ((float)1.0 - pitchfact) * randvec[i]); |
219 | 0 | else |
220 | 0 | PLCresidual[i] = (float)0.9*use_gain*(pitchfact * |
221 | 0 | PLCresidual[i] + |
222 | 0 | ((float)1.0 - pitchfact) * randvec[i]); |
223 | |
|
224 | 0 | energy += PLCresidual[i] * PLCresidual[i]; |
225 | 0 | } |
226 | | |
227 | | /* less than 30 dB, use only noise */ |
228 | | |
229 | | |
230 | | |
231 | | |
232 | | |
233 | |
|
234 | 0 | if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) { |
235 | 0 | gain=0.0; |
236 | 0 | for (i=0; i<iLBCdec_inst->blockl; i++) { |
237 | 0 | PLCresidual[i] = randvec[i]; |
238 | 0 | } |
239 | 0 | } |
240 | | |
241 | | /* use old LPC */ |
242 | |
|
243 | 0 | memcpy(PLClpc,iLBCdec_inst->prevLpc, |
244 | 0 | (LPC_FILTERORDER+1)*sizeof(float)); |
245 | |
|
246 | 0 | } |
247 | | |
248 | | /* no packet loss, copy input */ |
249 | | |
250 | 215 | else { |
251 | 215 | memcpy(PLCresidual, decresidual, |
252 | 215 | iLBCdec_inst->blockl*sizeof(float)); |
253 | 215 | memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float)); |
254 | 215 | iLBCdec_inst->consPLICount = 0; |
255 | 215 | } |
256 | | |
257 | | /* update state */ |
258 | | |
259 | 215 | if (PLI) { |
260 | 0 | iLBCdec_inst->prevLag = lag; |
261 | 0 | iLBCdec_inst->per=max_per; |
262 | 0 | } |
263 | | |
264 | 215 | iLBCdec_inst->prevPLI = PLI; |
265 | 215 | memcpy(iLBCdec_inst->prevLpc, PLClpc, |
266 | 215 | (LPC_FILTERORDER+1)*sizeof(float)); |
267 | 215 | memcpy(iLBCdec_inst->prevResidual, PLCresidual, |
268 | 215 | iLBCdec_inst->blockl*sizeof(float)); |
269 | 215 | } |
270 | | |