build: fix symlink selection
[sox.git] / lpc10 / pitsyn.c
blobb987d4eacae049214a34136383cbb3817c0d660f
1 /*
3 * Revision 1.2 1996/08/20 20:40:12 jaf
4 * Removed all static local variables that were SAVE'd in the Fortran
5 * code, and put them in struct lpc10_decoder_state that is passed as an
6 * argument.
8 * Removed init function, since all initialization is now done in
9 * init_lpc10_decoder_state().
11 * Revision 1.1 1996/08/19 22:31:12 jaf
12 * Initial revision
17 /* -- translated by f2c (version 19951025).
18 You must link the resulting object file with the libraries:
19 -lf2c -lm (in that order)
22 #include "f2c.h"
24 extern int pitsyn_(integer *order, integer *voice, integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv, integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio, struct lpc10_decoder_state *st);
26 /* ***************************************************************** */
28 /* PITSYN Version 53 */
31 * Revision 1.2 1996/08/20 20:40:12 jaf
32 * Removed all static local variables that were SAVE'd in the Fortran
33 * code, and put them in struct lpc10_decoder_state that is passed as an
34 * argument.
36 * Removed init function, since all initialization is now done in
37 * init_lpc10_decoder_state().
39 * Revision 1.1 1996/08/19 22:31:12 jaf
40 * Initial revision
41 * */
42 /* Revision 1.2 1996/03/25 18:49:07 jaf */
43 /* Added commments about which indices of array arguments are read or */
44 /* written. */
46 /* Rearranged local variable declarations to indicate which need to be */
47 /* saved from one invocation to the next. Added entry INITPITSYN to */
48 /* reinitialize local state variables, if desired. */
50 /* Added lots of comments about proving that the maximum number of pitch */
51 /* periods (NOUT) that can be returned is 16. The call to STOP that */
52 /* could happen if NOUT got too large was removed as a result. */
54 /* Also proved that the total number of samples returned from N calls, */
55 /* each with identical values of LFRAME, will always be in the range */
56 /* N*LFRAME-MAXPIT+1 to N*LFRAME. */
58 /* Revision 1.1 1996/02/07 14:48:18 jaf */
59 /* Initial revision */
62 /* ***************************************************************** */
64 /* Synthesize a single pitch epoch */
66 /* Input: */
67 /* ORDER - Synthesis order (number of RC's) */
68 /* VOICE - Half frame voicing decisions */
69 /* Indices 1 through 2 read. */
70 /* LFRAME - Length of speech buffer */
71 /* Input/Output: */
72 /* PITCH - Pitch */
73 /* This value should be in the range MINPIT (20) to MAXPIT */
74 /* (156), inclusive. */
75 /* PITCH can be modified under some conditions. */
76 /* RMS - Energy (can be modified) */
77 /* RMS is changed to 1 if the value passed in is less than 1. */
78 /* RC - Reflection coefficients */
79 /* Indices 1 through ORDER can be temporarily overwritten with */
80 /* RCO, and then replaced with original values, under some */
81 /* conditions. */
82 /* Output: */
83 /* IVUV - Pitch epoch voicing decisions */
84 /* Indices (I) of IVUV, IPITI, and RMSI are written, */
85 /* and indices (J,I) of RCI are written, */
86 /* where I ranges from 1 to NOUT, and J ranges from 1 to ORDER. */
87 /* IPITI - Pitch epoch length */
88 /* RMSI - Pitch epoch energy */
89 /* RCI - Pitch epoch RC's */
90 /* NOUT - Number of pitch periods in this frame */
91 /* This is at least 0, at least 1 if MAXPIT .LT. LFRAME (this */
92 /* is currently true on every call), and can never be more than */
93 /* (LFRAME+MAXPIT-1)/PITCH, which is currently 16 with */
94 /* LFRAME=180, MAXPIT=156, and PITCH .GE. 20, as SYNTHS */
95 /* guarantees when it calls this subroutine. */
96 /* RATIO - Previous to present energy ratio */
97 /* Always assigned a value. */
99 /* Subroutine */ int pitsyn_(integer *order, integer *voice,
100 integer *pitch, real *rms, real *rc, integer *lframe, integer *ivuv,
101 integer *ipiti, real *rmsi, real *rci, integer *nout, real *ratio,
102 struct lpc10_decoder_state *st)
104 /* Initialized data */
106 real *rmso;
107 logical *first;
109 /* System generated locals */
110 integer rci_dim1 = 0, rci_offset, i__1, i__2;
111 real r__1;
113 /* Builtin functions */
114 double log(doublereal), exp(doublereal);
116 /* Local variables */
117 real alrn, alro, yarc[10], prop;
118 integer i__, j, vflag, jused, lsamp;
119 integer *jsamp;
120 real slope;
121 integer *ipito;
122 real uvpit;
123 integer ip, nl, ivoice;
124 integer *ivoico;
125 integer istart;
126 real *rco;
127 real xxy;
129 /* Arguments */
131 /* LPC Configuration parameters: */
132 /* Frame size, Prediction order, Pitch period */
133 /* Local variables that need not be saved */
134 /* LSAMP is initialized in the IF (FIRST) THEN clause, but it is */
135 /* not used the first time through, and it is given a value before
137 /* use whenever FIRST is .FALSE., so it appears unnecessary to */
138 /* assign it a value when FIRST is .TRUE. */
139 /* Local state */
140 /* FIRST - .TRUE. only on first call to PITSYN. */
141 /* IVOICO - Previous VOICE(2) value. */
142 /* IPITO - Previous PITCH value. */
143 /* RMSO - Previous RMS value. */
144 /* RCO - Previous RC values. */
146 /* JSAMP - If this routine is called N times with identical values of */
147 /* LFRAME, then the total length of all pitch periods returned */
148 /* is always N*LFRAME-JSAMP, and JSAMP is always in the range 0
150 /* to MAXPIT-1 (see below for why this is so). Thus JSAMP is */
151 /* the number of samples "left over" from the previous call to */
152 /* PITSYN, that haven't been "used" in a pitch period returned */
153 /* from this subroutine. Every time this subroutine is called,
155 /* it returns pitch periods with a total length of at most */
156 /* LFRAME+JSAMP. */
158 /* IVOICO, IPITO, RCO, and JSAMP need not be assigned an initial value */
159 /* with a DATA statement, because they are always initialized on the */
160 /* first call to PITSYN. */
162 /* FIRST and RMSO should be initialized with DATA statements, because */
163 /* even on the first call, they are used before being initialized. */
164 /* Parameter adjustments */
165 if (rc) {
166 --rc;
168 if (rci) {
169 rci_dim1 = *order;
170 rci_offset = rci_dim1 + 1;
171 rci -= rci_offset;
173 if (voice) {
174 --voice;
176 if (ivuv) {
177 --ivuv;
179 if (ipiti) {
180 --ipiti;
182 if (rmsi) {
183 --rmsi;
186 /* Function Body */
187 ivoico = &(st->ivoico);
188 ipito = &(st->ipito);
189 rmso = &(st->rmso);
190 rco = &(st->rco[0]);
191 jsamp = &(st->jsamp);
192 first = &(st->first_pitsyn);
194 if (*rms < 1.f) {
195 *rms = 1.f;
197 if (*rmso < 1.f) {
198 *rmso = 1.f;
200 uvpit = 0.f;
201 *ratio = *rms / (*rmso + 8.f);
202 if (*first) {
203 lsamp = 0;
204 ivoice = voice[2];
205 if (ivoice == 0) {
206 *pitch = *lframe / 4;
208 *nout = *lframe / *pitch;
209 *jsamp = *lframe - *nout * *pitch;
211 /* SYNTHS only calls this subroutine with PITCH in the range
212 20 */
213 /* to 156. LFRAME = MAXFRM = 180, so NOUT is somewhere in th
214 e */
215 /* range 1 to 9. */
217 /* JSAMP is "LFRAME mod PITCH", so it is in the range 0 to */
218 /* (PITCH-1), or 0 to MAXPIT-1=155, after the first call. */
220 i__1 = *nout;
221 for (i__ = 1; i__ <= i__1; ++i__) {
222 i__2 = *order;
223 for (j = 1; j <= i__2; ++j) {
224 rci[j + i__ * rci_dim1] = rc[j];
226 ivuv[i__] = ivoice;
227 ipiti[i__] = *pitch;
228 rmsi[i__] = *rms;
230 *first = FALSE_;
231 } else {
232 vflag = 0;
233 lsamp = *lframe + *jsamp;
234 slope = (*pitch - *ipito) / (real) lsamp;
235 *nout = 0;
236 jused = 0;
237 istart = 1;
238 if (voice[1] == *ivoico && voice[2] == voice[1]) {
239 if (voice[2] == 0) {
240 /* SSUV - - 0 , 0 , 0 */
241 *pitch = *lframe / 4;
242 *ipito = *pitch;
243 if (*ratio > 8.f) {
244 *rmso = *rms;
247 /* SSVC - - 1 , 1 , 1 */
248 slope = (*pitch - *ipito) / (real) lsamp;
249 ivoice = voice[2];
250 } else {
251 if (*ivoico != 1) {
252 if (*ivoico == voice[1]) {
253 /* UV2VC2 - - 0 , 0 , 1 */
254 nl = lsamp - *lframe / 4;
255 } else {
256 /* UV2VC1 - - 0 , 1 , 1 */
257 nl = lsamp - *lframe * 3 / 4;
259 ipiti[1] = nl / 2;
260 ipiti[2] = nl - ipiti[1];
261 ivuv[1] = 0;
262 ivuv[2] = 0;
263 rmsi[1] = *rmso;
264 rmsi[2] = *rmso;
265 i__1 = *order;
266 for (i__ = 1; i__ <= i__1; ++i__) {
267 rci[i__ + rci_dim1] = rco[i__ - 1];
268 rci[i__ + (rci_dim1 << 1)] = rco[i__ - 1];
269 rco[i__ - 1] = rc[i__];
271 slope = 0.f;
272 *nout = 2;
273 *ipito = *pitch;
274 jused = nl;
275 istart = nl + 1;
276 ivoice = 1;
277 } else {
278 if (*ivoico != voice[1]) {
279 /* VC2UV1 - - 1 , 0 , 0 */
280 lsamp = *lframe / 4 + *jsamp;
281 } else {
282 /* VC2UV2 - - 1 , 1 , 0 */
283 lsamp = *lframe * 3 / 4 + *jsamp;
285 i__1 = *order;
286 for (i__ = 1; i__ <= i__1; ++i__) {
287 yarc[i__ - 1] = rc[i__];
288 rc[i__] = rco[i__ - 1];
290 ivoice = 1;
291 slope = 0.f;
292 vflag = 1;
295 /* Here is the value of most variables that are used below, depending
296 on */
297 /* the values of IVOICO, VOICE(1), and VOICE(2). VOICE(1) and VOICE(2
298 ) */
299 /* are input arguments, and IVOICO is the value of VOICE(2) on the */
300 /* previous call (see notes for the IF (NOUT .NE. 0) statement near th
301 e */
302 /* end). Each of these three values is either 0 or 1. These three */
303 /* values below are given as 3-bit long strings, in the order IVOICO,
305 /* VOICE(1), and VOICE(2). It appears that the code above assumes tha
306 t */
307 /* the bit sequences 010 and 101 never occur, but I wonder whether a
309 /* large enough number of bit errors in the channel could cause such a
311 /* thing to happen, and if so, could that cause NOUT to ever go over 1
312 1? */
314 /* Note that all of the 180 values in the table are really LFRAME, but
316 /* 180 has fewer characters, and it makes the table a little more */
317 /* concrete. If LFRAME is ever changed, keep this in mind. Similarly
318 , */
319 /* 135's are 3*LFRAME/4, and 45's are LFRAME/4. If LFRAME is not a */
320 /* multiple of 4, then the 135 for NL-JSAMP is actually LFRAME-LFRAME/
321 4, */
322 /* and the 45 for NL-JSAMP is actually LFRAME-3*LFRAME/4. */
324 /* Note that LSAMP-JSAMP is given as the variable. This was just for
326 /* brevity, to avoid adding "+JSAMP" to all of the column entries. */
327 /* Similarly for NL-JSAMP. */
329 /* Variable | 000 001 011,010 111 110 100,101 */
330 /* ------------+-------------------------------------------------- */
331 /* ISTART | 1 NL+1 NL+1 1 1 1 */
332 /* LSAMP-JSAMP | 180 180 180 180 135 45 */
333 /* IPITO | 45 PITCH PITCH oldPITCH oldPITCH oldPITCH */
334 /* SLOPE | 0 0 0 seebelow 0 0 */
335 /* JUSED | 0 NL NL 0 0 0 */
336 /* PITCH | 45 PITCH PITCH PITCH PITCH PITCH */
337 /* NL-JSAMP | -- 135 45 -- -- -- */
338 /* VFLAG | 0 0 0 0 1 1 */
339 /* NOUT | 0 2 2 0 0 0 */
340 /* IVOICE | 0 1 1 1 1 1 */
342 /* while_loop | once once once once twice twice */
344 /* ISTART | -- -- -- -- JUSED+1 JUSED+1 */
345 /* LSAMP-JSAMP | -- -- -- -- 180 180 */
346 /* IPITO | -- -- -- -- oldPITCH oldPITCH */
347 /* SLOPE | -- -- -- -- 0 0 */
348 /* JUSED | -- -- -- -- ?? ?? */
349 /* PITCH | -- -- -- -- PITCH PITCH */
350 /* NL-JSAMP | -- -- -- -- -- -- */
351 /* VFLAG | -- -- -- -- 0 0 */
352 /* NOUT | -- -- -- -- ?? ?? */
353 /* IVOICE | -- -- -- -- 0 0 */
356 /* UVPIT is always 0.0 on the first pass through the DO WHILE (.TRUE.)
358 /* loop below. */
360 /* The only possible non-0 value of SLOPE (in column 111) is */
361 /* (PITCH-IPITO)/FLOAT(LSAMP) */
363 /* Column 101 is identical to 100. Any good properties we can prove
365 /* for 100 will also hold for 101. Similarly for 010 and 011. */
367 /* SYNTHS calls this subroutine with PITCH restricted to the range 20
368 to */
369 /* 156. IPITO is similarly restricted to this range, after the first
371 /* call. IP below is also restricted to this range, given the */
372 /* definitions of IPITO, SLOPE, UVPIT, and that I is in the range ISTA
373 RT */
374 /* to LSAMP. */
376 while(TRUE_) {
378 /* JUSED is the total length of all pitch periods curr
379 ently */
380 /* in the output arrays, in samples. */
382 /* An invariant of the DO I = ISTART,LSAMP loop below,
383 under */
384 /* the condition that IP is always in the range 1 thro
385 ugh */
386 /* MAXPIT, is: */
388 /* (I - MAXPIT) .LE. JUSED .LE. (I-1) */
390 /* Note that the final value of I is LSAMP+1, so that
391 after */
392 /* the DO loop is complete, we know: */
394 /* (LSAMP - MAXPIT + 1) .LE. JUSED .LE. LSAMP */
396 i__1 = lsamp;
397 for (i__ = istart; i__ <= i__1; ++i__) {
398 r__1 = *ipito + slope * i__;
399 ip = r__1 + .5f;
400 if (uvpit != 0.f) {
401 ip = uvpit;
403 if (ip <= i__ - jused) {
404 ++(*nout);
406 /* The following check is no longer nece
407 ssary, now that */
408 /* we can prove that NOUT will never go
409 over 16. */
411 /* IF (NOUT .GT. 16) STOP 'PITSYN: too many epochs'
414 ipiti[*nout] = ip;
415 *pitch = ip;
416 ivuv[*nout] = ivoice;
417 jused += ip;
418 prop = (jused - ip / 2) / (real) lsamp;
419 i__2 = *order;
420 for (j = 1; j <= i__2; ++j) {
421 alro = log((rco[j - 1] + 1) / (1 - rco[j - 1]));
422 alrn = log((rc[j] + 1) / (1 - rc[j]));
423 xxy = alro + prop * (alrn - alro);
424 xxy = exp(xxy);
425 rci[j + *nout * rci_dim1] = (xxy - 1) / (xxy + 1);
427 rmsi[*nout] = log(*rmso) + prop * (log(*rms) - log(*rmso));
428 rmsi[*nout] = exp(rmsi[*nout]);
431 if (vflag != 1) {
432 goto L100;
435 /* I want to prove what range UVPIT must lie in after
436 the */
437 /* assignments to it below. To do this, I must determ
438 ine */
439 /* what range (LSAMP-ISTART) must lie in, after the */
440 /* assignments to ISTART and LSAMP below. */
442 /* Let oldLSAMP be the value of LSAMP at this point in
443 the */
444 /* execution. This is 135+JSAMP in state 110, or 45+J
445 SAMP in */
446 /* states 100 or 101. */
448 /* Given the loop invariant on JUSED above, we know th
449 at: */
451 /* (oldLSAMP - MAXPIT + 1) .LE. JUSED .LE. oldLSAMP */
453 /* ISTART is one more than this. */
455 /* Let newLSAMP be the value assigned to LSAMP below.
456 This */
457 /* is 180+JSAMP. Thus (newLSAMP-oldLSAMP) is either 4
458 5 or */
459 /* 135, depending on the state. */
461 /* Thus, the range of newLSAMP-ISTART is: */
463 /* (newLSAMP-(oldLSAMP+1)) .LE. newLSAMP-ISTART */
464 /* .LE. (newLSAMP-(oldLSAMP - MAXPIT + 2)) */
466 /* or: */
468 /* 46 .LE. newLSAMP-ISTART .LE. 133+MAXPIT .EQ. 289 */
470 /* Therefore, UVPIT is in the range 23 to 144 after th
471 e first */
472 /* assignment to UVPIT below, and after the conditiona
473 l */
474 /* assignment, it is in the range 23 to 90. */
476 /* The important thing is that it is in the range 20 t
477 o 156, */
478 /* so that in the loop above, IP is always in this ran
479 ge. */
481 vflag = 0;
482 istart = jused + 1;
483 lsamp = *lframe + *jsamp;
484 slope = 0.f;
485 ivoice = 0;
486 uvpit = (real) ((lsamp - istart) / 2);
487 if (uvpit > 90.f) {
488 uvpit /= 2;
490 *rmso = *rms;
491 i__1 = *order;
492 for (i__ = 1; i__ <= i__1; ++i__) {
493 rc[i__] = yarc[i__ - 1];
494 rco[i__ - 1] = yarc[i__ - 1];
497 L100:
498 *jsamp = lsamp - jused;
500 /* Given that the maximum pitch period MAXPIT .LT. LFRAME (this is
502 /* currently true on every call, since SYNTHS always sets */
503 /* LFRAME=180), NOUT will always be .GE. 1 at this point. */
504 if (*nout != 0) {
505 *ivoico = voice[2];
506 *ipito = *pitch;
507 *rmso = *rms;
508 i__1 = *order;
509 for (i__ = 1; i__ <= i__1; ++i__) {
510 rco[i__ - 1] = rc[i__];
513 return 0;
514 } /* pitsyn_ */