예제 #1
0
 /// <summary>
 /// 0番のアルゴリズムを定義します。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public static double ZeroSerial(IList <FMOperator> op, ref object tag, FMSynthesisState state)
 {
     if (op.Count < 4)
     {
         throw new InvalidOperationException("OPN系アルゴリズムではオペレータは4つ必要です");
     }
     return(_serial(op, ref tag, state));
 }
예제 #2
0
 /// <summary>
 /// 最初のチャンネルをキャリア、次のチャンネルをモジュレータとして変調します。
 /// それ以降のオペレータは無視されます。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public static double PairModulationAlgorithm(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     var s = state;
     if (op.Count < 2) throw new ArgumentException("オペレータは最低2つ必要です");
     var mod = op[1].GetState(s);
     s.State = mod;
     return op[0].GetState(s) / op[0].ModulationIndex;
 }
예제 #3
0
        /// <summary>
        /// ホールドし始めた時刻を0として、
        /// 指定した時刻のオペレータ出力を取得します。
        /// </summary>
        /// <param name="state">合成状態の情報</param>
        /// <returns>オペレータ出力</returns>
        public double GetState(FMSynthesisState state)
        {
            var env   = GetEnvelopeState(state.Time, state.IsHolding);
            var myfr  = state.Frequency * Detune;
            var ctime = 1.0 / myfr;
            var pos   = ((state.Time) % ctime) / ctime;

            return(ModulationIndex * Oscillator(pos, state.State) * env);
        }
예제 #4
0
 /// <summary>
 /// 全てのチャンネルを独立して計算し、
 /// 全て同じ比率でミックスします。
 /// <para>厳密にはこれはFM音源にはなりません。</para>
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public static double ParallelMixAlgorithm(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     var mix = 0.0;
     var max = op.Sum(p => p.ModulationIndex);
     foreach (var i in op)
     {
         mix += i.GetState(state);
     }
     return mix / max;
 }
예제 #5
0
 /// <summary>
 /// 先頭をキャリア、それ以降をモジュレータとして、
 /// 全て直列に接続して変調します。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public static double SerialModulationAlgorithm(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     var s = state;
     var mix = 0.0;
     for (int i = op.Count - 1; i >= 0; i--)
     {
         mix = op[i].GetState(s);
         s.State = mix;
     }
     return mix / op[0].ModulationIndex;
 }
예제 #6
0
                /// <summary>
                /// 現在の状態でのアルゴリズムを定義します。
                /// </summary>
                /// <param name="op">オペレーターのリスト</param>
                /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
                /// <param name="state">合成状態の情報</param>
                /// <returns>状態</returns>
                public double Algorithm(IList <FMOperator> op, ref object tag, FMSynthesisState state)
                {
                    var s   = state;
                    var mix = 0.0;

                    for (int i = op.Count - 1; i >= 0; i--)
                    {
                        if (i == FeedbackChannel)
                        {
                            var fbs = state;
                            fbs.Time -= FeedbackReferenceBackingtime;
                            s.State  += op[i].GetState(fbs);
                        }
                        mix     = op[i].GetState(s);
                        s.State = mix;
                    }
                    return(mix / op[0].ModulationIndex);
                }
예제 #7
0
                /// <summary>
                /// 現在の状態でのアルゴリズムを定義します。
                /// </summary>
                /// <param name="op">オペレーターのリスト</param>
                /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
                /// <param name="state">合成状態の情報</param>
                /// <returns>状態</returns>
                public double Algorithm(IList <FMOperator> op, ref object tag, FMSynthesisState state)
                {
                    var s   = state;
                    var mix = 0.0;

                    for (int i = op.Count - 1; i >= 0; i--)
                    {
                        if (i == FeedbackChannel)
                        {
                            s.State += PreviousFeedbackState;
                        }
                        mix = op[i].GetState(s);
                        if (i == FeedbackChannel)
                        {
                            PreviousFeedbackState = mix;
                        }
                        s.State = mix;
                    }
                    return(mix / op[0].ModulationIndex);
                }
예제 #8
0
        /// <summary>
        /// 先頭をキャリア、それ以降をモジュレータとして、
        /// 全て直列に接続して変調します。
        /// </summary>
        /// <param name="op">オペレーターのリスト</param>
        /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
        /// <param name="state">合成状態の情報</param>
        /// <returns>状態</returns>
        public static double SerialModulationAlgorithm(IList <FMOperator> op, ref object tag, FMSynthesisState state)
        {
            var s   = state;
            var mix = 0.0;

            for (int i = op.Count - 1; i >= 0; i--)
            {
                mix     = op[i].GetState(s);
                s.State = mix;
            }
            return(mix / op[0].ModulationIndex);
        }
예제 #9
0
        /// <summary>
        /// 全てのチャンネルを独立して計算し、
        /// 全て同じ比率でミックスします。
        /// <para>厳密にはこれはFM音源にはなりません。</para>
        /// </summary>
        /// <param name="op">オペレーターのリスト</param>
        /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
        /// <param name="state">合成状態の情報</param>
        /// <returns>状態</returns>
        public static double ParallelMixAlgorithm(IList <FMOperator> op, ref object tag, FMSynthesisState state)
        {
            var mix = 0.0;
            var max = op.Sum(p => p.ModulationIndex);

            foreach (var i in op)
            {
                mix += i.GetState(state);
            }
            return(mix / max);
        }
