⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onset.c

📁 10阶LPC编解码及源程序
💻 C
字号:
/*$Log: onset.c,v $Revision 1.1.1.1  2001/11/19 19:50:15  smorlatFirst cvs.Revision 1.1.1.1  2001/08/08 21:29:08  simonFirst import * Revision 1.2  1996/08/20  20:37:55  jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1  1996/08/19  22:31:18  jaf * Initial revision **/#ifdef P_R_O_T_O_T_Y_P_E_Sextern int onset_(real *pebuf, integer *osbuf, integer *osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *lframe, struct lpc10_encoder_state *st);#endif/*  -- translated by f2c (version 19951025).   You must link the resulting object file with the libraries:	-lf2c -lm   (in that order)*/#include "f2c.h"/* Table of constant values */static real c_b2 = 1.f;/* ****************************************************************** *//* 	ONSET Version 49 *//* $Log: onset.c,v $/* Revision 1.1.1.1  2001/11/19 19:50:15  smorlat/* First cvs./*/* Revision 1.1.1.1  2001/08/08 21:29:08  simon/* First import/* * Revision 1.2  1996/08/20  20:37:55  jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1  1996/08/19  22:31:18  jaf * Initial revision * *//* Revision 1.5  1996/03/15  16:41:01  jaf *//* Just rearranged INITONSET assignment orders to be consistent with *//* order of DATA statements in ONSET. *//* Revision 1.4  1996/03/15  15:48:27  jaf *//* Changed some comments, and only reordered the DATA statements (their *//* meaning wasn't changed). *//* Revision 1.3  1996/03/14  23:53:06  jaf *//* Added an entry INITONSET that reinitializes the local state variables *//* of subroutine ONSET. *//* Rearranged quite a few comments, adding more explaining which *//* arguments were inputs, and how the modified ones can be changed. *//* Revision 1.2  1996/03/12  23:53:00  jaf *//* Lots of comments added about the local state of this subroutine that *//* must be saved from one invocation to the next. *//* One constant 180 replaced with LFRAME, which should be "more general", *//* even though it would probably require many more changes than this to *//* get this coder to work for other frame sizes. *//* Revision 1.1  1996/02/07 14:48:09  jaf *//* Initial revision *//* ****************************************************************** *//* 	Floating point version *//*   Detection of onsets in (or slightly preceding) the futuremost frame *//*   of speech. *//* Input: *//*  PEBUF(SBUFL:SBUFH)  - Preemphasized speech *//*                        Indices SBUFH-LFRAME through SBUFH are read. *//*  OSLEN  - Maximum number of onsets that can be stored in OSBUF. *//*  SBUFL, SBUFH        - Range of PEBUF *//*  LFRAME              - length of a frame, in samples *//* Input/Output: *//*  OSBUF(OSLEN) - Buffer which holds sorted indexes of onsets *//*                 Indices A through B are modified, where A *//*                 is the original value of OSPTR, and B is the final *//*                 value of OSPTR-1.  B is at most OSLEN. *//*  OSPTR        - Free pointer into OSBUF *//*                 Initial value should be .LE. OSLEN+1. *//*                 If so, final value grows by one for each new onset *//*                 found, and final value will be .LE. OSLEN+1. *//* This subroutine maintains local state from one call to the next.  If *//* you want to switch to using a new audio stream for this subroutine, or *//* reinitialize its state for any other reason, call the ENTRY INITONSET. *//* Subroutine */ int onset_(real *pebuf, integer *osbuf, integer *	osptr, integer *oslen, integer *sbufl, integer *sbufh, integer *	lframe, struct lpc10_encoder_state *st){    /* Initialized data */    real *n;    real *d__;    real *l2buf;    real *l2sum1;    integer *l2ptr1;    integer *l2ptr2;    logical *hyst;    /* System generated locals */    integer pebuf_offset, i__1;    real r__1;    /* Builtin functions */    double r_sign(real *, real *);    /* Local variables */    integer i__;    integer *lasti;    real l2sum2;    real *fpc;/*       Arguments *//* $Log: onset.c,v $/* Revision 1.1.1.1  2001/11/19 19:50:15  smorlat/* First cvs./*/* Revision 1.1.1.1  2001/08/08 21:29:08  simon/* First import/* * Revision 1.2  1996/08/20  20:37:55  jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1  1996/08/19  22:31:18  jaf * Initial revision * *//* Revision 1.3  1996/03/29  22:03:47  jaf *//* Removed definitions for any constants that were no longer used. *//* Revision 1.2  1996/03/26  19:34:33  jaf *//* Added comments indicating which constants are not needed in an *//* application that uses the LPC-10 coder. *//* Revision 1.1  1996/02/07  14:43:51  jaf *//* Initial revision *//*   LPC Configuration parameters: *//* Frame size, Prediction order, Pitch period *//*       Parameters/constants *//*   Parameters for onset detection algorithm: *//*    L2		Threshold for filtered slope of FPC (function of L2WID!) *//*    L2LAG	Lag due to both filters which compute filtered slope of FPC *//*    L2WID	Width of the filter which computes the slope of FPC *//*    OSHYST	The number of samples of slope(FPC) which must be below *//* 	        the threshold before a new onset may be declared. *//*       Local variables that need not be saved *//*       Local state *//*   Variables *//*    N, D       Numerator and denominator of prediction filters *//*    FPC        Current prediction coefs *//*    L2BUF, L2SUM1, L2SUM2    State of slope filter *//*       The only "significant" change I've made is to change L2SUM2 out *//*       of the list of local variables that need to be saved, since it *//*       didn't need to be. *//*       L2SUM1 need not be, but avoiding saving it would require a small *//*       change to the body of the code.  See comments below for an *//*       example of how the code could be changed to avoid saving L2SUM1. *//*       FPC and LASTI are saved from one invocation to the next, but *//*       they are not given initial values.  This is acceptable, because *//*       FPC will be assigned a value the first time that this function *//*       is called after D is initialized to 1, since the formula to *//*       change D will not change it to 0 in one step, and the IF (D *//*       .NE. 0) statement will execute its THEN part, initializing FPC. *//*       LASTI's value will not be used until HYST is .TRUE., and *//*       whenever HYST is changed from its initial value of .FALSE., *//*       LASTI is assigned a value. *//*       In a C version of this coder, it would be nice if all of these *//*       saved things, in this and all other subroutines, could be stored *//*       in a single struct lpc10_coder_state_t, initialized with a call *//*       to a function like lpc10_init(&lpc10_coder_state).  In this way, *//*       a program that used these functions could conveniently alternate *//*       coding more than one distinct audio stream. */    n = &(st->n);    d__ = &(st->d__);    fpc = &(st->fpc);    l2buf = &(st->l2buf[0]);    l2sum1 = &(st->l2sum1);    l2ptr1 = &(st->l2ptr1);    l2ptr2 = &(st->l2ptr2);    lasti = &(st->lasti);    hyst = &(st->hyst);    /* Parameter adjustments */    if (osbuf) {	--osbuf;	}    if (pebuf) {	pebuf_offset = *sbufl;	pebuf -= pebuf_offset;	}    /* Function Body *//*       The following line subtracted a hard-coded "180" from LASTI, *//*       instead of using a variable like LFRAME or a constant like *//*       MAXFRM.  I changed it to LFRAME, for "generality". */    if (*hyst) {	*lasti -= *lframe;    }    i__1 = *sbufh;    for (i__ = *sbufh - *lframe + 1; i__ <= i__1; ++i__) {/*   Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1. */	*n = (pebuf[i__] * pebuf[i__ - 1] + (*n) * 63.f) / 64.f;/* Computing 2nd power */	r__1 = pebuf[i__ - 1];	*d__ = (r__1 * r__1 + (*d__) * 63.f) / 64.f;	if ((*d__) != 0.f) {	    if (abs(*n) > (*d__)) {		*fpc = r_sign(&c_b2, n);	    } else {		*fpc = (*n) / (*d__);	    }	}/*   Filter FPC *//*       In order to allow L2SUM1 not to be saved from one invocation of *//*       this subroutine to the next, one could change the sequence of *//*       assignments below, up to the IF statement, to the following.  In *//*       addition, the initial value of L2PTR2 should be changed to *//*       L2WID/2 instead of L2WID/2+1. *//*       L2SUM1 = L2BUF(L2PTR2) *//*       L2PTR2 = MOD(L2PTR2,L2WID)+1 *//*       L2SUM1 = L2SUM1 - L2BUF(L2PTR2) + FPC *//*       L2BUF(L2PTR2) = L2SUM1 *//* *       The following lines didn't change from the original: *//*       L2SUM2 = L2BUF(L2PTR1) *//*       L2BUF(L2PTR1) = FPC *//*       L2PTR1 = MOD(L2PTR1,L2WID)+1 */	l2sum2 = l2buf[*l2ptr1 - 1];	*l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc;	l2buf[*l2ptr2 - 1] = *l2sum1;	l2buf[*l2ptr1 - 1] = *fpc;	*l2ptr1 = *l2ptr1 % 16 + 1;	*l2ptr2 = *l2ptr2 % 16 + 1;	if ((r__1 = *l2sum1 - l2sum2, abs(r__1)) > 1.7f) {	    if (! (*hyst)) {/*   Ignore if buffer full */		if (*osptr <= *oslen) {		    osbuf[*osptr] = i__ - 9;		    ++(*osptr);		}		*hyst = TRUE_;	    }	    *lasti = i__;/*       After one onset detection, at least OSHYST sample times must go *//*       by before another is allowed to occur. */	} else if ((*hyst) && i__ - *lasti >= 10) {	    *hyst = FALSE_;	}    }    return 0;} /* onset_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -