Coverage Report

Created: 2026-03-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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