Asterisk - The Open Source Telephony Project  18.5.0
bsynz.c
Go to the documentation of this file.
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 {
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_ */
logical corrp
Definition: bsynz.c:47
integer lframe
Definition: bsynz.c:46
integer order
Definition: bsynz.c:46
real exc[166]
Definition: lpc10.h:176
double doublereal
Definition: f2c.h:50
#define contrl_1
Definition: bsynz.c:50
int bsynz_(real *coef, integer *ip, integer *iv, real *sout, real *rms, real *ratio, real *g2pass, struct lpc10_decoder_state *st)
Definition: bsynz.c:122
real exc2[166]
Definition: lpc10.h:177
float real
Definition: lpc10.h:79
INT32 logical
Definition: lpc10.h:81
integer random_(struct lpc10_decoder_state *st)
Definition: random.c:93
#define min(a, b)
Definition: f2c.h:197
INT32 integer
Definition: lpc10.h:80
struct @188 contrl_