bsynz.c
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:14k
源码类别:

Linux/Unix编程

开发平台:

Visual C++

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