예제 #10
0
            /// <summary>
            /// 3番のアルゴリズムを定義します。
            /// </summary>
            /// <param name="op">オペレーターのリスト</param>
            /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
            /// <param name="state">合成状態の情報</param>
            /// <returns>状態</returns>
            public static double ThreeSingleAndSerial(IList <FMOperator> op, ref object tag, FMSynthesisState state)
            {
                if (op.Count < 4)
                {
                    throw new InvalidOperationException("OPN系アルゴリズムではオペレータは4つ必要です");
                }
                var fbs = state;

                fbs.Time -= 0.001;
                var ch3 = op[1].GetState(state);
                var ch1 = op[3].GetState(fbs);

                state.State = ch1;
                var ch2 = op[2].GetState(state);

                state.State = ch2 + ch3;
                state.State = (ch2 + ch3);
                return(op[0].GetState(state));
            }
예제 #11
0
        /// <summary>
        /// 最初のチャンネルをキャリア、次のチャンネルをモジュレータとして変調します。
        /// それ以降のオペレータは無視されます。
        /// </summary>
        /// <param name="op">オペレーターのリスト</param>
        /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
        /// <param name="state">合成状態の情報</param>
        /// <returns>状態</returns>
        public static double PairModulationAlgorithm(IList <FMOperator> op, ref object tag, FMSynthesisState state)
        {
            var s = state;

            if (op.Count < 2)
            {
                throw new ArgumentException("オペレータは最低2つ必要です");
            }
            var mod = op[1].GetState(s);

            s.State = mod;
            return(op[0].GetState(s) / op[0].ModulationIndex);
        }
예제 #12
0
파일: FMOperator.cs 프로젝트: kb10uy/Kb10uy
 /// <summary>
 /// ホールドし始めた時刻を0として、
 /// 指定した時刻のオペレータ出力を取得します。
 /// </summary>
 /// <param name="state">合成状態の情報</param>
 /// <returns>オペレータ出力</returns>
 public double GetState(FMSynthesisState state)
 {
     var env = GetEnvelopeState(state.Time, state.IsHolding);
     var myfr = state.Frequency * Detune;
     var ctime = 1.0 / myfr;
     var pos = ((state.Time) % ctime) / ctime;
     return ModulationIndex * Oscillator(pos, state.State) * env;
 }
예제 #13
0
 /// <summary>
 /// 0番のアルゴリズムを定義します。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public static double ZeroSerial(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     if (op.Count < 4) throw new InvalidOperationException("OPN系アルゴリズムではオペレータは4つ必要です");
     return _serial(op, ref tag, state);
 }
예제 #14
0
            /// <summary>
            /// 2番のアルゴリズムを定義します。
            /// </summary>
            /// <param name="op">オペレーターのリスト</param>
            /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
            /// <param name="state">合成状態の情報</param>
            /// <returns>状態</returns>
            public static double TwoFeedbackAndSerial(IList<FMOperator> op, ref object tag, FMSynthesisState state)
            {
                if (op.Count < 4) throw new InvalidOperationException("OPN系アルゴリズムではオペレータは4つ必要です");
                var fbs = state;
                fbs.Time -= 0.001;

                var ch2 = op[2].GetState(state);
                state.State = ch2;
                var ch3 = op[1].GetState(state);
                var ch1 = op[3].GetState(fbs);
                state.State = (ch1 + ch3);
                return op[0].GetState(state);
            }
예제 #15
0
 /// <summary>
 /// 現在の状態でのアルゴリズムを定義します。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public double Algorithm(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     var s = state;
     var mix = 0.0;
     for (int i = op.Count - 1; i >= 0; i--)
     {
         if (i == FeedbackChannel)
         {
             s.State += PreviousFeedbackState;
         }
         mix = op[i].GetState(s);
         if (i == FeedbackChannel)
         {
             PreviousFeedbackState = mix;
         }
         s.State = mix;
     }
     return mix / op[0].ModulationIndex;
 }
예제 #16
0
 /// <summary>
 /// 現在の状態でのアルゴリズムを定義します。
 /// </summary>
 /// <param name="op">オペレーターのリスト</param>
 /// <param name="tag">フィードバックの保持など自由に使えるタグオブジェクト</param>
 /// <param name="state">合成状態の情報</param>
 /// <returns>状態</returns>
 public double Algorithm(IList<FMOperator> op, ref object tag, FMSynthesisState state)
 {
     var s = state;
     var mix = 0.0;
     for (int i = op.Count - 1; i >= 0; i--)
     {
         if (i == FeedbackChannel)
         {
             var fbs = state;
             fbs.Time -= FeedbackReferenceBackingtime;
             s.State += op[i].GetState(fbs);
         }
         mix = op[i].GetState(s);
         s.State = mix;
     }
     return mix / op[0].ModulationIndex;
 }