フィルタ係数。 アナログプロトタイプ/ディジタル兼用。
アナログ : �巴[i]s^i / �蚤[i]s^i ディジタル: �巴[i]z^-i / �蚤[i]z^-i 双一次変換では分母/分子の次数が変わらないことを利用して、 アナログ・ディジタルで係数クラスを使いまわす。
Inheritance: ICloneable
		//public override void GetDigitalLPF(double w, Coefficient[] coefs)
		public void GetDigitalLPF2(double w, Coefficient[] coefs)
		{
			double sin, cos;
			GetSinCos(w, out sin, out cos);
			double b0 = (1 - cos) / 2;
			double a1 = -2 * cos;

			double nu = (this.order & 1) == 1 ? 1 : 0.5;

			for(int i=this.order-1, j=0; i>0; i-=2, ++j)
			{
				Coefficient coef = coefs[j];

				double alpha = sin * Math.Cos(Math.PI / 2.0 * (double)i / this.order);

				coef.a[0] = 1 + alpha;
				coef.a[1] = a1;
				coef.a[2] = 1 - alpha;
				coef.b[0] = b0;
				coef.b[1] = 2 * b0;
				coef.b[2] = b0;
			}

			if((this.order & 1) == 1)
			{
				Coefficient coef = coefs[this.order / 2];

				coef.a[0] = sin + cos + 1;
				coef.a[1] = sin - cos - 1;
				coef.a[2] = 0;
				coef.b[0] = sin;
				coef.b[1] = sin;
				coef.b[2] = 0;
			}
		}
		//public override void GetAnalogPrototype(Coefficient[] coefs)
		public void GetAnalogPrototype2(Coefficient[] coefs)
		{
			for(int i=this.order-1, j=0; i>0; i-=2, ++j)
			{
				Coefficient coef = coefs[j];

				coef.a[0] = 1;
				coef.a[1] = 2 * Math.Cos(Math.PI / 2 * (double)i / this.order);
				coef.a[2] = 1;
				coef.b[0] = 1;
				coef.b[1] = 0;
				coef.b[2] = 0;
			}

			if((this.order & 1) == 1)
			{
				Coefficient coef = coefs[this.order / 2];

				coef.a[0] = 1;
				coef.a[1] = 1;
				coef.a[2] = 0;
				coef.b[0] = 1;
				coef.b[1] = 0;
				coef.b[2] = 0;
			}
		}
        //public override void GetAnalogPrototype(Coefficient[] coefs)
        public void GetAnalogPrototype2(Coefficient[] coefs)
        {
            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                Coefficient coef = coefs[j];

                coef.a[0] = 1;
                coef.a[1] = 2 * Math.Cos(Math.PI / 2 * (double)i / this.order);
                coef.a[2] = 1;
                coef.b[0] = 1;
                coef.b[1] = 0;
                coef.b[2] = 0;
            }

            if ((this.order & 1) == 1)
            {
                Coefficient coef = coefs[this.order / 2];

                coef.a[0] = 1;
                coef.a[1] = 1;
                coef.a[2] = 0;
                coef.b[0] = 1;
                coef.b[1] = 0;
                coef.b[2] = 0;
            }
        }
        public static void ToPeqCoefficient(Coefficient digital, ParametricEqualizer.Parameter peq)
        {
            double[] a = digital.a;
            double[] b = digital.b;

            peq.c  = b[0] / a[0];
            peq.a1 = -a[1] / a[0];
            peq.a2 = -a[2] / a[0];
            peq.b1 = b[1] / b[0];
            peq.b2 = b[2] / b[0];
        }
        /// <summary>
        /// ディジタル LPF 係数を計算。
        /// </summary>
        /// <param name="w">カットオフ周波数</param>
        /// <returns>ディジタル LPF 係数</returns>
        public Coefficient[] GetDigitalLPF(double w)
        {
            Coefficient[] coefs = new Coefficient[this.Length];
            for (int i = 0; i < coefs.Length; ++i)
            {
                coefs[i] = new Coefficient();
            }

            this.GetDigitalLPF(w, coefs);

            return(coefs);
        }
        /// <summary>
        /// アナログプロトタイプフィルタの係数を計算。
        /// </summary>
        /// <returns>AP フィルタ係数</returns>
        public Coefficient[] GetAnalogPrototype()
        {
            Coefficient[] coefs = new Coefficient[this.Length];
            for (int i = 0; i < coefs.Length; ++i)
            {
                coefs[i] = new Coefficient();
            }

            this.GetAnalogPrototype(coefs);

            return(coefs);
        }
Example #7
0
        public override void GetAnalogPrototype(Coefficient[] coefs)
//		public void GetAnalogPrototype2(Coefficient[] coefs)
        {
            double m1  = this.m1;
            double m1p = 1 - this.m1;

            double Kk1  = Elliptic.K(m1);
            double Kk1p = Elliptic.K(m1p);

            double m  = Elliptic.InverseQ(Math.Exp(-Math.PI * Kk1p / (this.order * Kk1)));
            double mp = 1 - m;
            double Kk = Elliptic.K(m);

            double phi, sn_p, cn_p, dn_p;
            double v = Elliptic.F(Math.Atan(1 / this.epsilon), m1p) * Kk / (this.order * Kk1);

            Elliptic.Jacobi(v, mp, out phi, out sn_p, out cn_p, out dn_p);

            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                Coefficient coef = coefs[j];

                double sn, cn, dn;
                double u = Kk * (double)i / this.order;
                Elliptic.Jacobi(u, m, out phi, out sn, out cn, out dn);

                double denom = 1 - dn * dn * sn_p * sn_p;
                double re    = -cn * dn * sn_p * cn_p / denom;
                double im    = -sn * dn_p / denom;

                double alpha = -2 * re;
                double beta  = re * re + im * im;
                double gamma = 1 / (m * sn * sn);

                coef.a[0] = 1; coef.a[1] = alpha / beta; coef.a[2] = 1 / beta;
                coef.b[0] = 1; coef.b[1] = 0;            coef.b[2] = 1 / gamma;
            }

            if ((this.order & 1) == 1)
            {
                Coefficient coef = coefs[this.order / 2];

                double denom = 1 - sn_p * sn_p;
                double re    = -sn_p * cn_p / denom;

                coef.a[0] = 1; coef.a[1] = -1 / re; coef.a[2] = 0;
                coef.b[0] = 1; coef.b[1] = 0;       coef.b[2] = 0;
            }
        }
        public override void GetAnalogPrototype(Coefficient[] coefs)
        {
            double beta0 = this.Beta0;

            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                Coefficient coef = coefs[j];

                double sin, cos;
                GetSinCos(Math.PI / 2 * (double)i / this.order, out sin, out cos);

                double alpha = 2 * beta0 * cos;
                double beta  = sin;
                beta *= beta;
                double gamma = beta;
                beta += beta0 * beta0;

                if (this.kind)
                {
                    coef.a[0] = 1; coef.a[1] = alpha; coef.a[2] = beta;
                    coef.b[0] = 1; coef.b[1] = 0;     coef.b[2] = gamma;
                }
                else
                {
                    coef.a[0] = beta; coef.a[1] = alpha; coef.a[2] = 1;
                    coef.b[0] = beta; coef.b[1] = 0;     coef.b[2] = 0;
                }
            }

            if ((this.order & 1) == 1)
            {
                Coefficient coef = coefs[this.order / 2];

                if (this.kind)
                {
                    coef.a[0] = 1; coef.a[1] = beta0; coef.a[2] = 0;
                    coef.b[0] = 1; coef.b[1] = 0;     coef.b[2] = 0;
                }
                else
                {
                    coef.a[0] = beta0; coef.a[1] = 1; coef.a[2] = 0;
                    coef.b[0] = beta0; coef.b[1] = 0; coef.b[2] = 0;
                }
            }
        }
        public static void BilinearTransform(Coefficient ap, Coefficient digital, double sin, double cos)
        {
            if (ap.a[2] != 0 || ap.b[2] != 0)
            {
                BilinearTransform(
                    ap.a[0], ap.a[1], ap.a[2],
                    out digital.a[0], out digital.a[1], out digital.a[2],
                    sin, cos);
                BilinearTransform(
                    ap.b[0], ap.b[1], ap.b[2],
                    out digital.b[0], out digital.b[1], out digital.b[2],
                    sin, cos);
                return;
            }

            digital.a[2] = 0;
            digital.b[2] = 0;

            if (ap.a[1] != 0 || ap.b[1] != 0)
            {
                BilinearTransform(
                    ap.a[0], ap.a[1],
                    out digital.a[0], out digital.a[1],
                    sin, cos);
                BilinearTransform(
                    ap.b[0], ap.b[1],
                    out digital.b[0], out digital.b[1],
                    sin, cos);
                return;
            }

            digital.a[1] = 0;
            digital.b[1] = 0;

            digital.a[0] = ap.a[0];
            digital.b[0] = ap.b[0];
        }
        //public override void GetDigitalLPF(double w, Coefficient[] coefs)
        public void GetDigitalLPF2(double w, Coefficient[] coefs)
        {
            double sin, cos;

            GetSinCos(w, out sin, out cos);
            double b0 = (1 - cos) / 2;
            double a1 = -2 * cos;

            double nu = (this.order & 1) == 1 ? 1 : 0.5;

            for (int i = this.order - 1, j = 0; i > 0; i -= 2, ++j)
            {
                Coefficient coef = coefs[j];

                double alpha = sin * Math.Cos(Math.PI / 2.0 * (double)i / this.order);

                coef.a[0] = 1 + alpha;
                coef.a[1] = a1;
                coef.a[2] = 1 - alpha;
                coef.b[0] = b0;
                coef.b[1] = 2 * b0;
                coef.b[2] = b0;
            }

            if ((this.order & 1) == 1)
            {
                Coefficient coef = coefs[this.order / 2];

                coef.a[0] = sin + cos + 1;
                coef.a[1] = sin - cos - 1;
                coef.a[2] = 0;
                coef.b[0] = sin;
                coef.b[1] = sin;
                coef.b[2] = 0;
            }
        }
		public override void GetAnalogPrototype(Coefficient[] coefs)
