Esempio n. 1
0
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;
            }
        }
    }
}
Esempio n. 2
0
    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;
                }
            }
        }
    }