onset.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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:15 matteo
  6. mer feb 12 14:56:57 CET 2003
  7. Revision 1.1.1.1 2003/02/12 13:59:15 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:37:55 jaf
  12. * Removed all static local variables that were SAVE'd in the Fortran
  13. * code, and put them in struct lpc10_encoder_state that is passed as an
  14. * argument.
  15. *
  16. * Removed init function, since all initialization is now done in
  17. * init_lpc10_encoder_state().
  18. *
  19. * Revision 1.1 1996/08/19 22:31:18 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 onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st);
  30. #endif
  31. /* Table of constant values */
  32. static real c_b2 = 1.f;
  33. /* ****************************************************************** */
  34. /* ONSET Version 49 */
  35. /* $Log$
  36. * Revision 1.15 2004/06/26 03:50:14 markster
  37. * Merge source cleanups (bug #1911)
  38. *
  39. * Revision 1.14 2003/02/12 13:59:15 matteo
  40. * mer feb 12 14:56:57 CET 2003
  41. *
  42. * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
  43. * mer feb 12 14:56:57 CET 2003
  44. *
  45. * Revision 1.2 2000/01/05 08:20:39 markster
  46. * Some OSS fixes and a few lpc changes to make it actually work
  47. *
  48. * Revision 1.2 1996/08/20 20:37:55 jaf
  49. * Removed all static local variables that were SAVE'd in the Fortran
  50. * code, and put them in struct lpc10_encoder_state that is passed as an
  51. * argument.
  52. *
  53. * Removed init function, since all initialization is now done in
  54. * init_lpc10_encoder_state().
  55. *
  56. * Revision 1.1 1996/08/19 22:31:18 jaf
  57. * Initial revision
  58. * */
  59. /* Revision 1.5 1996/03/15 16:41:01 jaf */
  60. /* Just rearranged INITONSET assignment orders to be consistent with */
  61. /* order of DATA statements in ONSET. */
  62. /* Revision 1.4 1996/03/15 15:48:27 jaf */
  63. /* Changed some comments, and only reordered the DATA statements (their */
  64. /* meaning wasn't changed). */
  65. /* Revision 1.3 1996/03/14 23:53:06 jaf */
  66. /* Added an entry INITONSET that reinitializes the local state variables */
  67. /* of subroutine ONSET. */
  68. /* Rearranged quite a few comments, adding more explaining which */
  69. /* arguments were inputs, and how the modified ones can be changed. */
  70. /* Revision 1.2 1996/03/12 23:53:00 jaf */
  71. /* Lots of comments added about the local state of this subroutine that */
  72. /* must be saved from one invocation to the next. */
  73. /* One constant 180 replaced with LFRAME, which should be "more general", */
  74. /* even though it would probably require many more changes than this to */
  75. /* get this coder to work for other frame sizes. */
  76. /* Revision 1.1 1996/02/07 14:48:09 jaf */
  77. /* Initial revision */
  78. /* ****************************************************************** */
  79. /* Floating point version */
  80. /* Detection of onsets in (or slightly preceding) the futuremost frame */
  81. /* of speech. */
  82. /* Input: */
  83. /* PEBUF(SBUFL:SBUFH) - Preemphasized speech */
  84. /* Indices SBUFH-LFRAME through SBUFH are read. */
  85. /* OSLEN - Maximum number of onsets that can be stored in OSBUF. */
  86. /* SBUFL, SBUFH - Range of PEBUF */
  87. /* LFRAME - length of a frame, in samples */
  88. /* Input/Output: */
  89. /* OSBUF(OSLEN) - Buffer which holds sorted indexes of onsets */
  90. /* Indices A through B are modified, where A */
  91. /* is the original value of OSPTR, and B is the final */
  92. /* value of OSPTR-1. B is at most OSLEN. */
  93. /* OSPTR - Free pointer into OSBUF */
  94. /* Initial value should be .LE. OSLEN+1. */
  95. /* If so, final value grows by one for each new onset */
  96. /* found, and final value will be .LE. OSLEN+1. */
  97. /* This subroutine maintains local state from one call to the next. If */
  98. /* you want to switch to using a new audio stream for this subroutine, or */
  99. /* reinitialize its state for any other reason, call the ENTRY INITONSET. */
  100. /* Subroutine */ int onset_(real *pebuf, integer *osbuf, integer *
  101. osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *
  102. lframe, struct lpc10_encoder_state *st)
  103. {
  104. /* Initialized data */
  105. real *n;
  106. real *d__;
  107. real *l2buf;
  108. real *l2sum1;
  109. integer *l2ptr1;
  110. integer *l2ptr2;
  111. logical *hyst;
  112. /* System generated locals */
  113. integer pebuf_offset, i__1;
  114. real r__1;
  115. /* Builtin functions */
  116. double r_sign(real *, real *);
  117. /* Local variables */
  118. integer i__;
  119. integer *lasti;
  120. real l2sum2;
  121. real *fpc;
  122. /* Arguments */
  123. /* $Log$
  124. * Revision 1.15 2004/06/26 03:50:14 markster
  125. * Merge source cleanups (bug #1911)
  126. *
  127. * Revision 1.14 2003/02/12 13:59:15 matteo
  128. * mer feb 12 14:56:57 CET 2003
  129. *
  130. * Revision 1.1.1.1 2003/02/12 13:59:15 matteo
  131. * mer feb 12 14:56:57 CET 2003
  132. *
  133. * Revision 1.2 2000/01/05 08:20:39 markster
  134. * Some OSS fixes and a few lpc changes to make it actually work
  135. *
  136. * Revision 1.2 1996/08/20 20:37:55 jaf
  137. * Removed all static local variables that were SAVE'd in the Fortran
  138. * code, and put them in struct lpc10_encoder_state that is passed as an
  139. * argument.
  140. *
  141. * Removed init function, since all initialization is now done in
  142. * init_lpc10_encoder_state().
  143. *
  144. * Revision 1.1 1996/08/19 22:31:18 jaf
  145. * Initial revision
  146. * */
  147. /* Revision 1.3 1996/03/29 22:03:47 jaf */
  148. /* Removed definitions for any constants that were no longer used. */
  149. /* Revision 1.2 1996/03/26 19:34:33 jaf */
  150. /* Added comments indicating which constants are not needed in an */
  151. /* application that uses the LPC-10 coder. */
  152. /* Revision 1.1 1996/02/07 14:43:51 jaf */
  153. /* Initial revision */
  154. /* LPC Configuration parameters: */
  155. /* Frame size, Prediction order, Pitch period */
  156. /* Parameters/constants */
  157. /* Parameters for onset detection algorithm: */
  158. /* L2 Threshold for filtered slope of FPC (function of L2WID!) */
  159. /* L2LAG Lag due to both filters which compute filtered slope of FPC */
  160. /* L2WID Width of the filter which computes the slope of FPC */
  161. /* OSHYST The number of samples of slope(FPC) which must be below */
  162. /* the threshold before a new onset may be declared. */
  163. /* Local variables that need not be saved */
  164. /* Local state */
  165. /* Variables */
  166. /* N, D Numerator and denominator of prediction filters */
  167. /* FPC Current prediction coefs */
  168. /* L2BUF, L2SUM1, L2SUM2 State of slope filter */
  169. /* The only "significant" change I've made is to change L2SUM2 out
  170. */
  171. /* of the list of local variables that need to be saved, since it */
  172. /* didn't need to be. */
  173. /* L2SUM1 need not be, but avoiding saving it would require a small
  174. */
  175. /* change to the body of the code. See comments below for an */
  176. /* example of how the code could be changed to avoid saving L2SUM1.
  177. */
  178. /* FPC and LASTI are saved from one invocation to the next, but */
  179. /* they are not given initial values. This is acceptable, because
  180. */
  181. /* FPC will be assigned a value the first time that this function */
  182. /* is called after D is initialized to 1, since the formula to */
  183. /* change D will not change it to 0 in one step, and the IF (D */
  184. /* .NE. 0) statement will execute its THEN part, initializing FPC.
  185. */
  186. /* LASTI's value will not be used until HYST is .TRUE., and */
  187. /* whenever HYST is changed from its initial value of .FALSE., */
  188. /* LASTI is assigned a value. */
  189. /* In a C version of this coder, it would be nice if all of these */
  190. /* saved things, in this and all other subroutines, could be stored
  191. */
  192. /* in a single struct lpc10_coder_state_t, initialized with a call
  193. */
  194. /* to a function like lpc10_init(&lpc10_coder_state). In this way,
  195. */
  196. /* a program that used these functions could conveniently alternate
  197. */
  198. /* coding more than one distinct audio stream. */
  199. n = &(st->n);
  200. d__ = &(st->d__);
  201. fpc = &(st->fpc);
  202. l2buf = &(st->l2buf[0]);
  203. l2sum1 = &(st->l2sum1);
  204. l2ptr1 = &(st->l2ptr1);
  205. l2ptr2 = &(st->l2ptr2);
  206. lasti = &(st->lasti);
  207. hyst = &(st->hyst);
  208. /* Parameter adjustments */
  209. if (osbuf) {
  210. --osbuf;
  211. }
  212. if (pebuf) {
  213. pebuf_offset = *sbufl;
  214. pebuf -= pebuf_offset;
  215. }
  216. /* Function Body */
  217. /* The following line subtracted a hard-coded "180" from LASTI, */
  218. /* instead of using a variable like LFRAME or a constant like */
  219. /* MAXFRM. I changed it to LFRAME, for "generality". */
  220. if (*hyst) {
  221. *lasti -= *lframe;
  222. }
  223. i__1 = *sbufh;
  224. for (i__ = *sbufh - *lframe + 1; i__ <= i__1; ++i__) {
  225. /* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1.
  226. */
  227. *n = (pebuf[i__] * pebuf[i__ - 1] + (*n) * 63.f) / 64.f;
  228. /* Computing 2nd power */
  229. r__1 = pebuf[i__ - 1];
  230. *d__ = (r__1 * r__1 + (*d__) * 63.f) / 64.f;
  231. if ((*d__) != 0.f) {
  232. if (abs(*n) > (*d__)) {
  233. *fpc = (real)r_sign(&c_b2, n);
  234. } else {
  235. *fpc = (*n) / (*d__);
  236. }
  237. }
  238. /* Filter FPC */
  239. /* In order to allow L2SUM1 not to be saved from one invocation
  240. of */
  241. /* this subroutine to the next, one could change the sequence of
  242. */
  243. /* assignments below, up to the IF statement, to the following.
  244. In */
  245. /* addition, the initial value of L2PTR2 should be changed to */
  246. /* L2WID/2 instead of L2WID/2+1. */
  247. /* L2SUM1 = L2BUF(L2PTR2) */
  248. /* L2PTR2 = MOD(L2PTR2,L2WID)+1 */
  249. /* L2SUM1 = L2SUM1 - L2BUF(L2PTR2) + FPC */
  250. /* L2BUF(L2PTR2) = L2SUM1 */
  251. /* * The following lines didn't change from the original: */
  252. /* L2SUM2 = L2BUF(L2PTR1) */
  253. /* L2BUF(L2PTR1) = FPC */
  254. /* L2PTR1 = MOD(L2PTR1,L2WID)+1 */
  255. l2sum2 = l2buf[*l2ptr1 - 1];
  256. *l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc;
  257. l2buf[*l2ptr2 - 1] = *l2sum1;
  258. l2buf[*l2ptr1 - 1] = *fpc;
  259. *l2ptr1 = *l2ptr1 % 16 + 1;
  260. *l2ptr2 = *l2ptr2 % 16 + 1;
  261. if ((r__1 = *l2sum1 - l2sum2, abs(r__1)) > 1.7f) {
  262. if (! (*hyst)) {
  263. /* Ignore if buffer full */
  264. if (*osptr <= *oslen) {
  265. osbuf[*osptr] = i__ - 9;
  266. ++(*osptr);
  267. }
  268. *hyst = TRUE_;
  269. }
  270. *lasti = i__;
  271. /* After one onset detection, at least OSHYST sample times m
  272. ust go */
  273. /* by before another is allowed to occur. */
  274. } else if ((*hyst) && i__ - *lasti >= 10) {
  275. *hyst = FALSE_;
  276. }
  277. }
  278. return 0;
  279. } /* onset_ */