doCPLC.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /******************************************************************
  2. iLBC Speech Coder ANSI-C Source Code
  3. doCPLC.c
  4. Copyright (C) The Internet Society (2004).
  5. All Rights Reserved.
  6. ******************************************************************/
  7. #include <math.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include "iLBC_define.h"
  11. /*----------------------------------------------------------------*
  12. * Compute cross correlation and pitch gain for pitch prediction
  13. * of last subframe at given lag.
  14. *---------------------------------------------------------------*/
  15. void compCorr(
  16. float *cc, /* (o) cross correlation coefficient */
  17. float *gc, /* (o) gain */
  18. float *pm,
  19. float *buffer, /* (i) signal buffer */
  20. int lag, /* (i) pitch lag */
  21. int bLen, /* (i) length of buffer */
  22. int sRange /* (i) correlation search length */
  23. ){
  24. int i;
  25. float ftmp1, ftmp2, ftmp3;
  26. /* Guard against getting outside buffer */
  27. if ((bLen-sRange-lag)<0) {
  28. sRange=bLen-lag;
  29. }
  30. ftmp1 = 0.0;
  31. ftmp2 = 0.0;
  32. ftmp3 = 0.0;
  33. for (i=0; i<sRange; i++) {
  34. ftmp1 += buffer[bLen-sRange+i] *
  35. buffer[bLen-sRange+i-lag];
  36. ftmp2 += buffer[bLen-sRange+i-lag] *
  37. buffer[bLen-sRange+i-lag];
  38. ftmp3 += buffer[bLen-sRange+i] *
  39. buffer[bLen-sRange+i];
  40. }
  41. if (ftmp2 > 0.0) {
  42. *cc = ftmp1*ftmp1/ftmp2;
  43. *gc = (float)fabs(ftmp1/ftmp2);
  44. *pm=(float)fabs(ftmp1)/
  45. ((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
  46. }
  47. else {
  48. *cc = 0.0;
  49. *gc = 0.0;
  50. *pm=0.0;
  51. }
  52. }
  53. /*----------------------------------------------------------------*
  54. * Packet loss concealment routine. Conceals a residual signal
  55. * and LP parameters. If no packet loss, update state.
  56. *---------------------------------------------------------------*/
  57. void doThePLC(
  58. float *PLCresidual, /* (o) concealed residual */
  59. float *PLClpc, /* (o) concealed LP parameters */
  60. int PLI, /* (i) packet loss indicator
  61. 0 - no PL, 1 = PL */
  62. float *decresidual, /* (i) decoded residual */
  63. float *lpc, /* (i) decoded LPC (only used for no PL) */
  64. int inlag, /* (i) pitch lag */
  65. iLBC_Dec_Inst_t *iLBCdec_inst
  66. /* (i/o) decoder instance */
  67. ){
  68. int lag=20, randlag;
  69. float gain, maxcc;
  70. float use_gain;
  71. float gain_comp, maxcc_comp, per, max_per=0;
  72. int i, pick, use_lag;
  73. float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
  74. /* Packet Loss */
  75. if (PLI == 1) {
  76. iLBCdec_inst->consPLICount += 1;
  77. /* if previous frame not lost,
  78. determine pitch pred. gain */
  79. if (iLBCdec_inst->prevPLI != 1) {
  80. /* Search around the previous lag to find the
  81. best pitch period */
  82. lag=inlag-3;
  83. compCorr(&maxcc, &gain, &max_per,
  84. iLBCdec_inst->prevResidual,
  85. lag, iLBCdec_inst->blockl, 60);
  86. for (i=inlag-2;i<=inlag+3;i++) {
  87. compCorr(&maxcc_comp, &gain_comp, &per,
  88. iLBCdec_inst->prevResidual,
  89. i, iLBCdec_inst->blockl, 60);
  90. if (maxcc_comp>maxcc) {
  91. maxcc=maxcc_comp;
  92. gain=gain_comp;
  93. lag=i;
  94. max_per=per;
  95. }
  96. }
  97. }
  98. /* previous frame lost, use recorded lag and periodicity */
  99. else {
  100. lag=iLBCdec_inst->prevLag;
  101. max_per=iLBCdec_inst->per;
  102. }
  103. /* downscaling */
  104. use_gain=1.0;
  105. if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)
  106. use_gain=(float)0.9;
  107. else if (iLBCdec_inst->consPLICount*
  108. iLBCdec_inst->blockl>2*320)
  109. use_gain=(float)0.7;
  110. else if (iLBCdec_inst->consPLICount*
  111. iLBCdec_inst->blockl>3*320)
  112. use_gain=(float)0.5;
  113. else if (iLBCdec_inst->consPLICount*
  114. iLBCdec_inst->blockl>4*320)
  115. use_gain=(float)0.0;
  116. /* mix noise and pitch repeatition */
  117. ftmp=(float)sqrt(max_per);
  118. if (ftmp>(float)0.7)
  119. pitchfact=(float)1.0;
  120. else if (ftmp>(float)0.4)
  121. pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
  122. else
  123. pitchfact=0.0;
  124. /* avoid repetition of same pitch cycle */
  125. use_lag=lag;
  126. if (lag<80) {
  127. use_lag=2*lag;
  128. }
  129. /* compute concealed residual */
  130. energy = 0.0;
  131. for (i=0; i<iLBCdec_inst->blockl; i++) {
  132. /* noise component */
  133. iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
  134. (0x80000000L-1);
  135. randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
  136. pick = i - randlag;
  137. if (pick < 0) {
  138. randvec[i] =
  139. iLBCdec_inst->prevResidual[
  140. iLBCdec_inst->blockl+pick];
  141. } else {
  142. randvec[i] = randvec[pick];
  143. }
  144. /* pitch repeatition component */
  145. pick = i - use_lag;
  146. if (pick < 0) {
  147. PLCresidual[i] =
  148. iLBCdec_inst->prevResidual[
  149. iLBCdec_inst->blockl+pick];
  150. } else {
  151. PLCresidual[i] = PLCresidual[pick];
  152. }
  153. /* mix random and periodicity component */
  154. if (i<80)
  155. PLCresidual[i] = use_gain*(pitchfact *
  156. PLCresidual[i] +
  157. ((float)1.0 - pitchfact) * randvec[i]);
  158. else if (i<160)
  159. PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
  160. PLCresidual[i] +
  161. ((float)1.0 - pitchfact) * randvec[i]);
  162. else
  163. PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
  164. PLCresidual[i] +
  165. ((float)1.0 - pitchfact) * randvec[i]);
  166. energy += PLCresidual[i] * PLCresidual[i];
  167. }
  168. /* less than 30 dB, use only noise */
  169. if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
  170. gain=0.0;
  171. for (i=0; i<iLBCdec_inst->blockl; i++) {
  172. PLCresidual[i] = randvec[i];
  173. }
  174. }
  175. /* use old LPC */
  176. memcpy(PLClpc,iLBCdec_inst->prevLpc,
  177. (LPC_FILTERORDER+1)*sizeof(float));
  178. }
  179. /* no packet loss, copy input */
  180. else {
  181. memcpy(PLCresidual, decresidual,
  182. iLBCdec_inst->blockl*sizeof(float));
  183. memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
  184. iLBCdec_inst->consPLICount = 0;
  185. }
  186. /* update state */
  187. if (PLI) {
  188. iLBCdec_inst->prevLag = lag;
  189. iLBCdec_inst->per=max_per;
  190. }
  191. iLBCdec_inst->prevPLI = PLI;
  192. memcpy(iLBCdec_inst->prevLpc, PLClpc,
  193. (LPC_FILTERORDER+1)*sizeof(float));
  194. memcpy(iLBCdec_inst->prevResidual, PLCresidual,
  195. iLBCdec_inst->blockl*sizeof(float));
  196. }