Mercurial > hg > emotion-detection-top-level
diff Code/Descriptors/yin/private/src/dftoperiod2.c @ 0:ea0c737c6323
first commit
author | Dawn Black <dawn.black@eecs.qmul.ac.uk> |
---|---|
date | Thu, 26 Jul 2012 14:46:25 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Code/Descriptors/yin/private/src/dftoperiod2.c Thu Jul 26 14:46:25 2012 +0100 @@ -0,0 +1,144 @@ +/* +* dftoperiods.c +* estimate period from df +* +* Alain de Cheveigné, CNRS/Ircam Dec 2001 +* (c) 2001 CNRS +*/ + +#include <math.h> +#include "mex.h" + +/* #define MWRAP */ +#include "mwrap_check.h" + +/* Input Arguments */ +#define D_IN prhs[0] +#define B_IN prhs[1] +#define T_IN prhs[2] + +/* output arguments */ +#define PRD_OUT plhs[0] + +static void ddftoperiods( + double *dp, /* input df */ + double *bp, /* bounds */ + double *prdp, /* periods */ + double thresh, /* threshold */ + int m, /* nrows of df */ + int n /* ncols of df */ + ) +{ + int j,k, p, lo, hi, maxj, goodflag; + double z, min, globalmin; + + /* bounds */ + lo= GET(bp[0]); + hi= GET(bp[1]); + if (lo<0 || hi>m ) { + mexPrintf("%d %d\n", lo, hi); + mexErrMsgTxt("DFTOPERIOD: bounds are out of bounds"); + } + + #define MARGIN 1.5 + + for (k=0;k<n;k++) { /* for each col */ + + goodflag=0; + + /* estimate global min */ + globalmin=GET(dp[k*m+lo]); + for (j=lo;j<hi; j++) { /* for each row */ + z = GET(dp[k*m+j]); + if (z<globalmin) { /* update min & period estimate */ + globalmin = z; + } + } + + thresh += globalmin; + + /* estimate period */ + p=lo; + min=GET(dp[k*m+lo]); + maxj=hi; + for (j=lo;j<maxj; j++) { /* for each row */ + + z = GET(dp[k*m+j]); + + if (z<thresh && z <= min) { /* good candidate, restrict search range */ + maxj=j*MARGIN; + if (maxj> hi) { maxj = hi; } + } + + if (z<min) { /* update min & period estimate */ + min = z; + p=j; + } + + } + + /* mexPrintf("%f %d %f\n", thresh, p, min); */ + + SET(prdp[k])=p; + } + + return; +} + +void mexFunction( + int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] + ) +{ + double *dp, *bp, *tp, *prdp, thresh; + int m, n; + + /* Check for proper number of arguments */ + if (nrhs != 3){ + mexErrMsgTxt("DFTOPERIOD requires 3 input arguments"); + } + + /* Check type of input */ + if (!mxIsNumeric(D_IN) || mxIsComplex(D_IN) || + mxIsSparse(D_IN) || !mxIsDouble(D_IN) ) { + mexErrMsgTxt("DFTOPERIOD: D should be doubles"); + } + if (!mxIsNumeric(B_IN) || mxIsComplex(B_IN) || + mxIsSparse(B_IN) || !mxIsDouble(B_IN) ) { + mexErrMsgTxt("DFTOPERIOD: B should be doubles"); + } + if (!mxIsNumeric(T_IN) || mxIsComplex(T_IN) || + mxIsSparse(T_IN) || !mxIsDouble(T_IN) ) { + mexErrMsgTxt("DFTOPERIOD: T should be double"); + } + m=mxGetM(D_IN); /* rows */ + n=mxGetN(D_IN); /* columns */ + + if (mxGetM(B_IN) * mxGetN(B_IN) != 2) { + mexErrMsgTxt("DFTOPERIOD: B should be a size 2 vector"); + } + if (mxGetM(T_IN)*mxGetN(T_IN) != 1) { + mexErrMsgTxt("DFTOPERIOD: T should be scalar"); + } + + /* Create matrix to return */ + PRD_OUT = mxCreateDoubleMatrix(1,n, mxREAL); + + dp = mxGetPr(D_IN); + bp = mxGetPr(B_IN); + tp = mxGetPr(T_IN); thresh=tp[0]; + prdp = mxGetPr(PRD_OUT); + + checkin_matrix((mxArray *) D_IN); + checkin_matrix((mxArray *) B_IN); + checkin_matrix((mxArray *) PRD_OUT); + + /* Do the actual computations in a subroutine */ + ddftoperiods(dp,bp,prdp,thresh,m,n); + + checkout_matrix((mxArray *) D_IN); + checkout_matrix((mxArray *) B_IN); + checkout_matrix((mxArray *) PRD_OUT); + return; +} +