//--------------------------------------------------------------
// 縦続形 IIR フィルタの構成要素として使う 2 次の IIR フィルタ
//		b0 は 1 と仮定している
//
//		作成者：三上直樹，2023/01/14 作成，ⓒ三上直樹 2023
//--------------------------------------------------------------

namespace Mikami.Filter
{
	// double 型
	public class BiquadD
	{
		public struct Coefs
		{
			public double a1, a2, b1, b2;
			public Coefs(double a1k, double a2k, double b1k, double b2k)
			{ a1 = a1k; a2 = a2k; b1 = b1k; b2 = b2k; }
		}
		private readonly Coefs ab_;
		private double un1_, un2_;		// 規定値が初期値になる
		
		// コンストラクタ
		public BiquadD(Coefs ck) { ab_ = ck; }

		// 2 次のフィルタを実行する
		public double Execute(double xn)
		{
			double un = xn + ab_.a1*un1_ + ab_.a2*un2_;
			double yn = un + ab_.b1*un1_ + ab_.b2*un2_;
			un2_ = un1_;
			un1_ = un;
			return yn;
		}
	}

	// float 型
	public class BiquadF
	{
		public struct Coefs
		{
			public float a1, a2, b1, b2;
			public Coefs(float a1k, float a2k, float b1k, float b2k)
			{ a1 = a1k; a2 = a2k; b1 = b1k; b2 = b2k; }
		}
		private readonly Coefs ab_;
		private float un1_, un2_;
		
		// コンストラクタ
		public BiquadF(Coefs ck) { ab_ = ck; }

		// 2 次のフィルタを実行する
		public float Execute(float xn)
		{
			float un = xn + ab_.a1*un1_ + ab_.a2*un2_;
			float yn = un + ab_.b1*un1_ + ab_.b2*un2_;
			un2_ = un1_;
			un1_ = un;
			return yn;
		}
	}
}
