Asterisk - The Open Source Telephony Project  18.5.0
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Functions
doCPLC.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void doThePLC (float *PLCresidual, float *PLClpc, int PLI, float *decresidual, float *lpc, int inlag, iLBC_Dec_Inst_t *iLBCdec_inst)
 

Function Documentation

◆ doThePLC()

void doThePLC ( float *  PLCresidual,
float *  PLClpc,
int  PLI,
float *  decresidual,
float *  lpc,
int  inlag,
iLBC_Dec_Inst_t iLBCdec_inst 
)

Definition at line 79 of file doCPLC.c.

References iLBC_Dec_Inst_t_::blockl, BLOCKL_MAX, compCorr(), iLBC_Dec_Inst_t_::consPLICount, LPC_FILTERORDER, iLBC_Dec_Inst_t_::per, iLBC_Dec_Inst_t_::prevLag, iLBC_Dec_Inst_t_::prevLpc, iLBC_Dec_Inst_t_::prevPLI, iLBC_Dec_Inst_t_::prevResidual, and iLBC_Dec_Inst_t_::seed.

Referenced by iLBC_decode().

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  }
float prevResidual[NSUB_MAX *SUBL]
Definition: iLBC_define.h:198
#define BLOCKL_MAX
Definition: iLBC_define.h:21
void compCorr(float *cc, float *gc, float *pm, float *buffer, int lag, int bLen, int sRange)
Definition: doCPLC.c:28
#define LPC_FILTERORDER
Definition: iLBC_define.h:40
unsigned long seed
Definition: iLBC_define.h:200
float prevLpc[LPC_FILTERORDER+1]
Definition: iLBC_define.h:197