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

Linux/Unix编程

开发平台:

Visual C++

  1. /*
  2. $Log: voicin.c,v $
  3. Revision 1.1.1.1  2002/07/28 05:23:51  freeman_yong
  4. lpc10 codec
  5.  * Revision 1.2  1996/08/20  20:45:00  jaf
  6.  * Removed all static local variables that were SAVE'd in the Fortran
  7.  * code, and put them in struct lpc10_encoder_state that is passed as an
  8.  * argument.
  9.  *
  10.  * Removed init function, since all initialization is now done in
  11.  * init_lpc10_encoder_state().
  12.  *
  13.  * Revision 1.1  1996/08/19  22:30:14  jaf
  14.  * Initial revision
  15.  *
  16. */
  17. #ifdef P_R_O_T_O_T_Y_P_E_S
  18. extern int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af, struct lpc10_encoder_state *st);
  19. /* comlen contrl_ 12 */
  20. /*:ref: vparms_ 14 14 4 6 6 4 4 6 4 4 4 4 6 6 6 6 */
  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. /*  VOICIN Version 52 */
  35. /* $Log: voicin.c,v $
  36. /* Revision 1.1.1.1  2002/07/28 05:23:51  freeman_yong
  37. /* lpc10 codec
  38. /*
  39.  * Revision 1.2  1996/08/20  20:45:00  jaf
  40.  * Removed all static local variables that were SAVE'd in the Fortran
  41.  * code, and put them in struct lpc10_encoder_state that is passed as an
  42.  * argument.
  43.  *
  44.  * Removed init function, since all initialization is now done in
  45.  * init_lpc10_encoder_state().
  46.  *
  47.  * Revision 1.1  1996/08/19  22:30:14  jaf
  48.  * Initial revision
  49.  * */
  50. /* Revision 1.10  1996/03/29  17:59:14  jaf */
  51. /* Avoided using VALUE(9), although it shouldn't affect the function of */
  52. /* the code at all, because it was always multiplied by VDC(9,SNRL), */
  53. /* which is 0 for all values of SNRL.  Still, if VALUE(9) had an initial */
  54. /* value of IEEE NaN, it might cause trouble (I don't know how IEEE */
  55. /* defines Nan * 0.  It should either be NaN or 0.) */
  56. /* Revision 1.9  1996/03/29  17:54:46  jaf */
  57. /* Added a few comments about the accesses made to argument array VOIBUF */
  58. /* and the local saved array VOICE. */
  59. /* Revision 1.8  1996/03/27  18:19:54  jaf */
  60. /* Added an assignment to VSTATE that does not affect the function of the */
  61. /* program at all.  The only reason I put it in was so that the tracing */
  62. /* statements at the end, when enabled, will print a consistent value for */
  63. /* VSTATE when HALF .EQ. 1, rather than a garbage value that could change */
  64. /* from one call to the next. */
  65. /* Revision 1.7  1996/03/26  20:00:06  jaf */
  66. /* Removed the inclusion of the file "vcomm.fh", and put its contents */
  67. /* into this file.  It was included nowhere else but here. */
  68. /* Revision 1.6  1996/03/26  19:38:09  jaf */
  69. /* Commented out trace statements. */
  70. /* Revision 1.5  1996/03/19  20:43:45  jaf */
  71. /* Added comments about which indices of OBOUND and VOIBUF can be */
  72. /* accessed, and whether they are read or written.  VOIBUF is fairly */
  73. /* messy. */
  74. /* Revision 1.4  1996/03/19  15:00:58  jaf */
  75. /* Moved the DATA statements for the *VDC* variables later, as it is */
  76. /* apparently illegal to have DATA statements before local variable */
  77. /* declarations. */
  78. /* Revision 1.3  1996/03/19  00:10:49  jaf */
  79. /* Heavily commented the local variables that are saved from one */
  80. /* invocation to the next, and how the local variable FIRST is used to */
  81. /* avoid the need to assign most of them initial values with DATA */
  82. /* statements. */
  83. /* A few should be initialized, but aren't.  I've guessed initial values */
  84. /* for two of these, SFBUE and SLBUE, and I've convinced myself that for */
  85. /* VOICE, the effects of uninitialized values will die out after 2 or 3 */
  86. /* frame times.  It would still be good to choose initial values for */
  87. /* these, but I don't know what reasonable values would be (0 comes to */
  88. /* mind). */
  89. /* Revision 1.2  1996/03/13  16:09:28  jaf */
  90. /* Comments added explaining which of the local variables of this */
  91. /* subroutine need to be saved from one invocation to the next, and which */
  92. /* do not. */
  93. /* WARNING!  Some of them that should are never given initial values in */
  94. /* this code.  Hopefully, Fortran 77 defines initial values for them, but */
  95. /* even so, giving them explicit initial values is preferable. */
  96. /* WARNING!  VALUE(9) is used, but never assigned a value.  It should */
  97. /* probably be eliminated from the code. */
  98. /* Revision 1.1  1996/02/07 14:50:28  jaf */
  99. /* Initial revision */
  100. /****************************************************************************/
  101. /*        Voicing Detection (VOICIN) makes voicing decisions for each half */
  102. /*  frame of input speech.  Tentative voicing decisions are made two frames*/
  103. /*   in the future (2F) for each half frame.  These decisions are carried */
  104. /*   through one frame in the future (1F) to the present (P) frame where */
  105. /*   they are examined and smoothed, resulting in the final voicing */
  106. /*   decisions for each half frame. */
  107. /*        The voicing parameter (signal measurement) column vector (VALUE) */
  108. /*   is based on a rectangular window of speech samples determined by the */
  109. /*  window placement algorithm.  The voicing parameter vector contains the*/
  110. /*  AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*/
  111. /*   measures, reflection coefficients, and prediction gains.  The voicing */
  112. /*  window is placed to avoid contamination of the voicing parameter vector*/
  113. /*   with speech onsets. */
  114. /*        The input signal is then classified as unvoiced (including */
  115. /*   silence) or voiced.  This decision is made by a linear discriminant */
  116. /*   function consisting of a dot product of the voicing decision */
  117. /*   coefficient (VDC) row vector with the measurement column vector */
  118. /*  (VALUE).  The VDC vector is 2-dimensional, each row vector is optimized*/
  119. /*   for a particular signal-to-noise ratio (SNR).  So, before the dot */
  120. /*   product is performed, the SNR is estimated to select the appropriate */
  121. /*   VDC vector. */
  122. /*        The smoothing algorithm is a modified median smoother.  The */
  123. /*  voicing discriminant function is used by the smoother to determine how*/
  124. /*   strongly voiced or unvoiced a signal is.  The smoothing is further */
  125. /*   modified if a speech onset and a voicing decision transition occur */
  126. /*   within one half frame.  In this case, the voicing decision transition */
  127. /*  is extended to the speech onset.  For transmission purposes, there are*/
  128. /*   constraints on the duration and transition of voicing decisions.  The */
  129. /*   smoother takes these constraints into account. */
  130. /*        Finally, the energy estimates are updated along with the dither */
  131. /*   threshold used to calculate the zero crossing rate (ZC). */
  132. /* Inputs: */
  133. /*  VWIN      - Voicing window limits */
  134. /*              The indices read of arrays VWIN, INBUF, LPBUF, and BUFLIM */
  135. /*              are the same as those read by subroutine VPARMS. */
  136. /*  INBUF     - Input speech buffer */
  137. /*  LPBUF     - Low-pass filtered speech buffer */
  138. /*  BUFLIM    - INBUF and LPBUF limits */
  139. /*  HALF      - Present analysis half frame number */
  140. /*  MINAMD    - Minimum value of the AMDF */
  141. /*  MAXAMD    - Maximum value of the AMDF */
  142. /*  MINTAU    - Pointer to the lag of the minimum AMDF value */
  143. /*  IVRC(2)   - Inverse filter's RC's */
  144. /*              Only index 2 of array IVRC read under normal operation. */
  145. /*              (Index 1 is also read when debugging is turned on.) */
  146. /*  OBOUND    - Onset boundary descriptions */
  147. /*             Indices 1 through 3 read if (HALF .NE. 1), otherwise untouched.
  148. */
  149. /*  AF        - The analysis frame number */
  150. /* Output: */
  151. /*  VOIBUF(2,0:AF) - Buffer of voicing decisions */
  152. /*              Index (HALF,3) written. */
  153. /*              If (HALF .EQ. 1), skip down to "Read (HALF,3)" below. */
  154. /*              Indices (1,2), (2,1), (1,2), and (2,2) read. */
  155. /*              One of the following is then done: */
  156. /*                 read (1,3) and possibly write (1,2) */
  157. /*                 read (1,3) and write (1,2) or (2,2) */
  158. /*                 write (2,1) */
  159. /*                 write (2,1) or (1,2) */
  160. /*                 read (1,0) and (1,3) and then write (2,2) or (1,1) */
  161. /*                 no reads or writes on VOIBUF */
  162. /*              Finally, read (HALF,3) */
  163. /* Internal: */
  164. /*  QS        - Ratio of preemphasized to full-band energies */
  165. /*  RC1       - First reflection coefficient */
  166. /* AR_B      - Product of the causal forward and reverse pitch prediction gain
  167. s*/
  168. /* AR_F      - Product of the noncausal forward and rev. pitch prediction gain
  169. s*/
  170. /*  ZC        - Zero crossing rate */
  171. /*  DITHER    - Zero crossing threshold level */
  172. /*  MAXMIN    - AMDF's 1 octave windowed maximum-to-minimum ratio */
  173. /*  MINPTR    - Location  of minimum AMDF value */
  174. /*  NVDC      - Number of elements in each VDC vector */
  175. /*  NVDCL     - Number of VDC vectors */
  176. /*  VDCL      - SNR values corresponding to the set of VDC's */
  177. /*  VDC       - 2-D voicing decision coefficient vector */
  178. /*  VALUE(9)  - Voicing Parameters */
  179. /*  VOICE(2,3)- History of LDA results */
  180. /*              On every call when (HALF .EQ. 1), VOICE(*,I+1) is */
  181. /*              shifted back to VOICE(*,I), for I=1,2. */
  182. /*              VOICE(HALF,3) is written on every call. */
  183. /*              Depending on several conditions, one or more of */
  184. /*              (1,1), (1,2), (2,1), and (2,2) might then be read. */
  185. /*  LBE       - Ratio of low-band instantaneous to average energies */
  186. /*  FBE       - Ratio of full-band instantaneous to average energies */
  187. /*  LBVE      - Low band voiced energy */
  188. /*  LBUE      - Low band unvoiced energy */
  189. /*  FBVE      - Full band voiced energy */
  190. /*  FBUE      - Full band unvoiced energy */
  191. /*  OFBUE     - Previous full-band unvoiced energy */
  192. /*  OLBUE     - Previous low-band unvoiced energy */
  193. /*  REF       - Reference energy for initialization and DITHER threshold */
  194. /*  SNR       - Estimate of signal-to-noise ratio */
  195. /*  SNR2      - Estimate of low-band signal-to-noise ratio */
  196. /*  SNRL      - SNR level number */
  197. /*  OT        - Onset transition present */
  198. /*  VSTATE    - Decimal interpretation of binary voicing classifications */
  199. /*  FIRST     - First call flag */
  200. /* This subroutine maintains local state from one call to the next.  If */
  201. /* you want to switch to using a new audio stream for this filter, or */
  202. /* reinitialize its state for any other reason, call the ENTRY */
  203. /* INITVOICIN. */
  204. /* Subroutine */ int voicin_(integer *vwin, real *inbuf, real *
  205. lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, 
  206. integer *mintau, real *ivrc, integer *obound, integer *voibuf, 
  207. integer *af, struct lpc10_encoder_state *st)
  208. {
  209.     /* Initialized data */
  210.     real *dither;
  211.     static real vdc[100] /* was [10][10] */ = { 0.f,1714.f,-110.f,
  212.     334.f,-4096.f,-654.f,3752.f,3769.f,0.f,1181.f,0.f,874.f,-97.f,
  213.     300.f,-4096.f,-1021.f,2451.f,2527.f,0.f,-500.f,0.f,510.f,-70.f,
  214.     250.f,-4096.f,-1270.f,2194.f,2491.f,0.f,-1500.f,0.f,500.f,-10.f,
  215.     200.f,-4096.f,-1300.f,2e3f,2e3f,0.f,-2e3f,0.f,500.f,0.f,0.f,
  216.     -4096.f,-1300.f,2e3f,2e3f,0.f,-2500.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
  217.     0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
  218.     0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
  219.     0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f };
  220.     static integer nvdcl = 5;
  221.     static real vdcl[10] = { 600.f,450.f,300.f,200.f,0.f,0.f,0.f,0.f,0.f,0.f }
  222.     ;
  223.     /* System generated locals */
  224.     integer inbuf_offset, lpbuf_offset, i__1, i__2;
  225.     real r__1, r__2;
  226.     /* Builtin functions */
  227.     integer i_nint(real *);
  228.     double sqrt(doublereal);
  229.     /* Local variables */
  230.     real ar_b__, ar_f__;
  231.     integer *lbve, *lbue, *fbve, *fbue;
  232.     integer snrl, i__;
  233.     integer *ofbue, *sfbue;
  234.     real *voice;
  235.     integer *olbue, *slbue;
  236.     real value[9];
  237.     integer zc;
  238.     logical ot;
  239.     real qs;
  240.     real *maxmin;
  241.     integer vstate;
  242.     real rc1;
  243.     extern /* Subroutine */ int vparms_(integer *, real *, real *, integer *, 
  244.     integer *, real *, integer *, integer *, integer *, integer *, 
  245.     real *, real *, real *, real *);
  246.     integer fbe, lbe;
  247.     real *snr;
  248.     real snr2;
  249. /*  Global Variables: */
  250. /*       Arguments */
  251. /* $Log: voicin.c,v $
  252. /* Revision 1.1.1.1  2002/07/28 05:23:51  freeman_yong
  253. /* lpc10 codec
  254. /*
  255.  * Revision 1.2  1996/08/20  20:45:00  jaf
  256.  * Removed all static local variables that were SAVE'd in the Fortran
  257.  * code, and put them in struct lpc10_encoder_state that is passed as an
  258.  * argument.
  259.  *
  260.  * Removed init function, since all initialization is now done in
  261.  * init_lpc10_encoder_state().
  262.  *
  263.  * Revision 1.1  1996/08/19  22:30:14  jaf
  264.  * Initial revision
  265.  * */
  266. /* Revision 1.3  1996/03/29  22:05:55  jaf */
  267. /* Commented out the common block variables that are not needed by the */
  268. /* embedded version. */
  269. /* Revision 1.2  1996/03/26  19:34:50  jaf */
  270. /* Added comments indicating which constants are not needed in an */
  271. /* application that uses the LPC-10 coder. */
  272. /* Revision 1.1  1996/02/07  14:44:09  jaf */
  273. /* Initial revision */
  274. /*   LPC Processing control variables: */
  275. /* *** Read-only: initialized in setup */
  276. /*  Files for Speech, Parameter, and Bitstream Input & Output, */
  277. /*    and message and debug outputs. */
  278. /* Here are the only files which use these variables: */
  279. /* lpcsim.f setup.f trans.f error.f vqsetup.f */
  280. /* Many files which use fdebug are not listed, since it is only used in */
  281. /* those other files conditionally, to print trace statements. */
  282. /*  integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
  283. /*  LPC order, Frame size, Quantization rate, Bits per frame, */
  284. /*    Error correction */
  285. /* Subroutine SETUP is the only place where order is assigned a value, */
  286. /* and that value is 10.  It could increase efficiency 1% or so to */
  287. /* declare order as a constant (i.e., a Fortran PARAMETER) instead of as 
  288. */
  289. /* a variable in a COMMON block, since it is used in many places in the */
  290. /* core of the coding and decoding routines.  Actually, I take that back. 
  291. */
  292. /* At least when compiling with f2c, the upper bound of DO loops is */
  293. /* stored in a local variable before the DO loop begins, and then that is 
  294. */
  295. /* compared against on each iteration. */
  296. /* Similarly for lframe, which is given a value of MAXFRM in SETUP. */
  297. /* Similarly for quant, which is given a value of 2400 in SETUP.  quant */
  298. /* is used in only a few places, and never in the core coding and */
  299. /* decoding routines, so it could be eliminated entirely. */
  300. /* nbits is similar to quant, and is given a value of 54 in SETUP. */
  301. /* corrp is given a value of .TRUE. in SETUP, and is only used in the */
  302. /* subroutines ENCODE and DECODE.  It doesn't affect the speed of the */
  303. /* coder significantly whether it is .TRUE. or .FALSE., or whether it is 
  304. */
  305. /* a constant or a variable, since it is only examined once per frame. */
  306. /* Leaving it as a variable that is set to .TRUE.  seems like a good */
  307. /* idea, since it does enable some error-correction capability for */
  308. /* unvoiced frames, with no change in the coding rate, and no noticeable 
  309. */
  310. /* quality difference in the decoded speech. */
  311. /*  integer quant, nbits */
  312. /* *** Read/write: variables for debugging, not needed for LPC algorithm 
  313. */
  314. /*  Current frame, Unstable frames, Output clip count, Max onset buffer, 
  315. */
  316. /*    Debug listing detail level, Line count on listing page */
  317. /* nframe is not needed for an embedded LPC10 at all. */
  318. /* nunsfm is initialized to 0 in SETUP, and incremented in subroutine */
  319. /* ERROR, which is only called from RCCHK.  When LPC10 is embedded into */
  320. /* an application, I would recommend removing the call to ERROR in RCCHK, 
  321. */
  322. /* and remove ERROR and nunsfm completely. */
  323. /* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in 
  324. */
  325. /* sread.f.  When LPC10 is embedded into an application, one might want */
  326. /* to cause it to be incremented in a routine that takes the output of */
  327. /* SYNTHS and sends it to an audio device.  It could be optionally */
  328. /* displayed, for those that might want to know what it is. */
  329. /* maxosp is never initialized to 0 in SETUP, although it probably should 
  330. */
  331. /* be, and it is updated in subroutine ANALYS.  I doubt that its value */
  332. /* would be of much interest to an application in which LPC10 is */
  333. /* embedded. */
  334. /* listl and lincnt are not needed for an embedded LPC10 at all. */
  335. /*  integer nframe, nunsfm, iclip, maxosp, listl, lincnt */
  336. /*  common /contrl/ fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug */
  337. /*  common /contrl/ quant, nbits */
  338. /*  common /contrl/ nframe, nunsfm, iclip, maxosp, listl, lincnt */
  339. /*  Parameters/constants */
  340. /*       Voicing coefficient and Linear Discriminant Analysis variables: 
  341. */
  342. /*       Max number of VDC's and VDC levels */
  343. /*       The following are not Fortran PARAMETER's, but they are */
  344. /*       initialized with DATA statements, and never modified. */
  345. /*       Actual number of VDC's and levels */
  346. /*       Local variables that need not be saved */
  347. /*       Note: */
  348. /*       VALUE(1) through VALUE(8) are assigned values, but VALUE(9) */
  349. /*       never is.  Yet VALUE(9) is read in the loop that begins "DO I = 
  350. */
  351. /*       1, 9" below.  I believe that this doesn't cause any problems in 
  352. */
  353. /*       this subroutine, because all VDC(9,*) array elements are 0, and 
  354. */
  355. /*       this is what is multiplied by VALUE(9) in all cases.  Still, it 
  356. */
  357. /*       would save a multiplication to change the loop to "DO I = 1, 8". 
  358. */
  359. /*       Local state */
  360. /*       WARNING! */
  361. /*       VOICE, SFBUE, and SLBUE should be saved from one invocation to */
  362. /*       the next, but they are never given an initial value. */
  363. /*       Does Fortran 77 specify some default initial value, like 0, or */
  364. /*       is it undefined?  If it is undefined, then this code should be */
  365. /*       corrected to specify an initial value. */
  366. /*       For VOICE, note that it is "shifted" in the statement that */
  367. /*       begins "IF (HALF .EQ. 1) THEN" below.  Also, uninitialized */
  368. /*       values in the VOICE array can only affect entries in the VOIBUF 
  369. */
  370. /*       array that are for the same frame, or for an older frame.  Thus 
  371. */
  372. /*       the effects of uninitialized values in VOICE cannot linger on */
  373. /*       for more than 2 or 3 frame times. */
  374. /*       For SFBUE and SLBUE, the effects of uninitialized values can */
  375. /*       linger on for many frame times, because their previous values */
  376. /*       are exponentially decayed.  Thus it is more important to choose 
  377. */
  378. /*       initial values for these variables.  I would guess that a */
  379. /*       reasonable initial value for SFBUE is REF/16, the same as used */
  380. /*       for FBUE and OFBUE.  Similarly, SLBUE can be initialized to */
  381. /*       REF/32, the same as for LBUE and OLBUE. */
  382. /*       These guessed initial values should be validated by re-running */
  383. /*       the modified program on some audio samples. */
  384. /*   Declare and initialize filters: */
  385.     dither = (&st->dither);
  386.     snr = (&st->snr);
  387.     maxmin = (&st->maxmin);
  388.     voice = (&st->voice[0]);
  389.     lbve = (&st->lbve);
  390.     lbue = (&st->lbue);
  391.     fbve = (&st->fbve);
  392.     fbue = (&st->fbue);
  393.     ofbue = (&st->ofbue);
  394.     olbue = (&st->olbue);
  395.     sfbue = (&st->sfbue);
  396.     slbue = (&st->slbue);
  397.     /* Parameter adjustments */
  398.     if (vwin) {
  399. --vwin;
  400. }
  401.     if (buflim) {
  402. --buflim;
  403. }
  404.     if (inbuf) {
  405. inbuf_offset = buflim[1];
  406. inbuf -= inbuf_offset;
  407. }
  408.     if (lpbuf) {
  409. lpbuf_offset = buflim[3];
  410. lpbuf -= lpbuf_offset;
  411. }
  412.     if (ivrc) {
  413. --ivrc;
  414. }
  415.     if (obound) {
  416. --obound;
  417. }
  418.     if (voibuf) {
  419. --voibuf;
  420. }
  421.     /* Function Body */
  422. /*       The following variables are saved from one invocation to the */
  423. /*       next, but are not initialized with DATA statements.  This is */
  424. /*       acceptable, because FIRST is initialized ot .TRUE., and the */
  425. /*       first time that this subroutine is then called, they are all */
  426. /*       given initial values. */
  427. /*       SNR */
  428. /*       LBVE, LBUE, FBVE, FBUE, OFBUE, OLBUE */
  429. /*       MAXMIN is initialized on the first call, assuming that HALF */
  430. /*       .EQ. 1 on first call.  This is how ANALYS calls this subroutine. 
  431. */
  432. /*   Voicing Decision Parameter vector (* denotes zero coefficient): */
  433. /*  * MAXMIN */
  434. /*    LBE/LBVE */
  435. /*    ZC */
  436. /*    RC1 */
  437. /*    QS */
  438. /*    IVRC2 */
  439. /*    aR_B */
  440. /*    aR_F */
  441. /*  * LOG(LBE/LBVE) */
  442. /*  Define 2-D voicing decision coefficient vector according to the voicin
  443. g*/
  444. /*  parameter order above.  Each row (VDC vector) is optimized for a speci
  445. fic*/
  446. /*   SNR.  The last element of the vector is the constant. */
  447. /*           E    ZC    RC1    Qs   IVRC2  aRb   aRf        c */
  448. /*  The VOICE array contains the result of the linear discriminant functio
  449. n*/
  450. /*   (analog values).  The VOIBUF array contains the hard-limited binary 
  451. */
  452. /*   voicing decisions.  The VOICE and VOIBUF arrays, according to FORTRAN
  453.  */
  454. /*   memory allocation, are addressed as: */
  455. /*     (half-frame number, future-frame number) */
  456. /*     |   Past    |  Present  |  Future1  |  Future2  | */
  457. /*     | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 |  --->  time */
  458. /*   Update linear discriminant function history each frame: */
  459.     if (*half == 1) {
  460. voice[0] = voice[2];
  461. voice[1] = voice[3];
  462. voice[2] = voice[4];
  463. voice[3] = voice[5];
  464. *maxmin = *maxamd / max(*minamd,1.f);
  465.     }
  466. /*   Calculate voicing parameters twice per frame: */
  467.     vparms_(&vwin[1], &inbuf[inbuf_offset], &lpbuf[lpbuf_offset], &buflim[1], 
  468.     half, dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b__, &
  469.     ar_f__);
  470. /*   Estimate signal-to-noise ratio to select the appropriate VDC vector. 
  471. */
  472. /*   The SNR is estimated as the running average of the ratio of the */
  473. /*   running average full-band voiced energy to the running average */
  474. /*   full-band unvoiced energy. SNR filter has gain of 63. */
  475.     r__1 = (*snr + *fbve / (real) max(*fbue,1)) * 63 / 64.f;
  476.     *snr = (real) i_nint(&r__1);
  477.     snr2 = *snr * *fbue / max(*lbue,1);
  478. /*   Quantize SNR to SNRL according to VDCL thresholds. */
  479.     snrl = 1;
  480.     i__1 = nvdcl - 1;
  481.     for (snrl = 1; snrl <= i__1; ++snrl) {
  482. if (snr2 > vdcl[snrl - 1]) {
  483.     goto L69;
  484. }
  485.     }
  486. /*    (Note:  SNRL = NVDCL here) */
  487. L69:
  488. /*   Linear discriminant voicing parameters: */
  489.     value[0] = *maxmin;
  490.     value[1] = (real) lbe / max(*lbve,1);
  491.     value[2] = (real) zc;
  492.     value[3] = rc1;
  493.     value[4] = qs;
  494.     value[5] = ivrc[2];
  495.     value[6] = ar_b__;
  496.     value[7] = ar_f__;
  497. /*   Evaluation of linear discriminant function: */
  498.     voice[*half + 3] = vdc[snrl * 10 - 1];
  499.     for (i__ = 1; i__ <= 8; ++i__) {
  500. voice[*half + 3] += vdc[i__ + snrl * 10 - 11] * value[i__ - 1];
  501.     }
  502. /*   Classify as voiced if discriminant > 0, otherwise unvoiced */
  503. /*   Voicing decision for current half-frame:  1 = Voiced; 0 = Unvoiced */
  504.     if (voice[*half + 3] > 0.f) {
  505. voibuf[*half + 6] = 1;
  506.     } else {
  507. voibuf[*half + 6] = 0;
  508.     }
  509. /*   Skip voicing decision smoothing in first half-frame: */
  510. /*     Give a value to VSTATE, so that trace statements below will print 
  511. */
  512. /*     a consistent value from one call to the next when HALF .EQ. 1. */
  513. /*     The value of VSTATE is not used for any other purpose when this is 
  514. */
  515. /*     true. */
  516.     vstate = -1;
  517.     if (*half == 1) {
  518. goto L99;
  519.     }
  520. /*   Voicing decision smoothing rules (override of linear combination): */
  521. /*  Unvoiced half-frames:  At least two in a row. */
  522. /*  -------------------- */
  523. /*  Voiced half-frames:    At least two in a row in one frame. */
  524. /*  -------------------    Otherwise at least three in a row. */
  525. /*         (Due to the way transition frames are encoded) */
  526. /*  In many cases, the discriminant function determines how to smooth. */
  527. /* In the following chart, the decisions marked with a * may be overridden
  528. .*/
  529. /*   Voicing override of transitions at onsets: */
  530. /*  If a V/UV or UV/V voicing decision transition occurs within one-half 
  531. */
  532. /*  frame of an onset bounding a voicing window, then the transition is */
  533. /*  moved to occur at the onset. */
  534. /*  P 1F */
  535. /*  ----- ----- */
  536. /*  0   0   0   0 */
  537. /*  0   0   0*  1 (If there is an onset there) */
  538. /*  0   0   1*  0* (Based on 2F and discriminant distance) */
  539. /*  0   0   1   1 */
  540. /*  0   1*  0   0 (Always) */
  541. /*  0   1*  0*  1 (Based on discriminant distance) */
  542. /*  0*  1   1   0* (Based on past, 2F, and discriminant distance) */
  543. /*  0   1*  1   1 (If there is an onset there) */
  544. /*  1   0*  0   0 (If there is an onset there) */
  545. /*  1   0   0   1 */
  546. /*  1   0*  1*  0 (Based on discriminant distance) */
  547. /*  1   0*  1   1 (Always) */
  548. /*  1   1   0   0 */
  549. /*  1   1   0*  1* (Based on 2F and discriminant distance) */
  550. /*  1   1   1*  0 (If there is an onset there) */
  551. /*  1   1   1   1 */
  552. /*   Determine if there is an onset transition between P and 1F. */
  553. /*   OT (Onset Transition) is true if there is an onset between */
  554. /*   P and 1F but not after 1F. */
  555.     ot = ((obound[1] & 2) != 0 || obound[2] == 1) && (obound[3] & 1) == 0;
  556. /*   Multi-way dispatch on voicing decision history: */
  557.     vstate = (voibuf[3] << 3) + (voibuf[4] << 2) + (voibuf[5] << 1) + voibuf[
  558.     6];
  559.     switch (vstate + 1) {
  560. case 1:  goto L99;
  561. case 2:  goto L1;
  562. case 3:  goto L2;
  563. case 4:  goto L99;
  564. case 5:  goto L4;
  565. case 6:  goto L5;
  566. case 7:  goto L6;
  567. case 8:  goto L7;
  568. case 9:  goto L8;
  569. case 10:  goto L99;
  570. case 11:  goto L10;
  571. case 12:  goto L11;
  572. case 13:  goto L99;
  573. case 14:  goto L13;
  574. case 15:  goto L14;
  575. case 16:  goto L99;
  576.     }
  577. L1:
  578.     if (ot && voibuf[7] == 1) {
  579. voibuf[5] = 1;
  580.     }
  581.     goto L99;
  582. L2:
  583.     if (voibuf[7] == 0 || voice[2] < -voice[3]) {
  584. voibuf[5] = 0;
  585.     } else {
  586. voibuf[6] = 1;
  587.     }
  588.     goto L99;
  589. L4:
  590.     voibuf[4] = 0;
  591.     goto L99;
  592. L5:
  593.     if (voice[1] < -voice[2]) {
  594. voibuf[4] = 0;
  595.     } else {
  596. voibuf[5] = 1;
  597.     }
  598.     goto L99;
  599. /*   VOIBUF(2,0) must be 0 */
  600. L6:
  601.     if (voibuf[1] == 1 || voibuf[7] == 1 || voice[3] > voice[0]) {
  602. voibuf[6] = 1;
  603.     } else {
  604. voibuf[3] = 1;
  605.     }
  606.     goto L99;
  607. L7:
  608.     if (ot) {
  609. voibuf[4] = 0;
  610.     }
  611.     goto L99;
  612. L8:
  613.     if (ot) {
  614. voibuf[4] = 1;
  615.     }
  616.     goto L99;
  617. L10:
  618.     if (voice[2] < -voice[1]) {
  619. voibuf[5] = 0;
  620.     } else {
  621. voibuf[4] = 1;
  622.     }
  623.     goto L99;
  624. L11:
  625.     voibuf[4] = 1;
  626.     goto L99;
  627. L13:
  628.     if (voibuf[7] == 0 && voice[3] < -voice[2]) {
  629. voibuf[6] = 0;
  630.     } else {
  631. voibuf[5] = 1;
  632.     }
  633.     goto L99;
  634. L14:
  635.     if (ot && voibuf[7] == 0) {
  636. voibuf[5] = 0;
  637.     }
  638. /*  GOTO 99 */
  639. L99:
  640. /*   Now update parameters: */
  641. /*   ---------------------- */
  642. /*  During unvoiced half-frames, update the low band and full band unvoice
  643. d*/
  644. /*   energy estimates (LBUE and FBUE) and also the zero crossing */
  645. /*   threshold (DITHER).  (The input to the unvoiced energy filters is */
  646. /*   restricted to be less than 10dB above the previous inputs of the */
  647. /*   filters.) */
  648. /*   During voiced half-frames, update the low-pass (LBVE) and all-pass */
  649. /*   (FBVE) voiced energy estimates. */
  650.     if (voibuf[*half + 6] == 0) {
  651. /* Computing MIN */
  652. i__1 = fbe, i__2 = *ofbue * 3;
  653. r__1 = (*sfbue * 63 + (min(i__1,i__2) << 3)) / 64.f;
  654. *sfbue = i_nint(&r__1);
  655. *fbue = *sfbue / 8;
  656. *ofbue = fbe;
  657. /* Computing MIN */
  658. i__1 = lbe, i__2 = *olbue * 3;
  659. r__1 = (*slbue * 63 + (min(i__1,i__2) << 3)) / 64.f;
  660. *slbue = i_nint(&r__1);
  661. *lbue = *slbue / 8;
  662. *olbue = lbe;
  663.     } else {
  664. r__1 = (*lbve * 63 + lbe) / 64.f;
  665. *lbve = i_nint(&r__1);
  666. r__1 = (*fbve * 63 + fbe) / 64.f;
  667. *fbve = i_nint(&r__1);
  668.     }
  669. /*   Set dither threshold to yield proper zero crossing rates in the */
  670. /*   presence of low frequency noise and low level signal input. */
  671. /*   NOTE: The divisor is a function of REF, the expected energies. */
  672. /* Computing MIN */
  673. /* Computing MAX */
  674.     r__2 = sqrt((real) (*lbue * *lbve)) * 64 / 3000;
  675.     r__1 = max(r__2,1.f);
  676.     *dither = min(r__1,20.f);
  677. /*   Voicing decisions are returned in VOIBUF. */
  678.     return 0;
  679. } /* voicin_ */