levnsn.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* Levnsn.c */
  2. /* Levinson-Durbin LPC
  3. *
  4. * | R0 R1 R2 ... RN-1 | | A1 | | -R1 |
  5. * | R1 R0 R1 ... RN-2 | | A2 | | -R2 |
  6. * | R2 R1 R0 ... RN-3 | | A3 | = | -R3 |
  7. * | ... | | ...| | ... |
  8. * | RN-1 RN-2... R0 | | AN | | -RN |
  9. *
  10. * Ref: John Makhoul, "Linear Prediction, A Tutorial Review"
  11. * Proc. IEEE Vol. 63, PP 561-580 April, 1975.
  12. *
  13. * R is the input autocorrelation function. R0 is the zero lag
  14. * term. A is the output array of predictor coefficients. Note
  15. * that a filter impulse response has a coefficient of 1.0 preceding
  16. * A1. E is an array of mean square error for each prediction order
  17. * 1 to N. REFL is an output array of the reflection coefficients.
  18. */
  19. #define abs(x) ( (x) < 0 ? -(x) : (x) )
  20. int levnsn( n, r, a, e, refl )
  21. int n;
  22. double r[], a[], e[], refl[];
  23. {
  24. int k, km1, i, kmi, j;
  25. double ai, akk, err, err1, r0, t, akmi;
  26. double *pa, *pr;
  27. for( i=0; i<n; i++ )
  28. {
  29. a[i] = 0.0;
  30. e[i] = 0.0;
  31. refl[i] = 0.0;
  32. }
  33. r0 = r[0];
  34. e[0] = r0;
  35. err = r0;
  36. akk = -r[1]/err;
  37. err = (1.0 - akk*akk) * err;
  38. e[1] = err;
  39. a[1] = akk;
  40. refl[1] = akk;
  41. if( err < 1.0e-2 )
  42. return 0;
  43. for( k=2; k<n; k++ )
  44. {
  45. t = 0.0;
  46. pa = &a[1];
  47. pr = &r[k-1];
  48. for( j=1; j<k; j++ )
  49. t += *pa++ * *pr--;
  50. akk = -( r[k] + t )/err;
  51. refl[k] = akk;
  52. km1 = k/2;
  53. for( j=1; j<=km1; j++ )
  54. {
  55. kmi = k-j;
  56. ai = a[j];
  57. akmi = a[kmi];
  58. a[j] = ai + akk*akmi;
  59. if( i == kmi )
  60. goto nxtk;
  61. a[kmi] = akmi + akk*ai;
  62. }
  63. nxtk:
  64. a[k] = akk;
  65. err1 = (1.0 - akk*akk)*err;
  66. e[k] = err1;
  67. if( err1 < 0 )
  68. err1 = -err1;
  69. /* err1 = abs(err1);*/
  70. /* if( (err1 < 1.0e-2) || (err1 >= err) )*/
  71. if( err1 < 1.0e-2 )
  72. return 0;
  73. err = err1;
  74. }
  75. return 0;
  76. }