annotate Code/Descriptors/yin/private/src/rsmooth.c @ 4:92ca03a8fa99 tip

Update to ICASSP 2013 benchmark
author Dawn Black
date Wed, 13 Feb 2013 11:02:39 +0000
parents ea0c737c6323
children
rev   line source
dawn@0 1 /*
dawn@0 2 * rsmooth.c
dawn@0 3 * smooth columnwise by convolution by a running square window
dawn@0 4 * multiple passes allowed (--> triangular, gaussian, etc.)
dawn@0 5 *
dawn@0 6 * Alain de Cheveigné, CNRS Ircam, Dec 2001.
dawn@0 7 * (c) CNRS 2001.
dawn@0 8 */
dawn@0 9
dawn@0 10 #include <math.h>
dawn@0 11 #include "mex.h"
dawn@0 12
dawn@0 13 /* #define MWRAP */
dawn@0 14 #include "mwrap_check.h"
dawn@0 15
dawn@0 16 /* Input Arguments */
dawn@0 17
dawn@0 18 #define X_IN prhs[0]
dawn@0 19 #define SMOOTH_IN prhs[1]
dawn@0 20 #define NPASSES_IN prhs[2]
dawn@0 21 #define CLIP_IN prhs[3]
dawn@0 22
dawn@0 23 /* Output Arguments */
dawn@0 24
dawn@0 25 #define Y_OUT plhs[0]
dawn@0 26
dawn@0 27 static void rsmooth(
dawn@0 28 double *xp,
dawn@0 29 int smooth,
dawn@0 30 int npasses,
dawn@0 31 double *yp,
dawn@0 32 int m,
dawn@0 33 int n,
dawn@0 34 int clip
dawn@0 35 )
dawn@0 36 {
dawn@0 37 int h,i,j,k,mm;
dawn@0 38 double *work1, *work2, *a, *b, *tmp, sum;
dawn@0 39
dawn@0 40 mm = m + smooth + npasses*(smooth-1); /* nrows of work buffer */
dawn@0 41 work1 = (double *) mxCalloc(mm*n,sizeof(double));
dawn@0 42 work2 = (double *) mxCalloc(mm*n,sizeof(double));
dawn@0 43
dawn@0 44 CHECKIN(work1, (char *) work1 + sizeof(double)*mm*n);
dawn@0 45 CHECKIN(work2, (char *) work2 + sizeof(double)*mm*n);
dawn@0 46
dawn@0 47 a = work1;
dawn@0 48 b = work2;
dawn@0 49
dawn@0 50 /* transfer data to buffer, preceded with leading zeros */
dawn@0 51 for (k=0; k<n; k++) {
dawn@0 52 for (j=0;j<m;j++) {
dawn@0 53 SET(a[ j+smooth+mm*k ]) = GET(xp[ j+m*k ]);
dawn@0 54 }
dawn@0 55 }
dawn@0 56
dawn@0 57 /* smooth repeatedly */
dawn@0 58 for (h=0;h<npasses;h++) {
dawn@0 59 for (k=0; k<n; k++) { /* for each column */
dawn@0 60 sum=0;
dawn@0 61 for (j=smooth;j<mm;j++) { /* for each row (inner loop) */
dawn@0 62 sum += - GET(a[j-smooth+mm*k]) + GET(a[j+mm*k]);
dawn@0 63 SET(b[j+mm*k]) = sum/smooth;
dawn@0 64 }
dawn@0 65 }
dawn@0 66 tmp=a; a=b; b=tmp; /* swap for next round */
dawn@0 67 }
dawn@0 68
dawn@0 69 /* transfer to output matrix */
dawn@0 70 if (clip) {
dawn@0 71 for (j=0;j<m;j++) {
dawn@0 72 for (k=0; k<n; k++) {
dawn@0 73 SET(yp[j+m*k]) = GET(a[ j+(int)(npasses*(smooth-1)/2)+smooth + mm*k]);
dawn@0 74 }
dawn@0 75 }
dawn@0 76 } else {
dawn@0 77 for (j=0;j<m+npasses*(smooth-1);j++) {
dawn@0 78 for (k=0; k<n; k++) {
dawn@0 79 SET(yp[j+(m+npasses*(smooth-1))*k]) = GET(a[j + smooth + mm*k]);
dawn@0 80 }
dawn@0 81 }
dawn@0 82 }
dawn@0 83 CHECKOUT(work1);
dawn@0 84 CHECKOUT(work2);
dawn@0 85
dawn@0 86 }
dawn@0 87
dawn@0 88 void mexFunction(
dawn@0 89 int nlhs, mxArray *plhs[],
dawn@0 90 int nrhs, const mxArray *prhs[]
dawn@0 91 )
dawn@0 92 {
dawn@0 93 double *xp, *yp;
dawn@0 94 int m,n,npasses,smooth,clip;
dawn@0 95
dawn@0 96 /* Check for proper number of arguments */
dawn@0 97 if (nrhs > 4 || nrhs < 2) {
dawn@0 98 mexErrMsgTxt("RSMOOTH takes at least 2 and most 4 input arguments");
dawn@0 99 } else if (nlhs > 1) {
dawn@0 100 mexErrMsgTxt("RSMOOTH allows at most 1 output argument");
dawn@0 101 }
dawn@0 102
dawn@0 103 /* Check type of input */
dawn@0 104 m = mxGetM(X_IN); /* rows */
dawn@0 105 n = mxGetN(X_IN); /* columns */
dawn@0 106 if (!mxIsNumeric(X_IN) || mxIsComplex(X_IN) ||
dawn@0 107 mxIsSparse(X_IN) || !mxIsDouble(X_IN) || m<=1) {
dawn@0 108 mexErrMsgTxt("RSMOOTH: X should be a column vector or matrix of doubles");
dawn@0 109 }
dawn@0 110
dawn@0 111 if (mxGetM(SMOOTH_IN)*mxGetN(SMOOTH_IN) > 1 || mxGetPr(SMOOTH_IN)[0] <1) {
dawn@0 112 mexErrMsgTxt("RSMOOTH: SMOOTH should be a positive scalar");
dawn@0 113 }
dawn@0 114 smooth = mxGetPr(SMOOTH_IN)[0];
dawn@0 115
dawn@0 116 if (nrhs > 2) {
dawn@0 117 npasses = mxGetPr(NPASSES_IN)[0];
dawn@0 118 if (mxGetM(NPASSES_IN)*mxGetN(NPASSES_IN) > 1 || npasses <1) {
dawn@0 119 mexErrMsgTxt("RSMOOTH: NPASSES should be a positive scalar");
dawn@0 120 }
dawn@0 121 } else {
dawn@0 122 npasses=1;
dawn@0 123 }
dawn@0 124
dawn@0 125 if (nrhs > 3) {
dawn@0 126 clip=1;
dawn@0 127 } else {
dawn@0 128 clip=0;
dawn@0 129 }
dawn@0 130
dawn@0 131 /* Create matrix to return */
dawn@0 132 if (clip) {
dawn@0 133 Y_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
dawn@0 134 } else {
dawn@0 135 Y_OUT = mxCreateDoubleMatrix(m+npasses*(smooth-1), n, mxREAL);
dawn@0 136 }
dawn@0 137
dawn@0 138 /* Assign pointers to the various parameters */
dawn@0 139 xp = mxGetPr(X_IN);
dawn@0 140 yp = mxGetPr(Y_OUT);
dawn@0 141
dawn@0 142 checkin_matrix((mxArray *) X_IN);
dawn@0 143 checkin_matrix(Y_OUT);
dawn@0 144
dawn@0 145 /* Do the actual computations in a subroutine */
dawn@0 146 rsmooth(xp,smooth,npasses,yp, m,n,clip);
dawn@0 147
dawn@0 148 checkout_matrix((mxArray *) X_IN);
dawn@0 149 checkout_matrix(Y_OUT);
dawn@0 150 return;
dawn@0 151 }
dawn@0 152
dawn@0 153