Asterisk - The Open Source Telephony Project GIT-master-f36a736
onset.c
Go to the documentation of this file.
1/*
2
3$Log$
4Revision 1.15 2004/06/26 03:50:14 markster
5Merge source cleanups (bug #1911)
6
7Revision 1.14 2003/02/12 13:59:15 matteo
8mer feb 12 14:56:57 CET 2003
9
10Revision 1.1.1.1 2003/02/12 13:59:15 matteo
11mer feb 12 14:56:57 CET 2003
12
13Revision 1.2 2000/01/05 08:20:39 markster
14Some 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
38extern 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
43static 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
282of */
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
317ust 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_ */
integer lframe
Definition: analys.c:66
double r_sign(real *a, real *b)
Definition: f2clib.c:64
#define abs(x)
Definition: f2c.h:195
#define TRUE_
Definition: f2c.h:67
#define FALSE_
Definition: f2c.h:68
float real
Definition: lpc10.h:79
INT32 integer
Definition: lpc10.h:80
INT32 logical
Definition: lpc10.h:81
static real c_b2
Definition: onset.c:43
int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st)
Definition: onset.c:129
logical hyst
Definition: lpc10.h:115
integer l2ptr2
Definition: lpc10.h:113
real l2buf[16]
Definition: lpc10.h:110
integer l2ptr1
Definition: lpc10.h:112
integer lasti
Definition: lpc10.h:114