//--------------------------------------------------------------
//	簡単な低域通過フィルタ
//		ブロック図：第1部第５章，図4(a), (b), (c), (d)
//
//		作成者：三上直樹，2023/01/28 作成，ⓒ三上直樹 2023
//--------------------------------------------------------------

namespace MyFilter
{
	// 図4(a) のブロック図のフィルタ
	public class Lpf1stA
	{
		private readonly float a1_, b0_;
		private float xn1_, yn1_;
		
		// コンストラクタ
		public Lpf1stA(float a1)
		{
			a1_ = a1;
			b0_ = 0.5f*(1.0f - a1);
			xn1_ = 0.0f;	// 初期条件設定
			yn1_ = 0.0f;	// 初期条件設定
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			float yn = a1_*yn1_ + b0_*(xn + xn1_);
			xn1_ = xn;		// 遅延器の更新
			yn1_ = yn;		// 遅延器の更新
			return yn;
		}
	}

	// 図4(b) のブロック図のフィルタ
	public class Lpf1stB
	{
		private readonly float a1_, b0_;
		private float vn1_;
		
		// コンストラクタ
		public Lpf1stB(float a1)
		{
			a1_ = a1;
			b0_ = 0.5f*(1.0f - a1);
			vn1_ = 0.0f;	// 初期条件設定
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			float vn = xn + a1_*vn1_;
			float yn = b0_*(vn + vn1_);
			vn1_ = vn;		// 遅延器の更新
			return yn;
		}
	}

	// 図4(c) のブロック図のフィルタ
	public class Lpf1stC
	{
		private readonly float a1_, b0_, b1_;
		private float vn1a_, vn1b_;
		
		// コンストラクタ
		public Lpf1stC(float a1)
		{
			a1_ = a1;
			b0_ = 0.5f*(1.0f - a1);
			b1_ = b0_;
			vn1a_ = 0.0f;	// 初期条件設定
			vn1b_ = 0.0f;	// 初期条件設定
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			float vn = xn + vn1a_;
			float yn = b0_*vn + vn1b_;
			vn1a_ = a1_*vn;	// 遅延器の更新
			vn1b_ = b1_*vn;	// 遅延器の更新
			return yn;
		}
	}

	// 図4(d) のブロック図のフィルタ
	public class Lpf1stD
	{
		private readonly float a1_, b0_, b1_;
		private float vn1_;
		
		// コンストラクタ
		public Lpf1stD(float a1)
		{
			a1_ = a1;
			b0_ = 0.5f*(1.0f - a1);
			b1_ = b0_;
			vn1_ = 0.0f;	// 初期条件設定
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			float yn = b0_*xn + vn1_;
			vn1_ = b1_*xn + a1_*yn;	// 遅延器の更新
			return yn;
		}
	}
}
