comparison intercom/ilbc/doCPLC.c @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
comparison
equal deleted inserted replaced
1:9cadc470e3da 2:13be24d74cd2
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(float *cc, /* (o) cross correlation coefficient */
29 float *gc, /* (o) gain */
30 float *pm, float *buffer, /* (i) signal buffer */
31 int lag, /* (i) pitch lag */
32 int bLen, /* (i) length of buffer */
33 int sRange /* (i) correlation search length */
34 )
35 {
36 int i;
37 float ftmp1, ftmp2, ftmp3;
38
39 /* Guard against getting outside buffer */
40 if ((bLen - sRange - lag) < 0) {
41 sRange = bLen - lag;
42 }
43
44 ftmp1 = 0.0;
45 ftmp2 = 0.0;
46 ftmp3 = 0.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] * buffer[bLen - sRange + i];
53 }
54
55 if (ftmp2 > 0.0) {
56 *cc = ftmp1 * ftmp1 / ftmp2;
57 *gc = (float) fabs(ftmp1 / ftmp2);
58 *pm = (float) fabs(ftmp1) /
59 ((float) sqrt(ftmp2) * (float) sqrt(ftmp3));
60 } else {
61 *cc = 0.0;
62 *gc = 0.0;
63 *pm = 0.0;
64 }
65 }
66
67
68
69
70
71 /*----------------------------------------------------------------*
72 * Packet loss concealment routine. Conceals a residual signal
73 * and LP parameters. If no packet loss, update state.
74 *---------------------------------------------------------------*/
75
76 void doThePLC(float *PLCresidual, /* (o) concealed residual */
77 float *PLClpc, /* (o) concealed LP parameters */
78 int PLI, /* (i) packet loss indicator
79 0 - no PL, 1 = PL */
80 float *decresidual, /* (i) decoded residual */
81 float *lpc, /* (i) decoded LPC (only used for no PL) */
82 int inlag, /* (i) pitch lag */
83 iLBC_Dec_Inst_t * iLBCdec_inst
84 /* (i/o) decoder instance */
85 )
86 {
87 int lag = 20, randlag;
88 float gain, maxcc;
89 float use_gain;
90 float gain_comp, maxcc_comp, per, max_per;
91 int i, pick, use_lag;
92 float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
93
94 /* Packet Loss */
95
96 if (PLI == 1) {
97
98 iLBCdec_inst->consPLICount += 1;
99
100 /* if previous frame not lost,
101 determine pitch pred. gain */
102
103 if (iLBCdec_inst->prevPLI != 1) {
104
105 /* Search around the previous lag to find the
106 best pitch period */
107
108 lag = inlag - 3;
109 compCorr(&maxcc, &gain, &max_per,
110 iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, 60);
111 for (i = inlag - 2; i <= inlag + 3; i++) {
112 compCorr(&maxcc_comp, &gain_comp, &per,
113 iLBCdec_inst->prevResidual, i, iLBCdec_inst->blockl, 60);
114
115 if (maxcc_comp > maxcc) {
116 maxcc = maxcc_comp;
117
118
119
120
121
122 gain = gain_comp;
123 lag = i;
124 max_per = per;
125 }
126 }
127
128 }
129
130 /* previous frame lost, use recorded lag and periodicity */
131
132 else {
133 lag = iLBCdec_inst->prevLag;
134 max_per = iLBCdec_inst->per;
135 }
136
137 /* downscaling */
138
139 use_gain = 1.0;
140 if (iLBCdec_inst->consPLICount * iLBCdec_inst->blockl > 320)
141 use_gain = (float) 0.9;
142 else if (iLBCdec_inst->consPLICount *
143 iLBCdec_inst->blockl > 2 * 320)
144 use_gain = (float) 0.7;
145 else if (iLBCdec_inst->consPLICount *
146 iLBCdec_inst->blockl > 3 * 320)
147 use_gain = (float) 0.5;
148 else if (iLBCdec_inst->consPLICount *
149 iLBCdec_inst->blockl > 4 * 320)
150 use_gain = (float) 0.0;
151
152 /* mix noise and pitch repeatition */
153 ftmp = (float) sqrt(max_per);
154 if (ftmp > (float) 0.7)
155 pitchfact = (float) 1.0;
156 else if (ftmp > (float) 0.4)
157 pitchfact = (ftmp - (float) 0.4) / ((float) 0.7 - (float) 0.4);
158 else
159 pitchfact = 0.0;
160
161
162 /* avoid repetition of same pitch cycle */
163 use_lag = lag;
164 if (lag < 80) {
165 use_lag = 2 * lag;
166 }
167
168 /* compute concealed residual */
169
170
171
172
173
174
175 energy = 0.0;
176 for (i = 0; i < iLBCdec_inst->blockl; i++) {
177
178 /* noise component */
179
180 iLBCdec_inst->seed = (iLBCdec_inst->seed * 69069L + 1) &
181 (0x80000000L - 1);
182 randlag = 50 + ((signed long) iLBCdec_inst->seed) % 70;
183 pick = i - randlag;
184
185 if (pick < 0) {
186 randvec[i] =
187 iLBCdec_inst->prevResidual[iLBCdec_inst->blockl + pick];
188 } else {
189 randvec[i] = randvec[pick];
190 }
191
192 /* pitch repeatition component */
193 pick = i - use_lag;
194
195 if (pick < 0) {
196 PLCresidual[i] =
197 iLBCdec_inst->prevResidual[iLBCdec_inst->blockl + pick];
198 } else {
199 PLCresidual[i] = PLCresidual[pick];
200 }
201
202 /* mix random and periodicity component */
203
204 if (i < 80)
205 PLCresidual[i] = use_gain * (pitchfact *
206 PLCresidual[i] + ((float) 1.0 - pitchfact) * randvec[i]);
207 else if (i < 160)
208 PLCresidual[i] = (float) 0.95 *use_gain * (pitchfact *
209 PLCresidual[i] + ((float) 1.0 - pitchfact) * randvec[i]);
210 else
211 PLCresidual[i] = (float) 0.9 *use_gain * (pitchfact *
212 PLCresidual[i] + ((float) 1.0 - pitchfact) * randvec[i]);
213
214 energy += PLCresidual[i] * PLCresidual[i];
215 }
216
217 /* less than 30 dB, use only noise */
218
219
220
221
222
223
224 if (sqrt(energy / (float) iLBCdec_inst->blockl) < 30.0) {
225 gain = 0.0;
226 for (i = 0; i < iLBCdec_inst->blockl; i++) {
227 PLCresidual[i] = randvec[i];
228 }
229 }
230
231 /* use old LPC */
232
233 memcpy(PLClpc, iLBCdec_inst->prevLpc,
234 (LPC_FILTERORDER + 1) * sizeof(float));
235
236 }
237
238 /* no packet loss, copy input */
239
240 else {
241 memcpy(PLCresidual, decresidual,
242 iLBCdec_inst->blockl * sizeof(float));
243 memcpy(PLClpc, lpc, (LPC_FILTERORDER + 1) * sizeof(float));
244 iLBCdec_inst->consPLICount = 0;
245 }
246
247 /* update state */
248
249 if (PLI) {
250 iLBCdec_inst->prevLag = lag;
251 iLBCdec_inst->per = max_per;
252 }
253
254 iLBCdec_inst->prevPLI = PLI;
255 memcpy(iLBCdec_inst->prevLpc, PLClpc,
256 (LPC_FILTERORDER + 1) * sizeof(float));
257 memcpy(iLBCdec_inst->prevResidual, PLCresidual,
258 iLBCdec_inst->blockl * sizeof(float));
259 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.