//		public void GetAnalogPrototype2(Coefficient[] coefs)
		{
			double m1 = this.m1;
			double m1p = 1 - this.m1;

			double Kk1  = Elliptic.K(m1);
			double Kk1p = Elliptic.K(m1p);

			double m    = Elliptic.InverseQ(Math.Exp(-Math.PI * Kk1p / (this.order * Kk1)));
			double mp   = 1 - m;
			double Kk   = Elliptic.K(m);

			double phi, sn_p, cn_p, dn_p;
			double v = Elliptic.F(Math.Atan(1 / this.epsilon), m1p) * Kk / (this.order * Kk1);
			Elliptic.Jacobi(v, mp, out phi, out sn_p, out cn_p, out dn_p);

			for(int i=this.order-1, j=0; i>0; i-=2, ++j)
			{
				Coefficient coef = coefs[j];

				double sn, cn, dn;
				double u = Kk * (double)i / this.order;
				Elliptic.Jacobi(u, m, out phi, out sn, out cn, out dn);

				double denom = 1 - dn * dn * sn_p * sn_p;
				double re = -cn * dn * sn_p * cn_p / denom;
				double im = -sn * dn_p / denom;

				double alpha = -2 * re;
				double beta  = re * re + im * im;
				double gamma = 1 / (m * sn * sn);

				coef.a[0] = 1; coef.a[1] = alpha / beta; coef.a[2] = 1 / beta;
				coef.b[0] = 1; coef.b[1] = 0;            coef.b[2] = 1 / gamma;
			}

			if((this.order & 1) == 1)
			{
				Coefficient coef = coefs[this.order / 2];

				double denom = 1 - sn_p * sn_p;
				double re = -sn_p * cn_p / denom;

				coef.a[0] = 1; coef.a[1] = -1 / re; coef.a[2] = 0;
				coef.b[0] = 1; coef.b[1] = 0;       coef.b[2] = 0;
			}
		}
Example #12
0
		/// <summary>
		/// ディジタル LPF 係数を計算。
		/// </summary>
		/// <param name="w">カットオフ周波数</param>
		/// <returns>ディジタル LPF 係数</returns>
		public Coefficient[] GetDigitalLPF(double w)
		{
			Coefficient[] coefs = new Coefficient[this.Length];
			for(int i=0; i<coefs.Length; ++i) coefs[i] = new Coefficient();

			this.GetDigitalLPF(w, coefs);

			return coefs;
		}
Example #13
0
		/// <summary>
		/// ディジタル LPF 係数を計算。
		/// </summary>
		/// <param name="w">カットオフ周波数</param>
		/// <param name="coefs">計算結果の格納先</param>
		public virtual void GetDigitalLPF(double w, Coefficient[] coefs)
		{
			this.GetAnalogPrototype(coefs);
			BilinearTransform(coefs, coefs, w);
		}
 public static void ZeroPoleToAnalogPrototype(ZeroPole zeropole, Coefficient coef)
 {
     RootToAnalogPrototype(zeropole.zero, coef.b);
     RootToAnalogPrototype(zeropole.pole, coef.a);
 }
