LTFAT_EXTERN void LTFAT_NAME_COMPLEX(idwiltiii_fb)(const LTFAT_COMPLEX *c, const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt gl, const ltfatInt W, const ltfatInt M, LTFAT_COMPLEX *f) { const ltfatInt N = L / M; const ltfatInt M2 = 2 * M; const ltfatInt M4 = 4 * M; const LTFAT_REAL scalconst = 1.0 / sqrt(2.0); const LTFAT_COMPLEX eipi4 = cexp(I * PI / 4.0); const LTFAT_COMPLEX emipi4 = cexp(-I * PI / 4.0); LTFAT_COMPLEX *coef2 = ltfat_calloc(2 * M * N * W, sizeof * coef2); LTFAT_COMPLEX *f2 = ltfat_malloc(L * W * sizeof * f2); const LTFAT_COMPLEX *pcoef = c; LTFAT_COMPLEX *pcoef2 = coef2; PREPROC_COMPLEX LTFAT_NAME(idgt_fb)(coef2, g, L, gl, W, M, 2 * M, FREQINV, f2); POSTPROC_COMPLEX LTFAT_SAFEFREEALL(coef2, f2); }
LTFAT_EXTERN void LTFAT_NAME_REAL(idwiltiii_long)(const LTFAT_REAL *c, const LTFAT_REAL *g, const ltfatInt L, const ltfatInt W, const ltfatInt M, LTFAT_REAL *f) { const ltfatInt N = L / M; const ltfatInt M2 = 2 * M; const ltfatInt M4 = 4 * M; const LTFAT_REAL scalconst = 1.0 / sqrt(2.0); const LTFAT_COMPLEX eipi4 = cexp(I * PI / 4.0); const LTFAT_COMPLEX emipi4 = cexp(-I * PI / 4.0); LTFAT_COMPLEX *coef2 = ltfat_calloc(2 * M * N * W, sizeof * coef2); LTFAT_COMPLEX *f2 = ltfat_malloc(L * W * sizeof * f2); LTFAT_COMPLEX *g2 = ltfat_malloc(L * sizeof * g2); for (ltfatInt ii = 0; ii < L; ii++) g2[ii] = g[ii]; const LTFAT_REAL *pcoef = c; LTFAT_COMPLEX *pcoef2 = coef2; PREPROC_COMPLEX LTFAT_NAME(idgt_long)(coef2, g2, L, W, M, 2 * M, FREQINV, f2); POSTPROC_REAL LTFAT_SAFEFREEALL(coef2, f2, g2); }
LTFAT_EXTERN fbreassOptOut* fbreassOptOut_init(const ltfatInt l, const ltfatInt inital) { fbreassOptOut* ret = ltfat_calloc( 1, sizeof * ret); ret->l = l; // This is an array of pointers. ret->repos = ltfat_malloc(l * sizeof * ret->repos); ret->reposl = ltfat_calloc(l , sizeof * ret->reposl); ret->reposlmax = ltfat_malloc(l * sizeof * ret->reposlmax); ltfatInt inital2 = imax(1, inital); for (ltfatInt ii = 0; ii < l; ii++) { ret->repos[ii] = ltfat_malloc( inital2 * sizeof * ret->repos[ii]); ret->reposlmax[ii] = inital2; } return ret; }
LTFAT_API void* ltfat_postpad (void* ptr, size_t nold, size_t nnew) { if(!ptr) return ltfat_calloc(nnew, 1); if (nnew > nold) { void* outp = ltfat_realloc (ptr, nold, nnew); if (!outp) return NULL; memset(((unsigned char*)outp) + nold, 0, nnew - nold); return outp; } return ptr; }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftblMexAtExitFnc)); atExitFncRegistered = 1; } const mxArray* mxc = prhs[0]; const mxArray* mxG = prhs[1]; double* foffDouble = mxGetData(prhs[2]); double* a = mxGetData(prhs[3]); double* realonlyDouble = mxGetData(prhs[4]); // number of channels mwSize W = mxGetN(mxGetCell(mxc,0)); // filter number mwSize M = mxGetNumberOfElements(mxG); // mwSize acols = mxGetN(prhs[3]); double afrac[M]; memcpy(afrac,a,M*sizeof(double)); if(acols>1) { for(mwIndex m=0; m<M; m++) { afrac[m] = afrac[m]/a[M+m]; } } // POINTER TO THE FILTERS const LTFAT_COMPLEX* GPtrs[M]; // input lengths mwSize inLen[M]; mwSignedIndex foff[M]; int realonly[M]; // POINTER TO INPUTS const LTFAT_COMPLEX* cPtrs[M]; // filter lengths mwSize Gl[M]; if(M!=LTFAT_NAME(oldM) || W!=LTFAT_NAME(oldW)) { LTFAT_NAME(fftblMexAtExitFnc)(); LTFAT_NAME(oldM) = M; LTFAT_NAME(oldW) = W; LTFAT_NAME(oldLc) = ltfat_calloc(M,sizeof(mwSize)); LTFAT_NAME(oldPlans) = ltfat_calloc(M,sizeof*LTFAT_NAME(oldPlans)); } // output data length mwSize L = (mwSize) floor(afrac[0]*mxGetM(mxGetCell(mxc, 0)) + 0.5); // over all channels for(mwIndex m =0; m<M; m++) { foff[m] = (mwSignedIndex) foffDouble[m]; realonly[m] = (realonlyDouble[m]>1e-3); cPtrs[m] = mxGetData(mxGetCell(mxc,m)); inLen[m] = (mwSize) mxGetM(mxGetCell(mxc, m)); GPtrs[m] = mxGetData(mxGetCell(mxG, m)); Gl[m] = (mwSize) mxGetNumberOfElements(mxGetCell(mxG, m)); if(LTFAT_NAME(oldLc)[m]!=inLen[m]) { LTFAT_NAME(oldLc)[m] = inLen[m]; LTFAT_NAME(upconv_fftbl_plan) ptmp = LTFAT_NAME(upconv_fftbl_init)(L, Gl[m], W, afrac[m]); if(LTFAT_NAME(oldPlans)[m]!=0) { LTFAT_NAME(upconv_fftbl_done)(LTFAT_NAME(oldPlans)[m]); } LTFAT_NAME(oldPlans)[m]=ptmp; } } plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxCOMPLEX); mxArray* mxF = plhs[0]; LTFAT_COMPLEX* FPtr = mxGetData(mxF); LTFAT_NAME(ifilterbank_fftbl_execute)( LTFAT_NAME(oldPlans), cPtrs, GPtrs, M, foff, realonly, FPtr); //LTFAT_NAME(ifilterbank_fftbl)( cPtrs, GPtrs,L,Gl,W,afrac, // M, foff, realonly, FPtr); }
void LTFAT_NAME(ltfatMexFnc)( int UNUSED(nlhs), mxArray *plhs[], int UNUSED(nrhs), const mxArray *prhs[] ) { static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftblMexAtExitFnc)); atExitFncRegistered = 1; } const mxArray* mxF = prhs[0]; const mxArray* mxG = prhs[1]; double* foffDouble = (double*) mxGetData(prhs[2]); double* a = (double*) mxGetData(prhs[3]); double* realonlyDouble = (double*) mxGetData(prhs[4]); // input data length mwSize L = mxGetM(mxF); // number of channels mwSize W = mxGetN(mxF); // filter number mwSize M = mxGetNumberOfElements(mxG); // mwSize acols = mxGetN(prhs[3]); double afrac[M]; memcpy(afrac,a,M*sizeof*a); if(acols>1) { for(mwIndex m=0; m<M; m++) { afrac[m] = afrac[m]/a[M+m]; } } // output lengths mwSize outLen[M]; // Frequency offsets mwSignedIndex foff[M]; // realonly int realonly[M]; // POINTER TO THE INPUT LTFAT_COMPLEX* FPtr = mxGetData(prhs[0]); // POINTER TO THE FILTERS const LTFAT_COMPLEX* GPtrs[M]; // filter lengths mwSize Gl[M]; // POINTER TO OUTPUTS LTFAT_COMPLEX* cPtrs[M]; // C99 feature plhs[0] = mxCreateCellMatrix(M, 1); if(M!=LTFAT_NAME(oldM) || W != LTFAT_NAME(oldW)) { LTFAT_NAME(fftblMexAtExitFnc)(); LTFAT_NAME(oldM) = M; LTFAT_NAME(oldW) = W; LTFAT_NAME(oldLc) = ltfat_calloc(M,sizeof(mwSize)); LTFAT_NAME(oldPlans) = ltfat_calloc(M,sizeof*LTFAT_NAME(oldPlans)); } for(mwIndex m=0; m<M; ++m) { foff[m] = (mwSignedIndex) foffDouble[m]; realonly[m] = (realonlyDouble[m]>1e-3); outLen[m] = (mwSize) floor( L/afrac[m] +0.5); GPtrs[m] = mxGetData(mxGetCell(mxG, m)); Gl[m] = mxGetNumberOfElements(mxGetCell(mxG, m)); mxSetCell(plhs[0], m, ltfatCreateMatrix(outLen[m], W, LTFAT_MX_CLASSID,mxCOMPLEX)); cPtrs[m] = mxGetData(mxGetCell(plhs[0],m)); if(LTFAT_NAME(oldLc)[m]!=outLen[m]) { LTFAT_NAME(oldLc)[m] = outLen[m]; LTFAT_NAME(convsub_fftbl_plan) ptmp = LTFAT_NAME(convsub_fftbl_init)( L, Gl[m], W, afrac[m], cPtrs[m]); if(LTFAT_NAME(oldPlans)[m]!=0) { LTFAT_NAME(convsub_fftbl_done)(LTFAT_NAME(oldPlans)[m]); } LTFAT_NAME(oldPlans)[m]=ptmp; } } LTFAT_NAME(filterbank_fftbl_execute)( LTFAT_NAME(oldPlans),FPtr, GPtrs, M, foff, realonly, cPtrs); }
LTFAT_EXTERN void LTFAT_NAME(atrousconvsub_td)(const LTFAT_TYPE *f, const LTFAT_TYPE *g, const ltfatInt L, const ltfatInt gl, const ltfatInt ga, ltfatInt skip, LTFAT_TYPE *c, ltfatExtType ext) { memset(c,0,L*sizeof*c); ltfatInt skipLoc = -skip; LTFAT_TYPE *filtRev = ltfat_malloc(gl*sizeof*filtRev); LTFAT_NAME(reverse_array)((LTFAT_TYPE*)g,filtRev,gl); ltfatInt glUps = ga*gl-(ga-1); LTFAT_TYPE *righExtbuff = 0; // number of output samples that can be calculated "painlessly" ltfatInt Nsafe = imax((L - skipLoc),0); // prepare cyclic buf of length of power of two (for effective modulo operations) ltfatInt bufgl = nextPow2(glUps); // buf index ltfatInt buffPtr = 0; // allocating and initializing the cyclic buf LTFAT_TYPE *buf = ltfat_calloc(bufgl,sizeof*buf); // pointer for moving in the input data const LTFAT_TYPE *tmpIn = f; LTFAT_TYPE *tmpOut = c; LTFAT_TYPE *tmpg = filtRev; LTFAT_TYPE *tmpBuffPtr = buf; // fill buf with the initial values from the input signal according to the boundary treatment // last glUps buf samples are filled to keep buffPtr=0 LTFAT_NAME(extend_left)(f,L,buf,bufgl,glUps,ext,1); if(Nsafe<L) { // right extension is necessary, additional buf from where to copy righExtbuff = ltfat_malloc(bufgl*sizeof(LTFAT_TYPE)); memset(righExtbuff,0,bufgl*sizeof(LTFAT_TYPE)); // store extension in the buf (must be done now to avoid errors when inplace calculation is done) LTFAT_NAME(extend_right)(f,L,righExtbuff,glUps,ext,1); } #define ONEOUTSAMPLE \ tmpg = filtRev; \ ltfatInt revBufPtr = modPow2(buffPtr-glUps,bufgl); \ ltfatInt loop1it = gl+1; \ while(--loop1it) \ { \ tmpBuffPtr = buf + modPow2(revBufPtr,bufgl); \ revBufPtr+=ga; \ *tmpOut += *(tmpBuffPtr) * *(tmpg++); \ } \ tmpOut++; #define READNEXTDATA(samples,wherePtr) \ buffOver = imax(buffPtr+(samples)-bufgl, 0); \ memcpy(buf + buffPtr, wherePtr, ((samples)-buffOver)*sizeof(LTFAT_TYPE)); \ memcpy(buf,wherePtr+(samples)-buffOver,buffOver*sizeof(LTFAT_TYPE)); \ buffPtr = modPow2(buffPtr += (samples),bufgl); #define READNEXTSAMPLE(wherePtr) \ *(buf + buffPtr) = *wherePtr; \ buffPtr = modPow2(++buffPtr,bufgl); ltfatInt buffOver = 0; /*** initial buf fill ***/ ltfatInt sampToRead = imin((skipLoc+1),L); READNEXTDATA(sampToRead,tmpIn); tmpIn += sampToRead; /*********** STEP 1: FREE LUNCH ( but also a hot-spot) *******************************/ // Take the smaller value from "painless" output length and the user defined output length ltfatInt iiLoops = imin(Nsafe-1,L-1); // loop trough all output samples, omit the very last one. for (ltfatInt ii = 0; ii < iiLoops; ii++) { ONEOUTSAMPLE READNEXTSAMPLE(tmpIn) tmpIn++; } /*********** STEP 2: FINALIZE FREE LUNCH ************************************/ if(Nsafe>0) { ONEOUTSAMPLE } /*********** STEP 3: NOW FOR THE TRICKY PART ************************************/ if(Nsafe<L) { /************ STEP 3a: DEALING WITH THE REMAINING SAMPLES ******************/ // CAREFULL NOW! possibly stepping outside of input signal // last index in the input signal for which reading next a samples reaches outside of the input signal ltfatInt rightExtBuffIdx = 0; if(Nsafe>0) { ltfatInt lastInIdx = ((Nsafe-1)+1+skipLoc); rightExtBuffIdx = lastInIdx + 1 - L; ltfatInt diff = imax(0,L - lastInIdx); READNEXTDATA(diff,(f + lastInIdx)) }