tbdm.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. $Log$
  3. Revision 1.15 2004/06/26 03:50:14 markster
  4. Merge source cleanups (bug #1911)
  5. Revision 1.14 2003/02/12 13:59:15 matteo
  6. mer feb 12 14:56:57 CET 2003
  7. Revision 1.1.1.1 2003/02/12 13:59:15 matteo
  8. mer feb 12 14:56:57 CET 2003
  9. Revision 1.2 2000/01/05 08:20:40 markster
  10. Some OSS fixes and a few lpc changes to make it actually work
  11. * Revision 1.1 1996/08/19 22:30:26 jaf
  12. * Initial revision
  13. *
  14. */
  15. /* -- translated by f2c (version 19951025).
  16. You must link the resulting object file with the libraries:
  17. -lf2c -lm (in that order)
  18. */
  19. #include "f2c.h"
  20. #ifdef P_R_O_T_O_T_Y_P_E_S
  21. extern int tbdm_(real *speech, integer *lpita, integer *tau, integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *mintau);
  22. /*:ref: difmag_ 14 8 6 4 4 4 4 6 4 4 */
  23. #endif
  24. /* ********************************************************************** */
  25. /* TBDM Version 49 */
  26. /* $Log$
  27. * Revision 1.15 2004/06/26 03:50:14 markster
  28. * Merge source cleanups (bug #1911)
  29. *
  30. * Revision 1.14 2003/02/12 13:59:15 matteo
  31. * mer feb 12 14:56:57 CET 2003
  32. *
  33. * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
  34. * mer feb 12 14:56:57 CET 2003
  35. *
  36. * Revision 1.2 2000/01/05 08:20:40 markster
  37. * Some OSS fixes and a few lpc changes to make it actually work
  38. *
  39. * Revision 1.1 1996/08/19 22:30:26 jaf
  40. * Initial revision
  41. * */
  42. /* Revision 1.3 1996/03/18 22:14:00 jaf */
  43. /* Just added a few comments about which array indices of the arguments */
  44. /* are used, and mentioning that this subroutine has no local state. */
  45. /* Revision 1.2 1996/03/13 14:48:37 jaf */
  46. /* Comments added explaining that none of the local variables of this */
  47. /* subroutine need to be saved from one invocation to the next. */
  48. /* Revision 1.1 1996/02/07 14:49:54 jaf */
  49. /* Initial revision */
  50. /* ********************************************************************* */
  51. /*TURBO DIFMAG: Compute High Resolution Average Magnitude Difference Function
  52. */
  53. /* Note: There are several constants in here that appear to depend on a */
  54. /* particular TAU table. That's not a problem for the LPC10 coder, but */
  55. /* watch out if you change the contents of TAU in the subroutine ANALYS. */
  56. /* Input: */
  57. /* SPEECH - Low pass filtered speech */
  58. /* Indices 1 through MAX+LPITA-1 are read, where: */
  59. /* MAX = (TAU(LTAU)-TAU(1))/2+1 */
  60. /* (If TAU(1) .LT. 39, then larger indices could be read */
  61. /* by the last call to DIFMAG below.) */
  62. /* LPITA - Length of speech buffer */
  63. /* TAU - Table of lags, sorted in increasing order. */
  64. /* Indices 1 through LTAU read. */
  65. /* LTAU - Number of lag values to compute */
  66. /* Output: */
  67. /* AMDF - Average Magnitude Difference for each lag in TAU */
  68. /* Indices 1 through LTAU written, and several might then be read.*/
  69. /* MINPTR - Index of minimum AMDF value */
  70. /* MAXPTR - Index of maximum AMDF value within +/- 1/2 octave of min */
  71. /* MINTAU - Lag corresponding to minimum AMDF value */
  72. /* This subroutine has no local state. */
  73. /* Subroutine */ int tbdm_(real *speech, integer *lpita, integer *tau,
  74. integer *ltau, real *amdf, integer *minptr, integer *maxptr, integer *
  75. mintau)
  76. {
  77. /* System generated locals */
  78. integer i__1, i__2, i__3, i__4;
  79. /* Local variables */
  80. real amdf2[6];
  81. integer minp2, ltau2, maxp2, i__;
  82. extern /* Subroutine */ int difmag_(real *, integer *, integer *, integer
  83. *, integer *, real *, integer *, integer *);
  84. integer minamd, ptr, tau2[6];
  85. /* Arguments */
  86. /* REAL SPEECH(LPITA+TAU(LTAU)), AMDF(LTAU) */
  87. /* Stupid TOAST doesn't understand expressions */
  88. /* Local variables that need not be saved */
  89. /* Local state */
  90. /* None */
  91. /* Compute full AMDF using log spaced lags, find coarse minimum */
  92. /* Parameter adjustments */
  93. --speech;
  94. --amdf;
  95. --tau;
  96. /* Function Body */
  97. difmag_(&speech[1], lpita, &tau[1], ltau, &tau[*ltau], &amdf[1], minptr,
  98. maxptr);
  99. *mintau = tau[*minptr];
  100. minamd = (integer)amdf[*minptr];
  101. /* Build table containing all lags within +/- 3 of the AMDF minimum */
  102. /* excluding all that have already been computed */
  103. ltau2 = 0;
  104. ptr = *minptr - 2;
  105. /* Computing MAX */
  106. i__1 = *mintau - 3;
  107. /* Computing MIN */
  108. i__3 = *mintau + 3, i__4 = tau[*ltau] - 1;
  109. i__2 = min(i__3,i__4);
  110. for (i__ = max(i__1,41); i__ <= i__2; ++i__) {
  111. while(tau[ptr] < i__) {
  112. ++ptr;
  113. }
  114. if (tau[ptr] != i__) {
  115. ++ltau2;
  116. tau2[ltau2 - 1] = i__;
  117. }
  118. }
  119. /* Compute AMDF of the new lags, if there are any, and choose one */
  120. /* if it is better than the coarse minimum */
  121. if (ltau2 > 0) {
  122. difmag_(&speech[1], lpita, tau2, &ltau2, &tau[*ltau], amdf2, &minp2, &
  123. maxp2);
  124. if (amdf2[minp2 - 1] < (real) minamd) {
  125. *mintau = tau2[minp2 - 1];
  126. minamd = (integer)amdf2[minp2 - 1];
  127. }
  128. }
  129. /* Check one octave up, if there are any lags not yet computed */
  130. if (*mintau >= 80) {
  131. i__ = *mintau / 2;
  132. if ((i__ & 1) == 0) {
  133. ltau2 = 2;
  134. tau2[0] = i__ - 1;
  135. tau2[1] = i__ + 1;
  136. } else {
  137. ltau2 = 1;
  138. tau2[0] = i__;
  139. }
  140. difmag_(&speech[1], lpita, tau2, &ltau2, &tau[*ltau], amdf2, &minp2, &
  141. maxp2);
  142. if (amdf2[minp2 - 1] < (real) minamd) {
  143. *mintau = tau2[minp2 - 1];
  144. minamd = (integer)amdf2[minp2 - 1];
  145. *minptr += -20;
  146. }
  147. }
  148. /* Force minimum of the AMDF array to the high resolution minimum */
  149. amdf[*minptr] = (real) minamd;
  150. /* Find maximum of AMDF within 1/2 octave of minimum */
  151. /* Computing MAX */
  152. i__2 = *minptr - 5;
  153. *maxptr = max(i__2,1);
  154. /* Computing MIN */
  155. i__1 = *minptr + 5;
  156. i__2 = min(i__1,*ltau);
  157. for (i__ = *maxptr + 1; i__ <= i__2; ++i__) {
  158. if (amdf[i__] > amdf[*maxptr]) {
  159. *maxptr = i__;
  160. }
  161. }
  162. return 0;
  163. } /* tbdm_ */