//--------------------------------------------------------------
//  グラフィックイコライザのクラス（ヘッダ）
//
//  2022/10/19, Copyright (c) 2022 MIKAMI, Naoki
//--------------------------------------------------------------

#include "Array.hpp"
#include "BiquadGrEq.hpp"
#include "GrEqParamsCalculator.hpp"

#ifndef GRAPHIC_EQALIZER_HPP
#define GRAPHIC_EQALIZER_HPP

namespace Mikami
{
    class GrEqualizer
    {
    public:
        // コンストラクタ
        GrEqualizer(int bands, float fs, float qVal = 1.0f/sqrtf(2.0f));
        // グラフィック･イコライザの実行
        float Execute(float xn) { return (this->*fPtr_)(xn); }
        // 周波数特性を平坦にする
        void Flatten();
        // 指定した帯域の利得（db 値）を設定する
        void SetGain(float db, int band)
        { biquad_[band].SetCoefficients(params_.Get(band, f0_[band], db, Q_VAL_)); }
        // グラフィック･イコライザの処理を有効にする
        void Validate() { fPtr_ = &GrEqualizer::Filtering; }
        // グラフィック･イコライザの処理を無効にする
        void Invalidate() { fPtr_ = &GrEqualizer::Through; }
            
    private:
        const int BANDS_;       // バンドの数
        const float Q_VAL_;     // Q 値

        Array<BiquadGrEq> biquad_;
        Array<float> f0_;
        GrEqParams params_;
        float (GrEqualizer::*fPtr_)(float);
        
        float Through(float xn) { return xn; }  // そのまま出力
        float Filtering(float xn);              // フィルタを実行して出力

        // コピー･コンストラクタ，代入演算子禁止禁止のため
        GrEqualizer(const GrEqualizer&);
        GrEqualizer& operator=(const GrEqualizer&);
    };
}
#endif  // GRAPHIC_EQALIZER_HPP
