int main(int argc, char **argv) { mfft *mtmh; double *sig, *psd, *specgram; double sigpow; printf("* Testing TFR library:\n"); printf("* N = %d\n", N); printf("* shift = %d\n", step); printf("* MTM NW = %3.2f\n", NW); printf("* TFR Np = %d\n", Np); printf("* TFR k = %d\n", k); printf("* TFR tm = %3.2f\n", tm); sig = (double*)malloc(17590 * sizeof(double)); fmsin(sig, npoints, 0.15, 0.45, 1024, 256./4, 0.3, -1); printf("* Input signal to tfr_in.dat\n"); write_file("tfr_in.dat", sig, npoints, 1); mtmh = mtm_init_dpss(N, NW, (int)(NW*2-1)); printf("* MTM PSD to tfr_out_psd\n"); psd = (double*)malloc(N * sizeof(double)); sigpow = mtfft(mtmh, sig+8300, N); mtpower(mtmh, psd, sigpow); write_file("tfr_out_psd.dat", psd, N/2 + 1, 1); free(psd); const int l = (npoints - Np + 1) / step; printf("* MTM spectrogram to tfr_out_mtm\n"); specgram = (double*)calloc(l * (N/2+1), sizeof(double)); mtm_spec(mtmh, specgram, sig, npoints, step, 1); write_file("tfr_out_mtm.dat", specgram, l, (N/2+1)); free(specgram); mtm_destroy(mtmh); printf("* TFR spectrogram to tfr_out_tfr\n"); mtmh = mtm_init_herm(N, Np, k, tm); specgram = (double*)calloc(l * (N/2+1), sizeof(double)); tfr_spec(mtmh, specgram, sig, npoints, -1, step, 0.01, 5, 0, NULL); write_file("tfr_out_tfr.dat", specgram, l, (N/2+1)); free(specgram); mtm_destroy(mtmh); free(sig); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int m,n,nt; int nfft, step, npoints; int ntapers = 6; int tlock = 5; double tm = 6.0; double flock=0.01; double *spec; mfft* mtmh; mxClassID data_type; double *data_double; if (nlhs < 1) return; if ((nrhs < 4) || (nrhs > 4) || (nlhs > 1)) mexErrMsgTxt("SP = TFRSPEC(S, N, step, Np, K, tm, flock, tlock)"); /* parse arguments */ m = mxGetM(prhs[0]); n = mxGetN(prhs[0]); if ((m > 1) && (n > 1)) mexErrMsgTxt("Input signal must be a 1-D time series"); nt = (m > n) ? m : n; /* check data type */ data_type = mxGetClassID(prhs[0]); if (!(data_type==mxDOUBLE_CLASS)) mexErrMsgTxt("Input signal must be double precision"); /*data_double = mxGetPr(prhs[0]);*/ nfft = mxGetScalar(prhs[1]); step = mxGetScalar(prhs[2]); npoints = mxGetScalar(prhs[3]); if (nrhs > 4) ntapers = mxGetScalar(plhs[4]); if (nrhs > 5) tm = mxGetScalar(prhs[5]); if (nrhs > 6) flock = mxGetScalar(prhs[6]); if (nrhs > 7) tlock = mxGetScalar(prhs[7]); /* generate transform object */ mtmh = mtm_init_herm(nfft, npoints, ntapers, tm); /* allocate output array */ plhs[0] = mxCreateDoubleMatrix(SPEC_NFREQ(mtmh), SPEC_NFRAMES(mtmh,nt,step),mxREAL); spec = mxGetPr(plhs[0]); /* calculate spectrogram; use the right precision fxn */ data_double = mxGetPr(prhs[0]); tfr_spec(mtmh, spec, data_double, nt, -1, step, flock, tlock, -1, 0); mtm_destroy(mtmh); }
/* methods */ static PyObject* libtfr_tfr_spec(PyObject *self, PyObject *args) { /* arguments */ PyObject *o = NULL; PyArrayObject *signal = NULL; PyArrayObject *signal_cast = NULL; PyObject *o2 = NULL; PyArrayObject *fgrid = NULL; PyArrayObject *fgrid_cast = NULL; int N; int step; int Np; int K = 6; double tm = 6.0; double flock = 0.01; int tlock = 5; /* output data */ npy_intp out_shape[2]; PyArrayObject *outdata = NULL; double *spec; /* internal stuff */ mfft *mtmh; double *samples; double *fgridp = NULL; /* parse arguments */ if (!PyArg_ParseTuple(args, "Oiii|iddiO", &o, &N, &step, &Np, &K, &tm, &flock, &tlock, &o2)) return NULL; signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL); if (signal==NULL) { PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray"); return NULL; } int nfreq = N/2+1; if (o2!=NULL && o2!=Py_None) { fgrid = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 1, NPY_CONTIGUOUS, NULL); if (fgrid!=NULL) { fgridp = coerce_ndarray_double(fgrid, &fgrid_cast); if (fgridp==NULL) { PyErr_SetString(PyExc_TypeError, "Unable to cast frequency grid to supported data type"); goto fail; } nfreq = PyArray_SIZE(fgrid); } } /* coerce input data to proper type */ samples = coerce_ndarray_double(signal, &signal_cast); if (samples==NULL) { PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type"); goto fail; } /* initialize transform object - window size may be adjusted */ mtmh = mtm_init_herm(N, Np, K, tm); /* allocate output array */ out_shape[0] = nfreq; out_shape[1] = SPEC_NFRAMES(mtmh,PyArray_SIZE(signal),step); outdata = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // last arg give fortran-order spec = (double*) PyArray_DATA(outdata); /* do the transform */ tfr_spec(mtmh, spec, samples, PyArray_SIZE(signal), -1, step, flock, tlock, nfreq, fgridp); mtm_destroy(mtmh); Py_DECREF(signal); Py_XDECREF(signal_cast); Py_XDECREF(fgrid); Py_XDECREF(fgrid_cast); return PyArray_Return(outdata); fail: Py_XDECREF(fgrid_cast); Py_XDECREF(fgrid); Py_XDECREF(signal_cast); Py_XDECREF(signal); return NULL; }
static PyObject* libtfr_stft(PyObject *self, PyObject *args) { /* arguments */ PyObject *o = NULL; PyArrayObject *signal = NULL; PyArrayObject *signal_cast = NULL; PyObject *o2 = NULL; PyArrayObject *window = NULL; int step; int N = 0; int Npoints, Ntapers; /* output data */ npy_intp out_shape[3]; PyArrayObject *outdata = NULL; int do_complex = 0; double *spec; complex double *zspec_tmp; npy_cdouble *zspec; /* internal stuff */ mfft *mtmh; double *samples = NULL; double *windowp; /* parse arguments */ if (!PyArg_ParseTuple(args, "OOi|ii", &o, &o2, &step, &N, &do_complex)) return NULL; signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL); if (signal==NULL) { PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray"); return NULL; } window = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 2, NPY_CONTIGUOUS, NULL); if (window==NULL) { PyErr_SetString(PyExc_TypeError, "Window must be a 1D or 2D ndarray"); goto fail; } /* determine dimensions of window */ if (PyArray_NDIM(window)==1) { Ntapers = 1; Npoints = PyArray_DIM(window, 0); } else { Ntapers = PyArray_DIM(window, 0); Npoints = PyArray_DIM(window, 1); } /* coerce data to proper type */ samples = coerce_ndarray_double(signal, &signal_cast); if (samples==NULL) { PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type"); goto fail; } /* need to copy the window function b/c mtm_destroy() will demalloc it */ if (PyArray_TYPE(window)!=NPY_DOUBLE) { PyErr_SetString(PyExc_TypeError, "Window function must be double precision float"); goto fail; } windowp = malloc(Npoints * Ntapers * sizeof(double)); memcpy(windowp, PyArray_DATA(window), Npoints * Ntapers * sizeof(double)); /* allocate outputs and do the transform */ if (N < 1) N = Npoints; mtmh = mtm_init(N, Npoints, Ntapers, windowp, NULL); out_shape[0] = N/2+1; if (do_complex) { out_shape[1] = Ntapers; out_shape[2] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step); outdata = (PyArrayObject*) PyArray_ZEROS(3,out_shape,NPY_CDOUBLE,1); // fortran-order zspec = (npy_cdouble*) PyArray_DATA(outdata); //printf("output dimensions: %d, %d, %d\n", out_shape[0], out_shape[1], out_shape[2]); zspec_tmp = (complex double*)malloc(PyArray_SIZE(outdata) * sizeof(complex double)); mtm_zspec(mtmh, zspec_tmp, samples, PyArray_SIZE(signal), step); cmplx_c99tonpy(zspec_tmp, zspec, PyArray_SIZE(outdata)); free(zspec_tmp); } else { out_shape[1] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step); outdata = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // fortran-order spec = (double*) PyArray_DATA(outdata); mtm_spec(mtmh, spec, samples, PyArray_SIZE(signal), step, 0); } mtm_destroy(mtmh); Py_DECREF(signal); Py_DECREF(window); Py_XDECREF(signal_cast); return PyArray_Return(outdata); fail: Py_XDECREF(signal_cast); Py_XDECREF(signal); Py_XDECREF(window); Py_XDECREF(outdata); return NULL; }