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