bsynz.c 15 KB

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