Mercurial > hg > audiostuff
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 } |