Example #15
0
		public static void ZeroPoleToAnalogPrototype(ZeroPole zeropole, Coefficient coef)
		{
			RootToAnalogPrototype(zeropole.zero, coef.b);
			RootToAnalogPrototype(zeropole.pole, coef.a);
		}
		public override void GetAnalogPrototype(Coefficient[] coefs)
		{
			double beta0 = this.Beta0;

			for(int i=this.order-1, j=0; i>0; i-=2, ++j)
			{
				Coefficient coef = coefs[j];

				double sin, cos;
				GetSinCos(Math.PI / 2 * (double)i / this.order, out sin, out cos);

				double alpha = 2 * beta0 * cos;
				double beta = sin;
				beta *= beta;
				double gamma = beta;
				beta += beta0 * beta0;

				if(this.kind)
				{
					coef.a[0] = 1; coef.a[1] = alpha; coef.a[2] = beta;
					coef.b[0] = 1; coef.b[1] = 0;     coef.b[2] = gamma;
				}
				else
				{
					coef.a[0] = beta; coef.a[1] = alpha; coef.a[2] = 1;
					coef.b[0] = beta; coef.b[1] = 0;     coef.b[2] = 0;
				}
			}

			if((this.order & 1) == 1)
			{
				Coefficient coef = coefs[this.order / 2];

				if(this.kind)
				{
					coef.a[0] = 1; coef.a[1] = beta0; coef.a[2] = 0;
					coef.b[0] = 1; coef.b[1] = 0;     coef.b[2] = 0;
				}
				else
				{
					coef.a[0] = beta0; coef.a[1] = 1; coef.a[2] = 0;
					coef.b[0] = beta0; coef.b[1] = 0; coef.b[2] = 0;
				}
			}
		}
Example #17
0
		public static void ZeroPoleToAnalogPrototype(ZeroPole[] roots, Coefficient[] coefs)
		{
			for(int i=0; i<roots.Length; ++i)
			{
				ZeroPoleToAnalogPrototype(roots[i], coefs[i]);
			}
		}
Example #18
0
		public static void BilinearTransform(Coefficient ap, Coefficient digital, double sin, double cos)
		{
			if(ap.a[2] != 0 || ap.b[2] != 0)
			{
				BilinearTransform(
					ap.a[0], ap.a[1], ap.a[2],
					out digital.a[0], out digital.a[1], out digital.a[2],
					sin, cos);
				BilinearTransform(
					ap.b[0], ap.b[1], ap.b[2],
					out digital.b[0], out digital.b[1], out digital.b[2],
					sin, cos);
				return;
			}

			digital.a[2] = 0;
			digital.b[2] = 0;

			if(ap.a[1] != 0 || ap.b[1] != 0)
			{
				BilinearTransform(
					ap.a[0], ap.a[1],
					out digital.a[0], out digital.a[1],
					sin, cos);
				BilinearTransform(
					ap.b[0], ap.b[1],
					out digital.b[0], out digital.b[1],
					sin, cos);
				return;
			}

			digital.a[1] = 0;
			digital.b[1] = 0;

			digital.a[0] = ap.a[0];
			digital.b[0] = ap.b[0];
		}
Example #19
0
		public static void BilinearTransform(Coefficient[] ap, Coefficient[] digital, double w)
		{
			double sin, cos;
			GetSinCos(w, out sin, out cos);

			for(int i=0; i<ap.Length; ++i)
			{
				BilinearTransform(ap[i], digital[i], sin, cos);
			}
		}
Example #20
0
		/// <summary>
		/// アナログプロトタイプフィルタの係数を計算。
		/// </summary>
		/// <param name="coefs">計算結果の格納先</param>
		public virtual void GetAnalogPrototype(Coefficient[] coefs)
		{
			ZeroPole[] roots = this.GetZeroPole();
			ZeroPoleToAnalogPrototype(roots, coefs);
		}
Example #21
0
		/// <summary>
		/// アナログプロトタイプフィルタの係数を計算。
		/// </summary>
		/// <returns>AP フィルタ係数</returns>
		public Coefficient[] GetAnalogPrototype()
		{
			Coefficient[] coefs = new Coefficient[this.Length];
			for(int i=0; i<coefs.Length; ++i) coefs[i] = new Coefficient();

			this.GetAnalogPrototype(coefs);

			return coefs;
		}
Example #22
0
		public static void ToPeqCoefficient(Coefficient[] digital, ParametricEqualizer.Parameter[] peq)
		{
			for(int i=0; i<digital.Length; ++i)
			{
				ToPeqCoefficient(digital[i], peq[i]);
			}
		}
Example #23
0
		public static void ToPeqCoefficient(Coefficient digital, ParametricEqualizer.Parameter peq)
		{
			double[] a = digital.a;
			double[] b = digital.b;

			peq.c  =  b[0] / a[0];
			peq.a1 = -a[1] / a[0];
			peq.a2 = -a[2] / a[0];
			peq.b1 =  b[1] / b[0];
			peq.b2 =  b[2] / b[0];
		}