1 /*
2 
3  * Revision 1.2  1996/08/20  20:42:59  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.
7  *
8  * Removed init function, since all initialization is now done in
9  * init_lpc10_decoder_state().
10  *
11  * Revision 1.1  1996/08/19  22:30:33  jaf
12  * Initial revision
13  *
14 
15 */
16 
17 /*  -- translated by f2c (version 19951025).
18    You must link the resulting object file with the libraries:
19 	-lf2c -lm   (in that order)
20 */
21 
22 #include "f2c.h"
23 
24 extern int synths_(integer *voice, integer *pitch, real *rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st);
25 
26 /* Common Block Declarations */
27 
28 extern struct {
29     integer order, lframe;
30     logical corrp;
31 } contrl_;
32 
33 #define contrl_1 contrl_
34 
35 /* Table of constant values */
36 
37 static real c_b2 = .7f;
38 
39 /* ***************************************************************** */
40 
41 /* 	SYNTHS Version 54 */
42 
43 /*
44  * Revision 1.2  1996/08/20  20:42:59  jaf
45  * Removed all static local variables that were SAVE'd in the Fortran
46  * code, and put them in struct lpc10_decoder_state that is passed as an
47  * argument.
48  *
49  * Removed init function, since all initialization is now done in
50  * init_lpc10_decoder_state().
51  *
52  * Revision 1.1  1996/08/19  22:30:33  jaf
53  * Initial revision
54  * */
55 /* Revision 1.5  1996/03/26  19:31:58  jaf */
56 /* Commented out trace statements. */
57 
58 /* Revision 1.4  1996/03/25  19:41:01  jaf */
59 /* Changed so that MAXFRM samples are always returned in the output array */
60 /* SPEECH. */
61 
62 /* This required delaying the returned samples by MAXFRM sample times, */
63 /* and remembering any "left over" samples returned by PITSYN from one */
64 /* call of SYNTHS to the next. */
65 
66 /* Changed size of SPEECH from 2*MAXFRM to MAXFRM.  Removed local */
67 /* variable SOUT.  Added local state variables BUF and BUFLEN. */
68 
69 /* Revision 1.3  1996/03/25  19:20:10  jaf */
70 /* Added comments about the range of possible return values for argument */
71 /* K, and increased the size of the arrays filled in by PITSYN from 11 to */
72 /* 16, as has been already done inside of PITSYN. */
73 
74 /* Revision 1.2  1996/03/22  00:18:18  jaf */
75 /* Added comments explaining meanings of input and output parameters, and */
76 /* indicating which array indices can be read or written. */
77 
78 /* Added entry INITSYNTHS, which does nothing except call the */
79 /* corresponding initialization entries for subroutines PITSYN, BSYNZ, */
80 /* and DEEMP. */
81 
82 /* Revision 1.1  1996/02/07 14:49:44  jaf */
83 /* Initial revision */
84 
85 
86 /* ***************************************************************** */
87 
88 /* The note below is from the distributed version of the LPC10 coder. */
89 /* The version of the code below has been modified so that SYNTHS always */
90 /* has a constant frame length output of MAXFRM. */
91 
92 /* Also, BSYNZ and DEEMP need not be modified to work on variable */
93 /* positions within an array.  It is only necessary to pass the first */
94 /* index desired as the array argument.  What actually gets passed is the */
95 /* address of that array position, which the subroutine treats as the */
96 /* first index of the array. */
97 
98 /* This technique is used in subroutine ANALYS when calling PREEMP, so it */
99 /* appears that multiple people wrote different parts of this LPC10 code, */
100 /* and that they didn't necessarily have equivalent knowledge of Fortran */
101 /* (not surprising). */
102 
103 /*  NOTE: There is excessive buffering here, BSYNZ and DEEMP should be */
104 /*        changed to operate on variable positions within SOUT.  Also, */
105 /*        the output length parameter is bogus, and PITSYN should be */
106 /*        rewritten to allow a constant frame length output. */
107 
108 /* Input: */
109 /*  VOICE  - Half frame voicing decisions */
110 /*           Indices 1 through 2 read. */
111 /* Input/Output: */
112 /*  PITCH  - Pitch */
113 /*           PITCH is restricted to range 20 to 156, inclusive, */
114 /*           before calling subroutine PITSYN, and then PITSYN */
115 /*           can modify it further under some conditions. */
116 /*  RMS    - Energy */
117 /*           Only use is for debugging, and passed to PITSYN. */
118 /*           See comments there for how it can be modified. */
119 /*  RC     - Reflection coefficients */
120 /*           Indices 1 through ORDER restricted to range -.99 to .99, */
121 /*           before calling subroutine PITSYN, and then PITSYN */
122 /*           can modify it further under some conditions. */
123 /* Output: */
124 /*  SPEECH - Synthesized speech samples. */
125 /*           Indices 1 through the final value of K are written. */
126 /*  K      - Number of samples placed into array SPEECH. */
127 /*           This is always MAXFRM. */
128 
synths_(integer * voice,integer * pitch,real * rms,real * rc,real * speech,integer * k,struct lpc10_decoder_state * st)129 /* Subroutine */ int synths_(integer *voice, integer *pitch, real *
130 	rms, real *rc, real *speech, integer *k, struct lpc10_decoder_state *st)
131 {
132     /* Initialized data */
133 
134     real *buf;
135     integer *buflen;
136 
137     /* System generated locals */
138     integer i__1;
139     real r__1, r__2;
140 
141     /* Local variables */
142     real rmsi[16];
143     integer nout, ivuv[16], i__, j;
144     extern /* Subroutine */ int deemp_(real *, integer *, struct lpc10_decoder_state *);
145     real ratio;
146     integer ipiti[16];
147     extern int bsynz_(real *, integer *,
148 	    integer *, real *, real *, real *, real *, struct lpc10_decoder_state *), irc2pc_(real *, real *
149 	    , integer *, real *, real *);
150     real g2pass;
151     real pc[10];
152     extern /* Subroutine */ int pitsyn_(integer *, integer *, integer *, real
153 	    *, real *, integer *, integer *, integer *, real *, real *,
154 	    integer *, real *, struct lpc10_decoder_state *);
155     real rci[160]	/* was [10][16] */;
156 
157 /*   LPC Configuration parameters: */
158 /* Frame size, Prediction order, Pitch period */
159 /*       Arguments */
160 
161 /*   LPC Processing control variables: */
162 
163 /* *** Read-only: initialized in setup */
164 
165 /*  Files for Speech, Parameter, and Bitstream Input & Output, */
166 /*    and message and debug outputs. */
167 
168 /* Here are the only files which use these variables: */
169 
170 /* lpcsim.f setup.f trans.f error.f vqsetup.f */
171 
172 /* Many files which use fdebug are not listed, since it is only used in */
173 /* those other files conditionally, to print trace statements. */
174 /* 	integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
175 /*  LPC order, Frame size, Quantization rate, Bits per frame, */
176 /*    Error correction */
177 /* Subroutine SETUP is the only place where order is assigned a value, */
178 /* and that value is 10.  It could increase efficiency 1% or so to */
179 /* declare order as a constant (i.e., a Fortran PARAMETER) instead of as
180 */
181 /* a variable in a COMMON block, since it is used in many places in the */
182 /* core of the coding and decoding routines.  Actually, I take that back.
183 */
184 /* At least when compiling with f2c, the upper bound of DO loops is */
185 /* stored in a local variable before the DO loop begins, and then that is
186 */
187 /* compared against on each iteration. */
188 /* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
189 /* Similarly for quant, which is given a value of 2400 in SETUP.  quant */
190 /* is used in only a few places, and never in the core coding and */
191 /* decoding routines, so it could be eliminated entirely. */
192 /* nbits is similar to quant, and is given a value of 54 in SETUP. */
193 /* corrp is given a value of .TRUE. in SETUP, and is only used in the */
194 /* subroutines ENCODE and DECODE.  It doesn't affect the speed of the */
195 /* coder significantly whether it is .TRUE. or .FALSE., or whether it is
196 */
197 /* a constant or a variable, since it is only examined once per frame. */
198 /* Leaving it as a variable that is set to .TRUE.  seems like a good */
199 /* idea, since it does enable some error-correction capability for */
200 /* unvoiced frames, with no change in the coding rate, and no noticeable
201 */
202 /* quality difference in the decoded speech. */
203 /* 	integer quant, nbits */
204 /* *** Read/write: variables for debugging, not needed for LPC algorithm
205 */
206 
207 /*  Current frame, Unstable frames, Output clip count, Max onset buffer,
208 */
209 /*    Debug listing detail level, Line count on listing page */
210 
211 /* nframe is not needed for an embedded LPC10 at all. */
212 /* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
213 /* ERROR, which is only called from RCCHK.  When LPC10 is embedded into */
214 /* an application, I would recommend removing the call to ERROR in RCCHK,
215 */
216 /* and remove ERROR and nunsfm completely. */
217 /* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in
218 */
219 /* sread.f.  When LPC10 is embedded into an application, one might want */
220 /* to cause it to be incremented in a routine that takes the output of */
221 /* SYNTHS and sends it to an audio device.  It could be optionally */
222 /* displayed, for those that might want to know what it is. */
223 /* maxosp is never initialized to 0 in SETUP, although it probably should
224 */
225 /* be, and it is updated in subroutine ANALYS.  I doubt that its value */
226 /* would be of much interest to an application in which LPC10 is */
227 /* embedded. */
228 /* listl and lincnt are not needed for an embedded LPC10 at all. */
229 /* 	integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
230 /* 	common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
231 /* 	common /contrl/ quant, nbits */
232 /* 	common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
233 /*       Parameters/constants */
234 /*       Local variables that need not be saved */
235 /*       Local state */
236 /*       BUF is a buffer of speech samples that would have been returned
237 */
238 /*       by the older version of SYNTHS, but the newer version doesn't, */
239 /*       so that the newer version can always return MAXFRM samples on */
240 /*       every call.  This has the effect of delaying the return of */
241 /*       samples for one additional frame time. */
242 
243 /*       Indices 1 through BUFLEN contain samples that are left over from
244 */
245 /*       the last call to SYNTHS.  Given the way that PITSYN works, */
246 /*       BUFLEN should always be in the range MAXFRM-MAXPIT+1 through */
247 /*       MAXFRM, inclusive, after a call to SYNTHS is complete. */
248 
249 /*       On the first call to SYNTHS (or the first call after */
250 /*       reinitializing with the entry INITSYNTHS), BUFLEN is MAXFRM, and
251 */
252 /*       a frame of silence is always returned. */
253     /* Parameter adjustments */
254     if (voice) {
255 	--voice;
256 	}
257     if (rc) {
258 	--rc;
259 	}
260     if (speech) {
261 	--speech;
262 	}
263 
264     /* Function Body */
265     buf = &(st->buf[0]);
266     buflen = &(st->buflen);
267 
268 /* Computing MAX */
269     i__1 = min(*pitch,156);
270     *pitch = max(i__1,20);
271     i__1 = contrl_1.order;
272     for (i__ = 1; i__ <= i__1; ++i__) {
273 /* Computing MAX */
274 /* Computing MIN */
275 	r__2 = rc[i__];
276 	r__1 = min(r__2,.99f);
277 	rc[i__] = max(r__1,-.99f);
278     }
279     pitsyn_(&contrl_1.order, &voice[1], pitch, rms, &rc[1], &contrl_1.lframe,
280 	    ivuv, ipiti, rmsi, rci, &nout, &ratio, st);
281     if (nout > 0) {
282 	i__1 = nout;
283 	for (j = 1; j <= i__1; ++j) {
284 
285 /*             Add synthesized speech for pitch period J to the en
286 d of */
287 /*             BUF. */
288 
289 	    irc2pc_(&rci[j * 10 - 10], pc, &contrl_1.order, &c_b2, &g2pass);
290 	    bsynz_(pc, &ipiti[j - 1], &ivuv[j - 1], &buf[*buflen], &rmsi[j - 1]
291 		    , &ratio, &g2pass, st);
292 	    deemp_(&buf[*buflen], &ipiti[j - 1], st);
293 	    *buflen += ipiti[j - 1];
294 	}
295 
296 /*          Copy first MAXFRM samples from BUF to output array SPEECH
297 */
298 /*          (scaling them), and then remove them from the beginning of
299  */
300 /*          BUF. */
301 
302 	for (i__ = 1; i__ <= 180; ++i__) {
303 	    speech[i__] = buf[i__ - 1] / 4096.f;
304 	}
305 	*k = 180;
306 	*buflen += -180;
307 	i__1 = *buflen;
308 	for (i__ = 1; i__ <= i__1; ++i__) {
309 	    buf[i__ - 1] = buf[i__ + 179];
310 	}
311     }
312     return 0;
313 } /* synths_ */
314