4
Revision 1.1.1.1 2001/11/19 19:50:15 smorlat
7
Revision 1.1.1.1 2001/08/08 21:29:08 simon
10
* Revision 1.2 1996/08/20 20:37:55 jaf
11
* Removed all static local variables that were SAVE'd in the Fortran
12
* code, and put them in struct lpc10_encoder_state that is passed as an
15
* Removed init function, since all initialization is now done in
16
* init_lpc10_encoder_state().
18
* Revision 1.1 1996/08/19 22:31:18 jaf
24
#ifdef P_R_O_T_O_T_Y_P_E_S
25
extern int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st);
28
/* -- translated by f2c (version 19951025).
29
You must link the resulting object file with the libraries:
30
-lf2c -lm (in that order)
35
/* Table of constant values */
37
static real c_b2 = 1.f;
39
/* ****************************************************************** */
41
/* ONSET Version 49 */
44
/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat
47
/* Revision 1.1.1.1 2001/08/08 21:29:08 simon
50
* Revision 1.2 1996/08/20 20:37:55 jaf
51
* Removed all static local variables that were SAVE'd in the Fortran
52
* code, and put them in struct lpc10_encoder_state that is passed as an
55
* Removed init function, since all initialization is now done in
56
* init_lpc10_encoder_state().
58
* Revision 1.1 1996/08/19 22:31:18 jaf
61
/* Revision 1.5 1996/03/15 16:41:01 jaf */
62
/* Just rearranged INITONSET assignment orders to be consistent with */
63
/* order of DATA statements in ONSET. */
65
/* Revision 1.4 1996/03/15 15:48:27 jaf */
66
/* Changed some comments, and only reordered the DATA statements (their */
67
/* meaning wasn't changed). */
69
/* Revision 1.3 1996/03/14 23:53:06 jaf */
70
/* Added an entry INITONSET that reinitializes the local state variables */
71
/* of subroutine ONSET. */
73
/* Rearranged quite a few comments, adding more explaining which */
74
/* arguments were inputs, and how the modified ones can be changed. */
76
/* Revision 1.2 1996/03/12 23:53:00 jaf */
77
/* Lots of comments added about the local state of this subroutine that */
78
/* must be saved from one invocation to the next. */
80
/* One constant 180 replaced with LFRAME, which should be "more general", */
81
/* even though it would probably require many more changes than this to */
82
/* get this coder to work for other frame sizes. */
84
/* Revision 1.1 1996/02/07 14:48:09 jaf */
85
/* Initial revision */
88
/* ****************************************************************** */
90
/* Floating point version */
93
/* Detection of onsets in (or slightly preceding) the futuremost frame */
98
/* PEBUF(SBUFL:SBUFH) - Preemphasized speech */
99
/* Indices SBUFH-LFRAME through SBUFH are read. */
100
/* OSLEN - Maximum number of onsets that can be stored in OSBUF. */
101
/* SBUFL, SBUFH - Range of PEBUF */
102
/* LFRAME - length of a frame, in samples */
104
/* OSBUF(OSLEN) - Buffer which holds sorted indexes of onsets */
105
/* Indices A through B are modified, where A */
106
/* is the original value of OSPTR, and B is the final */
107
/* value of OSPTR-1. B is at most OSLEN. */
108
/* OSPTR - Free pointer into OSBUF */
109
/* Initial value should be .LE. OSLEN+1. */
110
/* If so, final value grows by one for each new onset */
111
/* found, and final value will be .LE. OSLEN+1. */
113
/* This subroutine maintains local state from one call to the next. If */
114
/* you want to switch to using a new audio stream for this subroutine, or */
115
/* reinitialize its state for any other reason, call the ENTRY INITONSET. */
117
/* Subroutine */ int onset_(real *pebuf, integer *osbuf, integer *
118
osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *
119
lframe, struct lpc10_encoder_state *st)
121
/* Initialized data */
131
/* System generated locals */
132
integer pebuf_offset, i__1;
135
/* Builtin functions */
136
double r_sign(real *, real *);
138
/* Local variables */
146
/* Revision 1.1.1.1 2001/11/19 19:50:15 smorlat
149
/* Revision 1.1.1.1 2001/08/08 21:29:08 simon
152
* Revision 1.2 1996/08/20 20:37:55 jaf
153
* Removed all static local variables that were SAVE'd in the Fortran
154
* code, and put them in struct lpc10_encoder_state that is passed as an
157
* Removed init function, since all initialization is now done in
158
* init_lpc10_encoder_state().
160
* Revision 1.1 1996/08/19 22:31:18 jaf
163
/* Revision 1.3 1996/03/29 22:03:47 jaf */
164
/* Removed definitions for any constants that were no longer used. */
166
/* Revision 1.2 1996/03/26 19:34:33 jaf */
167
/* Added comments indicating which constants are not needed in an */
168
/* application that uses the LPC-10 coder. */
170
/* Revision 1.1 1996/02/07 14:43:51 jaf */
171
/* Initial revision */
173
/* LPC Configuration parameters: */
174
/* Frame size, Prediction order, Pitch period */
175
/* Parameters/constants */
176
/* Parameters for onset detection algorithm: */
177
/* L2 Threshold for filtered slope of FPC (function of L2WID!) */
178
/* L2LAG Lag due to both filters which compute filtered slope of FPC */
179
/* L2WID Width of the filter which computes the slope of FPC */
180
/* OSHYST The number of samples of slope(FPC) which must be below */
181
/* the threshold before a new onset may be declared. */
182
/* Local variables that need not be saved */
185
/* N, D Numerator and denominator of prediction filters */
186
/* FPC Current prediction coefs */
187
/* L2BUF, L2SUM1, L2SUM2 State of slope filter */
188
/* The only "significant" change I've made is to change L2SUM2 out
190
/* of the list of local variables that need to be saved, since it */
191
/* didn't need to be. */
192
/* L2SUM1 need not be, but avoiding saving it would require a small
194
/* change to the body of the code. See comments below for an */
195
/* example of how the code could be changed to avoid saving L2SUM1.
197
/* FPC and LASTI are saved from one invocation to the next, but */
198
/* they are not given initial values. This is acceptable, because
200
/* FPC will be assigned a value the first time that this function */
201
/* is called after D is initialized to 1, since the formula to */
202
/* change D will not change it to 0 in one step, and the IF (D */
203
/* .NE. 0) statement will execute its THEN part, initializing FPC.
206
/* LASTI's value will not be used until HYST is .TRUE., and */
207
/* whenever HYST is changed from its initial value of .FALSE., */
208
/* LASTI is assigned a value. */
209
/* In a C version of this coder, it would be nice if all of these */
210
/* saved things, in this and all other subroutines, could be stored
212
/* in a single struct lpc10_coder_state_t, initialized with a call
214
/* to a function like lpc10_init(&lpc10_coder_state). In this way,
216
/* a program that used these functions could conveniently alternate
218
/* coding more than one distinct audio stream. */
223
l2buf = &(st->l2buf[0]);
224
l2sum1 = &(st->l2sum1);
225
l2ptr1 = &(st->l2ptr1);
226
l2ptr2 = &(st->l2ptr2);
227
lasti = &(st->lasti);
230
/* Parameter adjustments */
235
pebuf_offset = *sbufl;
236
pebuf -= pebuf_offset;
241
/* The following line subtracted a hard-coded "180" from LASTI, */
242
/* instead of using a variable like LFRAME or a constant like */
243
/* MAXFRM. I changed it to LFRAME, for "generality". */
248
for (i__ = *sbufh - *lframe + 1; i__ <= i__1; ++i__) {
249
/* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1.
251
*n = (pebuf[i__] * pebuf[i__ - 1] + (*n) * 63.f) / 64.f;
252
/* Computing 2nd power */
253
r__1 = pebuf[i__ - 1];
254
*d__ = (r__1 * r__1 + (*d__) * 63.f) / 64.f;
256
if (abs(*n) > (*d__)) {
257
*fpc = r_sign(&c_b2, n);
259
*fpc = (*n) / (*d__);
263
/* In order to allow L2SUM1 not to be saved from one invocation
265
/* this subroutine to the next, one could change the sequence of
267
/* assignments below, up to the IF statement, to the following.
269
/* addition, the initial value of L2PTR2 should be changed to */
270
/* L2WID/2 instead of L2WID/2+1. */
272
/* L2SUM1 = L2BUF(L2PTR2) */
273
/* L2PTR2 = MOD(L2PTR2,L2WID)+1 */
274
/* L2SUM1 = L2SUM1 - L2BUF(L2PTR2) + FPC */
275
/* L2BUF(L2PTR2) = L2SUM1 */
277
/* * The following lines didn't change from the original: */
278
/* L2SUM2 = L2BUF(L2PTR1) */
279
/* L2BUF(L2PTR1) = FPC */
280
/* L2PTR1 = MOD(L2PTR1,L2WID)+1 */
282
l2sum2 = l2buf[*l2ptr1 - 1];
283
*l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc;
284
l2buf[*l2ptr2 - 1] = *l2sum1;
285
l2buf[*l2ptr1 - 1] = *fpc;
286
*l2ptr1 = *l2ptr1 % 16 + 1;
287
*l2ptr2 = *l2ptr2 % 16 + 1;
288
if ((r__1 = *l2sum1 - l2sum2, abs(r__1)) > 1.7f) {
290
/* Ignore if buffer full */
291
if (*osptr <= *oslen) {
292
osbuf[*osptr] = i__ - 9;
298
/* After one onset detection, at least OSHYST sample times m
300
/* by before another is allowed to occur. */
301
} else if ((*hyst) && i__ - *lasti >= 10) {