/// <summary>
 /// コンストラクタ(フィルタ係数をセット)
 /// </summary>
 /// <param name="coeff">フィルタ係数</param>
 public Filtering(FilterCoefficient coeff)
 {
     Coeff = coeff;
 }
Exemple #2
0
        /// <summary>
        /// 双一次変換
        /// </summary>
        /// <param name="order">フィルタ次数</param>
        /// <param name="Wa">フィルタの正規化カットオフ周波数または中心周波数(ナイキスト周波数で正規化)</param>
        /// <param name="aAnalog">アナログフィルタの分子の係数</param>
        /// <param name="bAnalog">アナログフィルタの分母の係数</param>
        /// <param name="filterType">フィルタの種類 FilterTypeで選択</param>
        /// <returns>FilterCoefficient 双一次変換されたデジタルフィルタの係数</returns>
        private static FilterCoefficient BilinearTransform(int order, double Wa, double[,] aAnalog, double[,] bAnalog, FilterType filterType)
        {
            // 双一次変換の格納用配列
            var a = new double[aAnalog.GetLength(0), aAnalog.GetLength(1)];
            var b = new double[bAnalog.GetLength(0), bAnalog.GetLength(1)];

            //フィルタの次数の偶数奇数判定
            bool odd = order % 2 != 0;

            // セクション数
            int sections = aAnalog.GetLength(0);

            // 双一次変換の変換係数
            double h = 1 / (Wa * Math.PI / 2);

            for (var k = 0; k < sections; k++)
            {
                double BB;

                if (k == 0 && odd && (filterType == FilterType.Low || filterType == FilterType.High))
                {
                    //ローパスハイパスの奇数一次のみ、1次のセクションとなる
                    // 分母の 係数b0の逆数
                    BB      = 1 / (h + bAnalog[0, 0]);
                    a[k, 0] = BB * (aAnalog[0, 1] * h + aAnalog[0, 0]);
                    a[k, 1] = BB * (-aAnalog[0, 1] * h + aAnalog[0, 0]);
                    a[k, 2] = 0;

                    b[k, 0] = BB * (h + bAnalog[0, 0]);
                    b[k, 1] = BB * (-h + bAnalog[0, 0]);
                    b[k, 2] = 0;
                }
                else
                {
                    // 分母の 係数b0の逆数
                    BB = 1 / (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]);

                    a[k, 0] = BB * (aAnalog[k, 2] * h * h + aAnalog[k, 1] * h + aAnalog[k, 0]);
                    a[k, 1] = BB * 2 * (-aAnalog[k, 2] * h * h + aAnalog[k, 0]);
                    a[k, 2] = BB * (aAnalog[k, 2] * h * h - aAnalog[k, 1] * h + aAnalog[k, 0]);

                    b[k, 0] = BB * (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]);
                    b[k, 1] = BB * (-2 * h * h + 2 * bAnalog[k, 2]);
                    b[k, 2] = BB * (h * h - bAnalog[k, 1] * h + bAnalog[k, 2]);
                }
            }

            //ゲインを最初のセクションに集める
            double gain = 1;

            for (var k = 0; k < sections; k++)
            {
                gain    *= a[k, 0];
                a[k, 2] /= a[k, 0];
                a[k, 1] /= a[k, 0];
                a[k, 0] /= a[k, 0];
            }
            a[0, 0] *= gain;
            a[0, 1] *= gain;
            a[0, 2] *= gain;

            var filterValue = new FilterCoefficient();

            filterValue.Numerator   = a;
            filterValue.Denominator = b;
            filterValue.Sections    = sections;
            filterValue.Order       = order;

            return(filterValue);
        }