voicin.c 28 KB

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