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