예제 #1
0
파일: Butter.cpp 프로젝트: faroit/loudness
    bool Butter::initializeInternal(const SignalBank &input)
    {
        switch(order_)
        {
            case 3:
            {
                aCoefs_.resize(4);
                bCoefs_.resize(4);

                Real T = 1.0/input.getFs();
                Real wc = 2.0/T * tan(2*PI*fc_*T/2.0);
                Real c1 = T*T*wc*wc;
                Real c2 = c1*T*wc/8.0;
                Real c3 = T*wc;

                bCoefs_[0] = 1.0;
                bCoefs_[1] = -3.0;
                bCoefs_[2] = 3.0;
                bCoefs_[3] = -1.0;
                aCoefs_[0] = c2 + 0.5 * c1 + c3 + 1;
                aCoefs_[1] = 3*c2 + 0.5 * c1 - c3 - 3;
                aCoefs_[2] = 3*c2 - 0.5 * c1 - c3 + 3;
                aCoefs_[3] = c2 - 0.5 * c1 + c3 - 1;

                break;
            }
            default:
            {
                LOUDNESS_ERROR(name_ << ": Only third order low pass implemented.");
                return 0;
            }
        }

        //normalise by a[0]
        normaliseCoefs();

        //delay line
        z_.assign(input.getNEars() * 2 * order_,0.0);

        //output SignalBank
        output_.initialize(input);

        return 1;
    }
예제 #2
0
파일: Biquad.cpp 프로젝트: deeuu/loudness
    bool Biquad::initializeInternal(const SignalBank &input)
    {
        if (type_ == "RLB")
        {
            RealVec bCoefs = {1.0, -2.0, 1.0};
            RealVec aCoefs = {1.0, -1.99004745483398, 0.99007225036621};
            setBCoefs (bCoefs);
            setACoefs (aCoefs);
            setCoefficientFs (48000);
        }
        else if (type_ == "prefilter")
        {
            RealVec bCoefs = {1.53512485958697,
                              -2.69169618940638, 
                              1.19839281085285};
            RealVec aCoefs = {1.0,
                              -1.69065929318241, 
                              0.73248077421585};
            setBCoefs (bCoefs);
            setACoefs (aCoefs);
            setCoefficientFs (48000);
        }

        LOUDNESS_ASSERT( bCoefs_.size() == 3 &&
                aCoefs_.size() == 3,
                "Filter coefficients do not satisfy filter order");

        //normalise by a[0]
        normaliseCoefs();

        //Transform coefficients if sampling frequency is different from
        //the one used in origin filter design
        //See: Parameter Quantization in Direct-Form Recursive Audio Filters
        //by Neunaber (2008)
        if((coefficientFs_ != 0) && (coefficientFs_ != input.getFs()))
        {
            double fc = (coefficientFs_/PI) * atan( sqrt( (1+aCoefs_[1]+aCoefs_[2]) /
                        (1-aCoefs_[1]+aCoefs_[2])));
            double Q = sqrt((aCoefs_[2]+1)*(aCoefs_[2]+1) - aCoefs_[1]*aCoefs_[1]) /
                        (2*fabs(1-aCoefs_[2]));
            double Vl = (bCoefs_[0]+bCoefs_[1]+bCoefs_[2]) / (1+aCoefs_[1]+aCoefs_[2]);
            double Vb = (bCoefs_[0] - bCoefs_[2]) / (1-aCoefs_[2]);
            double Vh = (bCoefs_[0]-bCoefs_[1]+bCoefs_[2]) / (1-aCoefs_[1]+aCoefs_[2]);

            double omega = tan(PI*fc/input.getFs());
            double omegaSqrd = omega*omega;
            double denom = omegaSqrd + omega/Q + 1;

            aCoefs_[0] = 1.0;
            aCoefs_[1] = 2*(omegaSqrd - 1) / denom;
            aCoefs_[2] = (omegaSqrd - (omega/Q) + 1)/ denom;

            bCoefs_[0] = (Vl * omegaSqrd + Vb * (omega/Q) + Vh) / denom;
            bCoefs_[1] = 2*(Vl*omegaSqrd - Vh) / denom;
            bCoefs_[2] = (Vl*omegaSqrd - (Vb*omega/Q) + Vh) / denom;
        }

        /*
        std::cout << "A" << std::endl;
        for (int i = 0; i < 3; ++i)
            std::cout << aCoefs_[i] << std::endl;
        std::cout << "B" << std::endl;
        for (int i = 0; i < 3; ++i)
            std::cout << bCoefs_[i] << std::endl;
        */

        delayLine_.initialize(input.getNSources(),
                              input.getNEars(),
                              input.getNChannels(),
                              2,
                              input.getFs());

        //output SignalBank
        output_.initialize(input);

        return 1;
    }