Version 0.1.4 from FTP
[asterisk/asterisk.git] / codecs / lpc10 / placev.c
1 /*
2
3 $Log$
4 Revision 1.3  2000/01/05 08:20:39  markster
5 Version 0.1.4 from FTP
6
7 Revision 1.2  2000/01/05 08:20:39  markster
8 Some OSS fixes and a few lpc changes to make it actually work
9
10  * Revision 1.1  1996/08/19  22:31:02  jaf
11  * Initial revision
12  *
13
14 */
15
16 #ifdef P_R_O_T_O_T_Y_P_E_S
17 extern int placev_(integer *osbuf, integer *osptr, integer *oslen, integer *obound, integer *vwin, integer *af, integer *lframe, integer *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh);
18 #endif
19
20 /*  -- translated by f2c (version 19951025).
21    You must link the resulting object file with the libraries:
22         -lf2c -lm   (in that order)
23 */
24
25 #include "f2c.h"
26
27 /* ****************************************************************** */
28
29 /*      PLACEV Version 48 */
30
31 /* $Log$
32  * Revision 1.3  2000/01/05 08:20:39  markster
33  * Version 0.1.4 from FTP
34  *
35 /* Revision 1.2  2000/01/05 08:20:39  markster
36 /* Some OSS fixes and a few lpc changes to make it actually work
37 /*
38  * Revision 1.1  1996/08/19  22:31:02  jaf
39  * Initial revision
40  * */
41 /* Revision 1.6  1996/03/19  20:42:19  jaf */
42 /* Added some conditions satisfied by the output values in VWIN. */
43
44 /* Revision 1.5  1996/03/19  18:37:56  jaf */
45 /* Strengthened the specification of which indices of VWIN are read and */
46 /* written. */
47
48 /* Revision 1.4  1996/03/15  16:38:33  jaf */
49 /* One tiny comment added. */
50
51 /* Revision 1.3  1996/03/15  16:36:13  jaf */
52 /* Added comments giving In/Out status of arguments. */
53
54 /* Revision 1.2  1996/03/12  23:56:01  jaf */
55 /* Comments added explaining that none of the local variables of this */
56 /* subroutine need to be saved from one invocation to the next. */
57
58 /* Revision 1.1  1996/02/07 14:48:39  jaf */
59 /* Initial revision */
60
61
62 /* ****************************************************************** */
63
64 /* Input: */
65 /*  OSBUF       Buffer which holds sorted indexes of onsets */
66 /*              I believe that only indices 1 through OSPTR-1 can be read. */
67 /*  OSLEN */
68 /*  OSPTR       Free pointer into OSBUF */
69 /*  AF */
70 /*  LFRAME */
71 /*  MINWIN */
72 /*  MAXWIN */
73 /*  DVWINL */
74 /*  DVWINH      (This argument is never used.  Should it be?) */
75 /* Input/Output: */
76 /*  VWIN                Buffer of Voicing Window Positions (Modified) */
77 /*              Index (2,AF-1) is read. */
78 /*              Indices (1,AF) and (2,AF) are written, */
79 /*              and then possibly read. */
80 /*              All other indices are unused. */
81 /*              In all cases, the final values will satsify the condition:*/
82 /*               VWIN(2,AF)-VWIN(1,AF)+1 .LE. MAXWIN */
83 /*               I'm not certain yet, but they may also satisfy: */
84 /*               MINWIN .LE. VWIN(2,AF)-VWIN(1,AF)+1 */
85 /* Output: */
86 /*  OBOUND      This variable is set by this procedure and used */
87 /*              in placing analysis windows (PLACEA).  Bit 1 */
88 /*              indicates whether an onset bounds the left side */
89 /*              of the voicing window, and bit 2 indicates whether */
90 /*              an onset bounds the right side of the voicing window. */
91
92 /* This subroutine has no local state. */
93
94 /* Subroutine */ int placev_(integer *osbuf, integer *osptr, integer *oslen, 
95         integer *obound, integer *vwin, integer *af, integer *lframe, integer 
96         *minwin, integer *maxwin, integer *dvwinl, integer *dvwinh)
97 {
98     /* System generated locals */
99     integer i__1, i__2;
100
101     /* Local variables */
102     logical crit;
103     integer i__, q, osptr1, hrange, lrange;
104
105 /*       Arguments */
106 /*       Local variables that need not be saved */
107 /*   Variables */
108 /*    LRANGE, HRANGE  Range in which window is placed */
109 /*    OSPTR1     OSPTR excluding samples in 3F */
110 /*       Local state */
111 /*       None */
112 /*   Voicing Window Placement */
113
114 /*         __________________ __________________ ______________ */
115 /*        |                  |                  | */
116 /*        |        1F        |        2F        |        3F ... */
117 /*        |__________________|__________________|______________ */
118
119 /*    Previous | */
120 /*      Window | */
121 /*  ...________| */
122
123 /*             |                                | */
124 /*      ------>| This window's placement range  |<------ */
125 /*             |                                | */
126
127 /*   There are three cases.  Note that these are different from those */
128 /*   given in the LPC-10e phase 1 report. */
129
130 /*   1.  If there are no onsets in this range, then the voicing window */
131 /*   is centered in the pitch window.  If such a placement is not within 
132 */
133 /*   the window's placement range, then the window is placed in the left- 
134 */
135 /*   most portion of the placement range.  Its length is always MAXWIN. */
136
137 /*   2.  If the first onset is in 2F and there is sufficient room to place
138  */
139 /*   the window immediately before this onset, then the window is placed 
140 */
141 /*   there, and its length is set to the maximum possible under these */
142 /*   constraints. */
143
144 /*      "Critical Region Exception":  If there is another onset in 2F */
145 /*      such that a window can be placed between the two onsets, the */
146 /*      window is placed there (ie, as in case 3). */
147
148 /*   3.  Otherwise, the window is placed immediately after the onset.  The
149  */
150 /*   window's length */
151 /*  is the longest length that can fit in the range under these constraint
152 s,*/
153 /*  except that the window may be shortened even further to avoid overlapp
154 ing*/
155 /*  other onsets in the placement range.  In any case, the window's length
156 */
157 /*   is at least MINWIN. */
158
159 /*   Note that the values of MINWIN and LFRAME must be chosen such */
160 /*   that case 2 = false implies case 3 = true.   This means that */
161 /*   MINWIN <= LFRAME/2.  If this were not the case, then a fourth case */
162 /*   would have to be added for when the window cannot fit either before 
163 */
164 /*   or after the onset. */
165
166 /*   Note also that onsets which weren't in 2F last time may be in 1F this
167  */
168 /*  time, due to the filter delays in computing onsets.  The result is tha
169 t*/
170 /*   occasionally a voicing window will overlap that onset.  The only way 
171 */
172 /*   to circumvent this problem is to add more delay in processing input 
173 */
174 /*   speech.  In the trade-off between delay and window-placement, window 
175 */
176 /*   placement lost. */
177 /* Compute the placement range */
178     /* Parameter adjustments */
179     --osbuf;
180     vwin -= 3;
181
182     /* Function Body */
183 /* Computing MAX */
184     i__1 = vwin[(*af - 1 << 1) + 2] + 1, i__2 = (*af - 2) * *lframe + 1;
185     lrange = max(i__1,i__2);
186     hrange = *af * *lframe;
187 /* Compute OSPTR1, so the following code only looks at relevant onsets. */
188     for (osptr1 = *osptr - 1; osptr1 >= 1; --osptr1) {
189         if (osbuf[osptr1] <= hrange) {
190             goto L90;
191         }
192     }
193 L90:
194     ++osptr1;
195 /* Check for case 1 first (fast case): */
196     if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) {
197 /* Computing MAX */
198         i__1 = vwin[(*af - 1 << 1) + 2] + 1;
199         vwin[(*af << 1) + 1] = max(i__1,*dvwinl);
200         vwin[(*af << 1) + 2] = vwin[(*af << 1) + 1] + *maxwin - 1;
201         *obound = 0;
202     } else {
203 /* Search backward in OSBUF for first onset in range. */
204 /* This code relies on the above check being performed first. */
205         for (q = osptr1 - 1; q >= 1; --q) {
206             if (osbuf[q] < lrange) {
207                 goto L100;
208             }
209         }
210 L100:
211         ++q;
212 /* Check for case 2 (placement before onset): */
213 /* Check for critical region exception: */
214         i__1 = osptr1 - 1;
215         for (i__ = q + 1; i__ <= i__1; ++i__) {
216             if (osbuf[i__] - osbuf[q] >= *minwin) {
217                 crit = TRUE_;
218                 goto L105;
219             }
220         }
221         crit = FALSE_;
222 L105:
223 /* Computing MAX */
224         i__1 = (*af - 1) * *lframe, i__2 = lrange + *minwin - 1;
225         if (! crit && osbuf[q] > max(i__1,i__2)) {
226             vwin[(*af << 1) + 2] = osbuf[q] - 1;
227 /* Computing MAX */
228             i__1 = lrange, i__2 = vwin[(*af << 1) + 2] - *maxwin + 1;
229             vwin[(*af << 1) + 1] = max(i__1,i__2);
230             *obound = 2;
231 /* Case 3 (placement after onset) */
232         } else {
233             vwin[(*af << 1) + 1] = osbuf[q];
234 L110:
235             ++q;
236             if (q >= osptr1) {
237                 goto L120;
238             }
239             if (osbuf[q] > vwin[(*af << 1) + 1] + *maxwin) {
240                 goto L120;
241             }
242             if (osbuf[q] < vwin[(*af << 1) + 1] + *minwin) {
243                 goto L110;
244             }
245             vwin[(*af << 1) + 2] = osbuf[q] - 1;
246             *obound = 3;
247             return 0;
248 L120:
249 /* Computing MIN */
250             i__1 = vwin[(*af << 1) + 1] + *maxwin - 1;
251             vwin[(*af << 1) + 2] = min(i__1,hrange);
252             *obound = 1;
253         }
254     }
255     return 0;
256 } /* placev_ */
257