//--------------------------------------------------------------
// 直接形Ⅱの IIR フィルタ
//
//		作成者：三上直樹，2023/01/21 作成，ⓒ三上直樹 2023
//--------------------------------------------------------------

using System.Linq;

namespace Mikami.Filter
{
	// double 型
	public class IIR_DirectD
	{
		private readonly double[] a_, b_, vn_;
		private readonly int order_;
		
		// コンストラクタ
		public IIR_DirectD(double[] a, double[] b)
		{
			order_ = a.Length;
			a_ = a.ToArray();
			b_ = b.ToArray();
			vn_ = new double[order_];
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			double vn = xn;
			for (int m=0; m<order_; m++) vn += a_[m]*vn_[m];
			double yn = b_[0]*vn;
			for (int m=0; m<order_; m++) yn += b_[m+1]*vn_[m];
			for (int m=order_-1; m>0; m--) vn_[m] = vn_[m-1];
			vn_[0] = vn;
			return (float)yn;
		}
	}

	// float 型
	public class IIR_DirectF
	{
		private readonly float[] a_, b_, vn_;
		private readonly int order_;
		
		// コンストラクタ
		public IIR_DirectF(float[] a, float[] b)
		{
			order_ = a.Length;
			a_ = a.ToArray();
			b_ = b.ToArray();
			vn_ = new float[order_];
		}

		// フィルタを実行する
		public float Execute(float xn)
		{
			float vn = xn;
			for (int m=0; m<order_; m++) vn += a_[m]*vn_[m];
			float yn = b_[0]*vn;
			for (int m=0; m<order_; m++) yn += b_[m+1]*vn_[m];
			for (int m=order_-1; m>0; m--) vn_[m] = vn_[m-1];
			vn_[0] = vn;
			return yn;
		}
	}
}
