//------------------------------------------------------------------------------
//  縦続形 IIR フィルタのクラス
//
//  2017/04/07, Copyright (c) 2017 MIKAMI, Naoki
//------------------------------------------------------------------------------

#ifndef IIR_CASCADE_HPP
#define IIR_CASCADE_HPP

#include "Biquad.hpp"
#include "Array.hpp"

namespace Mikami
{
    class IIR_Cascade
    {
    public:
        // コンストラクタ
        IIR_Cascade(int order, const Biquad::Coefs ck[], float g0)
            : ORDER2_(order/2), G0_(g0), hk_(ORDER2_)
        {
            if ((order % 2) != 0)
            {
                fprintf(stderr, "\r\nOrder is not even number.\r\n");
                while (true) {}
            }
            for (int n=0; n<order/2; n++) hk_[n] = Biquad(ck[n]);
            Clear();
        }

        // デストラクタ
        ~IIR_Cascade() {}

        // 過去の計算結果を格納する遅延器のクリア
        void Clear()
        {
            for (int k=0; k<ORDER2_; k++) hk_[k].Clear();
        }

        // フィルタ処理の実行
        float Execute(float xn)
        {
            float yn = G0_*xn;
            for (int k=0; k<ORDER2_; k++) yn = hk_[k].Execute(yn);
            return yn;
        }

    private:
        const int ORDER2_;      // 次数/2
        const float G0_;        // 利得定数

        Array<Biquad> hk_;      // 2 次の IIR フィルタのオブジェクトの配列

        // disallow copy constructor and assignment operator
        IIR_Cascade(const IIR_Cascade&);
        IIR_Cascade& operator=(const IIR_Cascade&);
    };
}
#endif  // IIR_CASCADE_HPP 
