Asterisk - The Open Source Telephony Project GIT-master-f36a736
bsynz.c
Go to the documentation of this file.
1/*
2
3$Log$
4Revision 1.15 2004/06/26 03:50:14 markster
5Merge source cleanups (bug #1911)
6
7Revision 1.14 2003/02/12 13:59:14 matteo
8mer feb 12 14:56:57 CET 2003
9
10Revision 1.1.1.1 2003/02/12 13:59:14 matteo
11mer feb 12 14:56:57 CET 2003
12
13Revision 1.2 2000/01/05 08:20:39 markster
14Some 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
38extern 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
45extern struct {
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
361at */
362/* least 32 bits (16 isn't enough), and PX should be in the rang
363e */
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
#define contrl_1
Definition: bsynz.c:50
struct @151 contrl_
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
integer order
Definition: bsynz.c:46
double doublereal
Definition: f2c.h:50
integer random_(struct lpc10_decoder_state *st)
Definition: random.c:93
#define min(a, b)
Definition: f2c.h:197
float real
Definition: lpc10.h:79
INT32 integer
Definition: lpc10.h:80
INT32 logical
Definition: lpc10.h:81
real exc[166]
Definition: lpc10.h:176
real exc2[166]
Definition: lpc10.h:177