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; } } } }
void RoexBankANSIS342007::processInternal(const SignalBank &input) { for (int src = 0; src < input.getNSources(); ++src) { for (int ear = 0; ear < input.getNEars(); ++ear) { Real excitationLin = 0.0, fc = 0.0, g = 0.0, p = 0.0, pg = 0.0; int nChannels = input.getNChannels(); const Real* inputPowerSpectrum = input .getSingleSampleReadPointer (src, ear, 0); Real* outputExcitationPattern = output_. getSingleSampleWritePointer (src, ear, 0); //ANSI 2007 style: calculate level per ERB //using level independent roex filters centred on every component int j = 0; for (int i = 0; i < nChannels; ++i) { excitationLin = 0.0; j = 0; fc = input.getCentreFreq(i); while (j < nChannels) { //normalised deviation g = (input.getCentreFreq(j) - fc) / fc; if (g > 2) break; if (g < 0) //lower value pg = -pcomp_[i] * g; //p*abs(g) else //upper value pg = pcomp_[i] * g; //excitation per erb excitationLin += (1 + pg) * exp (-pg) * inputPowerSpectrum[j++]; } //convert to dB, subtract 51 here to save operations later compLevel_[i] = powerToDecibels (excitationLin, 1e-10, -100.0) - 51; } //now the excitation pattern for (int i = 0; i < nFilters_; ++i) { excitationLin = 0.0; j = 0; fc = output_.getCentreFreq(i); while (j < nChannels) { //normalised deviation g = (input.getCentreFreq(j) - fc) / fc; if (g > 2) break; if (g < 0) //lower value { //checked out 2.4.14 p = pu_[i] - (pl_[i] * compLevel_[j]); //51dB subtracted above p = max(0.1, p); //p can go negative for very high levels pg = -p * g; //p*abs(g) } else //upper value { pg = pu_[i] * g; } excitationLin += (1 + pg) * exp(-pg) * inputPowerSpectrum[j++]; } outputExcitationPattern[i] = excitationLin; } } } }