Merge "res_pjsip_mwi: potential double unref, and potential unwanted double link"
[asterisk/asterisk.git] / codecs / lpc10 / bsynz.c
1 /*
2
3 $Log$
4 Revision 1.15  2004/06/26 03:50:14  markster
5 Merge source cleanups (bug #1911)
6
7 Revision 1.14  2003/02/12 13:59:14  matteo
8 mer feb 12 14:56:57 CET 2003
9
10 Revision 1.1.1.1  2003/02/12 13:59:14  matteo
11 mer feb 12 14:56:57 CET 2003
12
13 Revision 1.2  2000/01/05 08:20:39  markster
14 Some OSS fixes and a few lpc changes to make it actually work
15
16  * Revision 1.2  1996/08/20  20:18:55  jaf
17  * Removed all static local variables that were SAVE'd in the Fortran
18  * code, and put them in struct lpc10_decoder_state that is passed as an
19  * argument.
20  *
21  * Removed init function, since all initialization is now done in
22  * init_lpc10_decoder_state().
23  *
24  * Revision 1.1  1996/08/19  22:32:58  jaf
25  * Initial revision
26  *
27
28 */
29
30 /*  -- translated by f2c (version 19951025).
31    You must link the resulting object file with the libraries:
32         -lf2c -lm   (in that order)
33 */
34
35 #include "f2c.h"
36
37 #ifdef P_R_O_T_O_T_Y_P_E_S
38 extern int bsynz_(real *coef, integer *ip, integer *iv, real *sout, real *rms, real *ratio, real *g2pass, struct lpc10_decoder_state *st);
39 /* comlen contrl_ 12 */
40 /*:ref: random_ 4 0 */
41 #endif
42
43 /* Common Block Declarations */
44
45 extern struct {
46     integer order, lframe;
47     logical corrp;
48 } contrl_;
49
50 #define contrl_1 contrl_
51
52 /* ***************************************************************** */
53
54 /*      BSYNZ Version 54 */
55
56 /* $Log$
57  * Revision 1.15  2004/06/26 03:50:14  markster
58  * Merge source cleanups (bug #1911)
59  *
60  * Revision 1.14  2003/02/12 13:59:14  matteo
61  * mer feb 12 14:56:57 CET 2003
62  *
63  * Revision 1.1.1.1  2003/02/12 13:59:14  matteo
64  * mer feb 12 14:56:57 CET 2003
65  *
66  * Revision 1.2  2000/01/05 08:20:39  markster
67  * Some OSS fixes and a few lpc changes to make it actually work
68  *
69  * Revision 1.2  1996/08/20  20:18:55  jaf
70  * Removed all static local variables that were SAVE'd in the Fortran
71  * code, and put them in struct lpc10_decoder_state that is passed as an
72  * argument.
73  *
74  * Removed init function, since all initialization is now done in
75  * init_lpc10_decoder_state().
76  *
77  * Revision 1.1  1996/08/19  22:32:58  jaf
78  * Initial revision
79  * */
80 /* Revision 1.4  1996/03/27  18:11:22  jaf */
81 /* Changed the range of NOISE printed out in the debugging statements, */
82 /* even though they are commented out.  I didn't discover this until I */
83 /* tried comparing two different versions of the LPC-10 coder, each with */
84 /* full tracing enabled. */
85
86 /* Revision 1.3  1996/03/26  19:33:23  jaf */
87 /* Commented out trace statements. */
88
89 /* Revision 1.2  1996/03/20  17:12:54  jaf */
90 /* Added comments about which indices of array arguments are read or */
91 /* written. */
92
93 /* Rearranged local variable declarations to indicate which need to be */
94 /* saved from one invocation to the next.  Added entry INITBSYNZ to */
95 /* reinitialize the local state variables, if desired. */
96
97 /* Revision 1.1  1996/02/07 14:43:15  jaf */
98 /* Initial revision */
99
100
101 /* ***************************************************************** */
102
103 /*   Synthesize One Pitch Epoch */
104
105 /* Input: */
106 /*  COEF  - Predictor coefficients */
107 /*          Indices 1 through ORDER read. */
108 /*  IP    - Pitch period (number of samples to synthesize) */
109 /*  IV    - Voicing for the current epoch */
110 /*  RMS   - Energy for the current epoch */
111 /*  RATIO - Energy slope for plosives */
112 /*  G2PASS- Sharpening factor for 2 pass synthesis */
113 /* Output: */
114 /*  SOUT  - Synthesized speech */
115 /*          Indices 1 through IP written. */
116
117 /* This subroutine maintains local state from one call to the next.  If */
118 /* you want to switch to using a new audio stream for this filter, or */
119 /* reinitialize its state for any other reason, call the ENTRY */
120 /* INITBSYNZ. */
121
122 /* Subroutine */ int bsynz_(real *coef, integer *ip, integer *iv,
123         real *sout, real *rms, real *ratio, real *g2pass,
124                             struct lpc10_decoder_state *st)
125 {
126     /* Initialized data */
127
128     integer *ipo;
129     real *rmso;
130     static integer kexc[25] = { 8,-16,26,-48,86,-162,294,-502,718,-728,184,
131             672,-610,-672,184,728,718,502,294,162,86,48,26,16,8 };
132     real *exc;
133     real *exc2;
134     real *lpi1;
135     real *lpi2;
136     real *lpi3;
137     real *hpi1;
138     real *hpi2;
139     real *hpi3;
140
141     /* System generated locals */
142     integer i__1, i__2;
143     real r__1, r__2;
144
145     /* Builtin functions */
146     double sqrt(doublereal);
147
148     /* Local variables */
149     real gain, xssq;
150     integer i__, j, k;
151     real noise[166], pulse;
152     integer px;
153     real sscale;
154     extern integer random_(struct lpc10_decoder_state *);
155     real xy, sum, ssq;
156     real lpi0, hpi0;
157
158 /* $Log$
159  * Revision 1.15  2004/06/26 03:50:14  markster
160  * Merge source cleanups (bug #1911)
161  *
162  * Revision 1.14  2003/02/12 13:59:14  matteo
163  * mer feb 12 14:56:57 CET 2003
164  *
165  * Revision 1.1.1.1  2003/02/12 13:59:14  matteo
166  * mer feb 12 14:56:57 CET 2003
167  *
168  * Revision 1.2  2000/01/05 08:20:39  markster
169  * Some OSS fixes and a few lpc changes to make it actually work
170  *
171  * Revision 1.2  1996/08/20  20:18:55  jaf
172  * Removed all static local variables that were SAVE'd in the Fortran
173  * code, and put them in struct lpc10_decoder_state that is passed as an
174  * argument.
175  *
176  * Removed init function, since all initialization is now done in
177  * init_lpc10_decoder_state().
178  *
179  * Revision 1.1  1996/08/19  22:32:58  jaf
180  * Initial revision
181  * */
182 /* Revision 1.3  1996/03/29  22:03:47  jaf */
183 /* Removed definitions for any constants that were no longer used. */
184
185 /* Revision 1.2  1996/03/26  19:34:33  jaf */
186 /* Added comments indicating which constants are not needed in an */
187 /* application that uses the LPC-10 coder. */
188
189 /* Revision 1.1  1996/02/07  14:43:51  jaf */
190 /* Initial revision */
191
192 /*   LPC Configuration parameters: */
193 /* Frame size, Prediction order, Pitch period */
194 /*       Arguments */
195 /* $Log$
196  * Revision 1.15  2004/06/26 03:50:14  markster
197  * Merge source cleanups (bug #1911)
198  *
199  * Revision 1.14  2003/02/12 13:59:14  matteo
200  * mer feb 12 14:56:57 CET 2003
201  *
202  * Revision 1.1.1.1  2003/02/12 13:59:14  matteo
203  * mer feb 12 14:56:57 CET 2003
204  *
205  * Revision 1.2  2000/01/05 08:20:39  markster
206  * Some OSS fixes and a few lpc changes to make it actually work
207  *
208  * Revision 1.2  1996/08/20  20:18:55  jaf
209  * Removed all static local variables that were SAVE'd in the Fortran
210  * code, and put them in struct lpc10_decoder_state that is passed as an
211  * argument.
212  *
213  * Removed init function, since all initialization is now done in
214  * init_lpc10_decoder_state().
215  *
216  * Revision 1.1  1996/08/19  22:32:58  jaf
217  * Initial revision
218  * */
219 /* Revision 1.3  1996/03/29  22:05:55  jaf */
220 /* Commented out the common block variables that are not needed by the */
221 /* embedded version. */
222
223 /* Revision 1.2  1996/03/26  19:34:50  jaf */
224 /* Added comments indicating which constants are not needed in an */
225 /* application that uses the LPC-10 coder. */
226
227 /* Revision 1.1  1996/02/07  14:44:09  jaf */
228 /* Initial revision */
229
230 /*   LPC Processing control variables: */
231
232 /* *** Read-only: initialized in setup */
233
234 /*  Files for Speech, Parameter, and Bitstream Input & Output, */
235 /*    and message and debug outputs. */
236
237 /* Here are the only files which use these variables: */
238
239 /* lpcsim.f setup.f trans.f error.f vqsetup.f */
240
241 /* Many files which use fdebug are not listed, since it is only used in */
242 /* those other files conditionally, to print trace statements. */
243 /*      integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
244 /*  LPC order, Frame size, Quantization rate, Bits per frame, */
245 /*    Error correction */
246 /* Subroutine SETUP is the only place where order is assigned a value, */
247 /* and that value is 10.  It could increase efficiency 1% or so to */
248 /* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
249 */
250 /* a variable in a COMMON block, since it is used in many places in the */
251 /* core of the coding and decoding routines.  Actually, I take that back.
252 */
253 /* At least when compiling with f2c, the upper bound of DO loops is */
254 /* stored in a local variable before the DO loop begins, and then that is
255 */
256 /* compared against on each iteration. */
257 /* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
258 /* Similarly for quant, which is given a value of 2400 in SETUP.  quant */
259 /* is used in only a few places, and never in the core coding and */
260 /* decoding routines, so it could be eliminated entirely. */
261 /* nbits is similar to quant, and is given a value of 54 in SETUP. */
262 /* corrp is given a value of .TRUE. in SETUP, and is only used in the */
263 /* subroutines ENCODE and DECODE.  It doesn't affect the speed of the */
264 /* coder significantly whether it is .TRUE. or .FALSE., or whether it is
265 */
266 /* a constant or a variable, since it is only examined once per frame. */
267 /* Leaving it as a variable that is set to .TRUE.  seems like a good */
268 /* idea, since it does enable some error-correction capability for */
269 /* unvoiced frames, with no change in the coding rate, and no noticeable
270 */
271 /* quality difference in the decoded speech. */
272 /*      integer quant, nbits */
273 /* *** Read/write: variables for debugging, not needed for LPC algorithm
274 */
275
276 /*  Current frame, Unstable frames, Output clip count, Max onset buffer,
277 */
278 /*    Debug listing detail level, Line count on listing page */
279
280 /* nframe is not needed for an embedded LPC10 at all. */
281 /* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
282 /* ERROR, which is only called from RCCHK.  When LPC10 is embedded into */
283 /* an application, I would recommend removing the call to ERROR in RCCHK,
284 */
285 /* and remove ERROR and nunsfm completely. */
286 /* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
287 */
288 /* sread.f.  When LPC10 is embedded into an application, one might want */
289 /* to cause it to be incremented in a routine that takes the output of */
290 /* SYNTHS and sends it to an audio device.  It could be optionally */
291 /* displayed, for those that might want to know what it is. */
292 /* maxosp is never initialized to 0 in SETUP, although it probably should
293 */
294 /* be, and it is updated in subroutine ANALYS.  I doubt that its value */
295 /* would be of much interest to an application in which LPC10 is */
296 /* embedded. */
297 /* listl and lincnt are not needed for an embedded LPC10 at all. */
298 /*      integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
299 /*      common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
300 /*      common /contrl/ quant, nbits */
301 /*      common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
302 /*       Function return value definitions */
303 /*      Parameters/constants */
304 /*       KEXC is not a Fortran PARAMETER, but it is an array initialized
305 */
306 /*       with a DATA statement that is never modified. */
307 /*       Local variables that need not be saved */
308 /*       NOISE is declared with range (1:MAXPIT+MAXORD), but only indices
309 */
310 /*       ORDER+1 through ORDER+IP are ever used, and I think that IP */
311 /*       .LE. MAXPIT.  Why not declare it to be in the range (1:MAXPIT) */
312 /*       and use that range? */
313 /*       Local state */
314 /*       I believe that only indices 1 through ORDER of EXC need to be */
315 /*       saved from one invocation to the next, but we may as well save */
316 /*       the whole array. */
317 /*       None of these local variables were given initial values in the */
318 /*       original code.  I'm guessing that 0 is a reasonable initial */
319 /*       value for all of them. */
320     /* Parameter adjustments */
321     if (coef) {
322         --coef;
323         }
324     if (sout) {
325         --sout;
326         }
327
328     /* Function Body */
329     ipo = &(st->ipo);
330     exc = &(st->exc[0]);
331     exc2 = &(st->exc2[0]);
332     lpi1 = &(st->lpi1);
333     lpi2 = &(st->lpi2);
334     lpi3 = &(st->lpi3);
335     hpi1 = &(st->hpi1);
336     hpi2 = &(st->hpi2);
337     hpi3 = &(st->hpi3);
338     rmso = &(st->rmso_bsynz);
339
340 /*                  MAXPIT+MAXORD=166 */
341 /*  Calculate history scale factor XY and scale filter state */
342 /* Computing MIN */
343     r__1 = *rmso / (*rms + 1e-6f);
344     xy = min(r__1,8.f);
345     *rmso = *rms;
346     i__1 = contrl_1.order;
347     for (i__ = 1; i__ <= i__1; ++i__) {
348         exc2[i__ - 1] = exc2[*ipo + i__ - 1] * xy;
349     }
350     *ipo = *ip;
351     if (*iv == 0) {
352 /*  Generate white noise for unvoiced */
353         i__1 = *ip;
354         for (i__ = 1; i__ <= i__1; ++i__) {
355             exc[contrl_1.order + i__ - 1] = (real) (random_(st) / 64);
356         }
357 /*  Impulse doublet excitation for plosives */
358 /*       (RANDOM()+32768) is in the range 0 to 2**16-1.  Therefore the
359  */
360 /*       following expression should be evaluated using integers with
361 at */
362 /*       least 32 bits (16 isn't enough), and PX should be in the rang
363 e */
364 /*       ORDER+1+0 through ORDER+1+(IP-2) .EQ. ORDER+IP-1. */
365         px = (random_(st) + 32768) * (*ip - 1) / 65536 + contrl_1.order + 1;
366         r__1 = *ratio / 4 * 1.f;
367         pulse = r__1 * 342;
368         if (pulse > 2e3f) {
369             pulse = 2e3f;
370         }
371         exc[px - 1] += pulse;
372         exc[px] -= pulse;
373 /*  Load voiced excitation */
374     } else {
375         sscale = (real)sqrt((real) (*ip)) / 6.928f;
376         i__1 = *ip;
377         for (i__ = 1; i__ <= i__1; ++i__) {
378             exc[contrl_1.order + i__ - 1] = 0.f;
379             if (i__ <= 25) {
380                 exc[contrl_1.order + i__ - 1] = sscale * kexc[i__ - 1];
381             }
382             lpi0 = exc[contrl_1.order + i__ - 1];
383             r__2 = exc[contrl_1.order + i__ - 1] * .125f + *lpi1 * .75f;
384             r__1 = r__2 + *lpi2 * .125f;
385             exc[contrl_1.order + i__ - 1] = r__1 + *lpi3 * 0.f;
386             *lpi3 = *lpi2;
387             *lpi2 = *lpi1;
388             *lpi1 = lpi0;
389         }
390         i__1 = *ip;
391         for (i__ = 1; i__ <= i__1; ++i__) {
392             noise[contrl_1.order + i__ - 1] = random_(st) * 1.f / 64;
393             hpi0 = noise[contrl_1.order + i__ - 1];
394             r__2 = noise[contrl_1.order + i__ - 1] * -.125f + *hpi1 * .25f;
395             r__1 = r__2 + *hpi2 * -.125f;
396             noise[contrl_1.order + i__ - 1] = r__1 + *hpi3 * 0.f;
397             *hpi3 = *hpi2;
398             *hpi2 = *hpi1;
399             *hpi1 = hpi0;
400         }
401         i__1 = *ip;
402         for (i__ = 1; i__ <= i__1; ++i__) {
403             exc[contrl_1.order + i__ - 1] += noise[contrl_1.order + i__ - 1];
404         }
405     }
406 /*   Synthesis filters: */
407 /*    Modify the excitation with all-zero filter  1 + G*SUM */
408     xssq = 0.f;
409     i__1 = *ip;
410     for (i__ = 1; i__ <= i__1; ++i__) {
411         k = contrl_1.order + i__;
412         sum = 0.f;
413         i__2 = contrl_1.order;
414         for (j = 1; j <= i__2; ++j) {
415             sum += coef[j] * exc[k - j - 1];
416         }
417         sum *= *g2pass;
418         exc2[k - 1] = sum + exc[k - 1];
419     }
420 /*   Synthesize using the all pole filter  1 / (1 - SUM) */
421     i__1 = *ip;
422     for (i__ = 1; i__ <= i__1; ++i__) {
423         k = contrl_1.order + i__;
424         sum = 0.f;
425         i__2 = contrl_1.order;
426         for (j = 1; j <= i__2; ++j) {
427             sum += coef[j] * exc2[k - j - 1];
428         }
429         exc2[k - 1] = sum + exc2[k - 1];
430         xssq += exc2[k - 1] * exc2[k - 1];
431     }
432 /*  Save filter history for next epoch */
433     i__1 = contrl_1.order;
434     for (i__ = 1; i__ <= i__1; ++i__) {
435         exc[i__ - 1] = exc[*ip + i__ - 1];
436         exc2[i__ - 1] = exc2[*ip + i__ - 1];
437     }
438 /*  Apply gain to match RMS */
439     r__1 = *rms * *rms;
440     ssq = r__1 * *ip;
441     gain = (real)sqrt(ssq / xssq);
442     i__1 = *ip;
443     for (i__ = 1; i__ <= i__1; ++i__) {
444         sout[i__] = gain * exc2[contrl_1.order + i__ - 1];
445     }
446     return 0;
447 } /* bsynz_ */