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