/*< subroutine splin2(x1a,x2a,ya,y2a,m,n,x1,x2,y) >*/ /* Subroutine */ int splin2_(doublereal *x1a, doublereal *x2a, doublereal *ya, doublereal *y2a, integer *m, integer *n, doublereal *x1, doublereal * x2, doublereal *y) { /* System generated locals */ integer ya_dim1, ya_offset, y2a_dim1, y2a_offset, i__1, i__2; /* Local variables */ integer j, k; doublereal ytmp[100], y2tmp[100], yytmp[100]; extern /* Subroutine */ int spline_(doublereal *, doublereal *, integer *, doublereal *, doublereal *, doublereal *), splint_(doublereal *, doublereal *, doublereal *, integer *, doublereal *, doublereal *) ; /*< parameter (nn=100) >*/ /*< integer m,n,j,k >*/ /*< real x1,x2,y >*/ /*< real x1a(m),x2a(n),ya(m,n),y2a(m,n),ytmp(nn),y2tmp(nn) >*/ /*< real yytmp(nn) >*/ /*< do 12 j=1,m >*/ /* Parameter adjustments */ --x1a; y2a_dim1 = *m; y2a_offset = y2a_dim1 + 1; y2a -= y2a_offset; ya_dim1 = *m; ya_offset = ya_dim1 + 1; ya -= ya_offset; --x2a; /* Function Body */ i__1 = *m; for (j = 1; j <= i__1; ++j) { /*< do 11 k=1,n >*/ i__2 = *n; for (k = 1; k <= i__2; ++k) { /*< ytmp(k)=ya(j,k) >*/ ytmp[k - 1] = ya[j + k * ya_dim1]; /*< y2tmp(k)=y2a(j,k) >*/ y2tmp[k - 1] = y2a[j + k * y2a_dim1]; /*< 11 continue >*/ /* L11: */ } /*< call splint(x2a,ytmp,y2tmp,n,x2,yytmp(j)) >*/ splint_(&x2a[1], ytmp, y2tmp, n, x2, &yytmp[j - 1]); /*< 12 continue >*/ /* L12: */ } /*< call spline(x1a,yytmp,m,1.e30,1.e30,y2tmp) >*/ spline_(&x1a[1], yytmp, m, &c_b4, &c_b4, y2tmp); /*< call splint(x1a,yytmp,y2tmp,m,x1,y) >*/ splint_(&x1a[1], yytmp, y2tmp, m, x1, y); /*< return >*/ return 0; /*< end >*/ } /* splin2_ */
/***************************************************************************** name: spline_r2xy This routine uses the cubic spline interpolation to interpolate the PSF values that are needed when sweping a radial section to a plane of the PSF. This routine works like r2xy (in misc.c) but using cubic interpolation instead of linear interpolation. ******************************************************************************/ void spline_r2xy(float *fxy, float *fr, int Nnx, int Nny, int Nnr, float deltaxy, float deltar) { extern void evenrepr(float *array, int Nnx, int Nny); int iy, ix, ir; float x, y, r, ysq; float interp_val; double cord, sq_cord; /* ..A number between zero and 1.0 for the interpolation */ float alpha; int HalfNnx, HalfNny; HalfNnx = Nnx/2; HalfNny = Nny/2; init3dr (fxy, 0.0, Nnx*Nny); /* radial coordinates array 'dr_cord' used below has been initialized before this routine was called outside the z-planes loop for speed */ /* compute the cubic spline interpolation coefficients: bcf, ccf, dcf */ spline_(&Nnr,dr_cord,fr,bcf,ccf,dcf); /* ..Interpolate in the first quadrant */ for(iy=1;iy<=HalfNny+1;iy++){ y = (float) (iy-1) * deltaxy; ysq = y*y; for(ix=iy;ix<=HalfNnx+1;ix++){ x = (float) (ix-1) * deltaxy; r = (float) sqrt((double) x*x+ysq); ir = (int) (r / deltar); cord = r - dr_cord[ir]; sq_cord = cord * cord; /* interpolated value based on cubic spline interpolation equation */ interp_val = fr[ir] + bcf[ir]*cord + ccf[ir]*sq_cord + dcf[ir]*cord*sq_cord; *(fxy+(ix-1)+(iy-1)*Nnx) = interp_val; *(fxy+(iy-1)+(ix-1)*Nnx) = interp_val; } } /* ..Replicate to the other three quadrants */ evenrepr(fxy, Nnx, Nny); }
/* Subroutine */ int splie2_(doublereal *x1a, doublereal *x2a, doublereal *ya, integer *m, integer *n, doublereal *y2a) { /* System generated locals */ integer ya_dim1, ya_offset, y2a_dim1, y2a_offset, i__1, i__2; /* Local variables */ static integer j, k; static doublereal ytmp[100], y2tmp[100]; extern /* Subroutine */ int spline_(doublereal *, doublereal *, integer *, doublereal *, doublereal *, doublereal *); /* Parameter adjustments */ --x1a; y2a_dim1 = *m; y2a_offset = 1 + y2a_dim1; y2a -= y2a_offset; ya_dim1 = *m; ya_offset = 1 + ya_dim1; ya -= ya_offset; --x2a; /* Function Body */ i__1 = *m; for (j = 1; j <= i__1; ++j) { i__2 = *n; for (k = 1; k <= i__2; ++k) { ytmp[k - 1] = ya[j + k * ya_dim1]; /* L11: */ } spline_(&x2a[1], ytmp, n, &c_b4, &c_b4, y2tmp); i__2 = *n; for (k = 1; k <= i__2; ++k) { y2a[j + k * y2a_dim1] = y2tmp[k - 1]; /* L12: */ } /* L13: */ } return 0; } /* splie2_ */
void FastRoexBank::processInternal(const SignalBank &input) { for (int ear = 0; ear < input.getNEars(); ++ear) { /* * Part 1: Obtain the level per ERB about each input component */ int nChannels = input.getNChannels(); const Real* inputPowerSpectrum = input.getSingleSampleReadPointer (ear, 0); Real* outputExcitationPattern = output_.getSingleSampleWritePointer (ear, 0); Real runningSum = 0.0; int j = 0; int k = rectBinIndices_[0][0]; for (int i = 0; i < nChannels; ++i) { //running sum of component powers while (j < rectBinIndices_[i][1]) runningSum += inputPowerSpectrum[j++]; //subtract components outside the window while (k < rectBinIndices_[i][0]) runningSum -= inputPowerSpectrum[k++]; //convert to dB, subtract 51 here to save operations later compLevel_[i] = powerToDecibels (runningSum, 1e-10, -100.0) - 51; } /* * Part 2: Complete roex filter response and compute excitation per ERB */ Real g = 0.0, p = 0.0, pg = 0.0, excitationLin = 0.0; int idx = 0; for (int i = 0; i < nFilters_; ++i) { excitationLin = 0.0; j = 0; while (j < nChannels) { //normalised deviation g = (input.getCentreFreq(j) - fc_[i]) / fc_[i]; if (g > 2) break; if (g < 0) //lower skirt - level dependent { //Complete Eq (3) p = pu_[i] - (pl_[i] * compLevel_[j]); //51dB subtracted above p = max(p, 0.1); //p can go negative for very high levels pg = -p * g; //p * abs (g) } else //upper skirt { pg = pu_[i] * g; //p * abs(g) } //excitation idx = (int)(pg / step_ + 0.5); idx = min (idx, roexIdxLimit_); excitationLin += roexTable_[idx] * inputPowerSpectrum[j++]; } //excitation level if (isExcitationPatternInterpolated_) excitationLevel_[i] = log (excitationLin + 1e-10); else outputExcitationPattern[i] = excitationLin; } /* * Part 3: Interpolate to estimate * 0.1~Cam res excitation pattern */ if (isExcitationPatternInterpolated_) { spline_.set_points (cams_, excitationLevel_, isInterpolationCubic_); for (int i = 0; i < 372; ++i) { excitationLin = exp (spline_ (1.8 + i * 0.1)); outputExcitationPattern[i] = excitationLin; } } } }