Example #1
0
            /* update convolver state with accent information */
            public SynthErrorCodes TrackUpdateState(
                ref AccentRec Accents,
                SynthParamRec SynthParams)
            {
                SynthErrorCodes error;

                error = ScalarParamEval(
                    this.DirectGain,
                    ref Accents,
                    SynthParams,
                    out this.CurrentDirectGain);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                error = ScalarParamEval(
                    this.ProcessedGain,
                    ref Accents,
                    SynthParams,
                    out this.CurrentProcessedGain);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                return(SynthErrorCodes.eSynthDone);
            }
Example #2
0
 /* retrigger effect envelopes from the origin point */
 public void OscRetriggerEnvelopes(
     ref AccentRec NewAccents,
     double NewHurryUp,
     double NewInitialFrequency,
     bool ActuallyRetrigger,
     SynthParamRec SynthParams)
 {
     for (int i = 0; i < this.paramCount; i += 1)
     {
         EnvelopeRetriggerFromOrigin(
             this.params_Osc[i].Envelope,
             ref NewAccents,
             NewInitialFrequency,
             1,
             NewHurryUp,
             ActuallyRetrigger,
             SynthParams);
         LFOGeneratorRetriggerFromOrigin(
             this.params_Osc[i].LFO,
             ref NewAccents,
             NewInitialFrequency,
             NewHurryUp,
             1,
             1,
             ActuallyRetrigger,
             SynthParams);
     }
 }
        /* update control state for effects processors.  this is called once per envelope */
        /* tick, and constitutes the first half of the control-update cycle. */
        /* returns true if successful, or false if it failed. */
        public static SynthErrorCodes UpdateStateTrackEffectGenerator(
            TrackEffectGenRec Generator,
            SynthParamRec SynthParams)
        {
            if (Generator.List != null)
            {
                AccentRec Accents = new AccentRec();
                InitializeAccent(
                    ref Accents,
                    Generator.Accents0.Current,
                    Generator.Accents1.Current,
                    Generator.Accents2.Current,
                    Generator.Accents3.Current,
                    Generator.Accents4.Current,
                    Generator.Accents5.Current,
                    Generator.Accents6.Current,
                    Generator.Accents7.Current);

                OneEffectRec Scan = Generator.List;
                while (Scan != null)
                {
                    SynthErrorCodes error = Scan.u.TrackUpdateState(
                        ref Accents,
                        SynthParams);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        return(error);
                    }
                    Scan = Scan.Next;
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
Example #4
0
            /* retrigger effect envelopes from the origin point */
            public void OscRetriggerEnvelopes(
                ref AccentRec NewAccents,
                double NewHurryUp,
                double NewInitialFrequency,
                bool ActuallyRetrigger,
                SynthParamRec SynthParams)
            {
                EnvelopeRetriggerFromOrigin(
                    this.Oscillator.InputScalingEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    ActuallyRetrigger,
                    SynthParams);
                EnvelopeRetriggerFromOrigin(
                    this.Oscillator.OutputScalingEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    ActuallyRetrigger,
                    SynthParams);
                EnvelopeRetriggerFromOrigin(
                    this.Oscillator.WaveTableIndexEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    ActuallyRetrigger,
                    SynthParams);

                LFOGeneratorRetriggerFromOrigin(
                    this.Oscillator.InputScalingLFO,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    ActuallyRetrigger,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    this.Oscillator.OutputScalingLFO,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    ActuallyRetrigger,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    this.Oscillator.WaveTableIndexLFO,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    ActuallyRetrigger,
                    SynthParams);
            }
Example #5
0
        /* scale one accent and add another to it.  source and target may be the same. */
        public static void AccentAdd(
            double LeftScale,
            ref AccentRec Left,
            ref AccentRec Right,
            ref AccentRec Target)
        {
            double Left0 = Left.Accent0;
            double Left1 = Left.Accent1;
            double Left2 = Left.Accent2;
            double Left3 = Left.Accent3;
            double Left4 = Left.Accent4;
            double Left5 = Left.Accent5;
            double Left6 = Left.Accent6;
            double Left7 = Left.Accent7;

            double Right0 = Right.Accent0;
            double Right1 = Right.Accent1;
            double Right2 = Right.Accent2;
            double Right3 = Right.Accent3;
            double Right4 = Right.Accent4;
            double Right5 = Right.Accent5;
            double Right6 = Right.Accent6;
            double Right7 = Right.Accent7;

            Target.Accent0 = LeftScale * Left0 + Right0;
            Target.Accent1 = LeftScale * Left1 + Right1;
            Target.Accent2 = LeftScale * Left2 + Right2;
            Target.Accent3 = LeftScale * Left3 + Right3;
            Target.Accent4 = LeftScale * Left4 + Right4;
            Target.Accent5 = LeftScale * Left5 + Right5;
            Target.Accent6 = LeftScale * Left6 + Right6;
            Target.Accent7 = LeftScale * Left7 + Right7;
        }
Example #6
0
        /* retrigger effect envelopes from the origin point */
        public static void OscEffectGeneratorRetriggerFromOrigin(
            OscEffectGenRec Generator,
            ref AccentRec Accents,
            double NewInitialFrequency,
            double HurryUp,
            bool ActuallyRetrigger,
            SynthParamRec SynthParams)
        {
            int count = Generator.count;

            IOscillatorEffect[] List = Generator.List;
            if (unchecked ((uint)count > (uint)List.Length))
            {
                Debug.Assert(false);
                throw new IndexOutOfRangeException();
            }

            for (int i = 0; i < count; i++)
            {
                List[i].OscRetriggerEnvelopes(
                    ref Accents,
                    HurryUp,
                    NewInitialFrequency,
                    ActuallyRetrigger,
                    SynthParams);
            }
        }
        /* do a scalar param evaluation */
        public static SynthErrorCodes StaticEval(
            double X,
            PcodeRec SpecifiedFormula,
            ref AccentRec CurrentParameters,
            SynthParamRec SynthParams,
            out double ResultOut)
        {
            ResultOut = 0;

            int initialCapacity = 1 /*retval*/ + 8 + 1 /*t*/ + 1 /*x*/ + 1 /*bpm*/;

            SynthParams.FormulaEvalContext.EmptyParamStackEnsureCapacity(initialCapacity);

            StackElement[] Stack;
            int            StackNumElements;

            SynthParams.FormulaEvalContext.GetRawStack(out Stack, out StackNumElements);

            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent0;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent1;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent2;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent3;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent4;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent5;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent6;
            Stack[StackNumElements++].Data.Double = CurrentParameters.Accent7;

            Stack[StackNumElements++].Data.Double = SynthParams.dElapsedTimeInSeconds;  /* t */

            Stack[StackNumElements++].Data.Double = X;                                  /* x */

            Stack[StackNumElements++].Data.Double = SynthParams.dCurrentBeatsPerMinute; /* bpm */

            StackNumElements++;                                                         /* return address placeholder */

            SynthParams.FormulaEvalContext.UpdateRawStack(Stack, StackNumElements);

            EvalErrInfoRec ErrorInfo;
            EvalErrors     Error = PcodeSystem.EvaluatePcode(
                SynthParams.FormulaEvalContext,
                SpecifiedFormula,
                SynthParams.CodeCenter,
                out ErrorInfo,
                PcodeExternsNull.Default,
                ref SynthParams.pcodeThreadContext);

            if (Error != EvalErrors.eEvalNoError)
            {
                SynthParams.ErrorInfo.ErrorEx           = SynthErrorSubCodes.eSynthErrorExUserParamFunctionEvalError;
                SynthParams.ErrorInfo.UserEvalErrorCode = Error;
                SynthParams.ErrorInfo.UserEvalErrorInfo = ErrorInfo;
                return(SynthErrorCodes.eSynthErrorEx);
            }
            Debug.Assert(SynthParams.FormulaEvalContext.GetStackNumElements() == initialCapacity); // args - retaddr + return value

            ResultOut = SynthParams.FormulaEvalContext.GetStackDouble(initialCapacity - 1);

            return(SynthErrorCodes.eSynthDone);
        }
 /* initialize the scalar parameter evaluator */
 public static void InitScalarParamEval(
     double SpecifiedValue,
     ref AccentRec SpecifiedAccentModifiers,
     PcodeRec SpecifiedFormula,
     out ScalarParamEvalRec EvalOut)
 {
     EvalOut = new ScalarParamEvalRec();
     EvalOut.SpecifiedValue           = SpecifiedValue;
     EvalOut.SpecifiedAccentModifiers = SpecifiedAccentModifiers;
     EvalOut.SpecifiedFormula         = SpecifiedFormula;
 }
Example #9
0
            /* update nonlinear state with accent information */
            public SynthErrorCodes TrackUpdateState(
                ref AccentRec Accents,
                SynthParamRec SynthParams)
            {
                SynthErrorCodes error;
                double          DoubleTemp;

                error = ScalarParamEval(
                    this.Track.InputScaling,
                    ref Accents,
                    SynthParams,
                    out this.CurrentInputScaling);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                error = ScalarParamEval(
                    this.Track.OutputScaling,
                    ref Accents,
                    SynthParams,
                    out this.CurrentOutputScaling);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                error = ScalarParamEval(
                    this.Track.WaveTableIndex,
                    ref Accents,
                    SynthParams,
                    out DoubleTemp);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }
                DoubleTemp = DoubleTemp * this.NumberOfTablesMinus1;
                if (DoubleTemp < 0)
                {
                    DoubleTemp = 0;
                }
                else if (DoubleTemp > this.NumberOfTablesMinus1)
                {
                    DoubleTemp = this.NumberOfTablesMinus1;
                }
                this.CurrentWaveTableIndex = DoubleTemp;

                return(SynthErrorCodes.eSynthDone);
            }
Example #10
0
        /* set accent member to value */
        public static void SetAccentMemberValue(
            ref AccentRec Accent,
            int Index,
            double Value)
        {
            switch (Index)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case 1:
                Accent.Accent0 = Value;
                break;

            case 2:
                Accent.Accent1 = Value;
                break;

            case 3:
                Accent.Accent2 = Value;
                break;

            case 4:
                Accent.Accent3 = Value;
                break;

            case 5:
                Accent.Accent4 = Value;
                break;

            case 6:
                Accent.Accent5 = Value;
                break;

            case 7:
                Accent.Accent6 = Value;
                break;

            case 8:
                Accent.Accent7 = Value;
                break;
            }
            if (Value != 0)
            {
                Accent.AnyNonZero = true;
            }
        }
 /* get current accents */
 public static void TrackEffectGetCurrentAccents(
     TrackEffectGenRec Generator,
     out AccentRec TrackAccentsOut)
 {
     TrackAccentsOut = new AccentRec();
     InitializeAccent(
         ref TrackAccentsOut,
         Generator.Accents0.Current,
         Generator.Accents1.Current,
         Generator.Accents2.Current,
         Generator.Accents3.Current,
         Generator.Accents4.Current,
         Generator.Accents5.Current,
         Generator.Accents6.Current,
         Generator.Accents7.Current);
 }
Example #12
0
        /* compute accent sum */
        public static double AccentProductAdd(
            double AddMe,
            ref AccentRec Left,
            ref AccentRec Right)
        {
#if DEBUG
            // zero flag violation
            if (!Right.AnyNonZero && ((Right.Accent0 != 0) || (Right.Accent1 != 0) ||
                                      (Right.Accent2 != 0) || (Right.Accent3 != 0) || (Right.Accent4 != 0) ||
                                      (Right.Accent5 != 0) || (Right.Accent6 != 0) || (Right.Accent7 != 0)))
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
            if (!Left.AnyNonZero && ((Left.Accent0 != 0) || (Left.Accent1 != 0) ||
                                     (Left.Accent2 != 0) || (Left.Accent3 != 0) || (Left.Accent4 != 0) ||
                                     (Left.Accent5 != 0) || (Left.Accent6 != 0) || (Left.Accent7 != 0)))
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
#endif

            if (!Right.AnyNonZero && !Left.AnyNonZero)
            {
                return(AddMe);
            }
            else
            {
                return(AddMe
                       + Left.Accent0 * Right.Accent0
                       + Left.Accent1 * Right.Accent1
                       + Left.Accent2 * Right.Accent2
                       + Left.Accent3 * Right.Accent3
                       + Left.Accent4 * Right.Accent4
                       + Left.Accent5 * Right.Accent5
                       + Left.Accent6 * Right.Accent6
                       + Left.Accent7 * Right.Accent7);
            }
        }
Example #13
0
 /* set contained values for accent structure */
 public static void InitializeAccent(
     ref AccentRec Accent,
     double Accent1,
     double Accent2,
     double Accent3,
     double Accent4,
     double Accent5,
     double Accent6,
     double Accent7,
     double Accent8)
 {
     Accent.Accent0    = Accent1;
     Accent.Accent1    = Accent2;
     Accent.Accent2    = Accent3;
     Accent.Accent3    = Accent4;
     Accent.Accent4    = Accent5;
     Accent.Accent5    = Accent6;
     Accent.Accent6    = Accent7;
     Accent.Accent7    = Accent8;
     Accent.AnyNonZero = (Accent1 != 0) || (Accent2 != 0) || (Accent3 != 0) || (Accent4 != 0) ||
                         (Accent5 != 0) || (Accent6 != 0) || (Accent7 != 0) || (Accent8 != 0);
 }
        /* do a scalar param evaluation */
        public static SynthErrorCodes ScalarParamEval(
            ScalarParamEvalRec Eval,
            ref AccentRec CurrentParameters,
            SynthParamRec SynthParams,
            out double ResultOut)
        {
            ResultOut = 0;

            double Temp = Eval.SpecifiedValue;

            /* ordering is somewhat arbitrary because if user wants it the other way, he can */
            /* always write it into the formula. */

            /* apply accent first */
            Temp = AccentProductAdd(
                Temp,
                ref CurrentParameters,
                ref Eval.SpecifiedAccentModifiers);

            /* compute formula second. */
            if (Eval.SpecifiedFormula != null)
            {
                SynthErrorCodes Error = StaticEval(
                    Temp,
                    Eval.SpecifiedFormula,
                    ref CurrentParameters,
                    SynthParams,
                    out Temp);
                if (Error != SynthErrorCodes.eSynthDone)
                {
                    return(Error);
                }
            }

            ResultOut = Temp;

            return(SynthErrorCodes.eSynthDone);
        }
Example #15
0
            /* update user effect processor state with accent information */
            public SynthErrorCodes TrackUpdateState(
                ref AccentRec Accents,
                SynthParamRec SynthParams)
            {
                double[] paramResultsTemp = this.paramResultsPrevious;
                this.paramResultsPrevious = this.paramResults;
                this.paramResults         = paramResultsTemp;

                for (int i = 0; i < this.paramCount; i += 1)
                {
                    SynthErrorCodes error = ScalarParamEval(
                        this.params_Track[i].Eval,
                        ref Accents,
                        SynthParams,
                        out this.paramResults[i]);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        return(error);
                    }
                }

                return(SynthErrorCodes.eSynthDone);
            }
Example #16
0
 public void OscRetriggerEnvelopes(ref AccentRec NewAccents, double NewHurryUp, double NewInitialFrequency, bool ActuallyRetrigger, SynthParamRec SynthParams)
 {
 }
Example #17
0
 public PluggableEvaluableParam(double constValue, AccentRec accent, PcodeRec formula)
 {
     this.constValue = constValue;
     this.accent     = accent;
     this.formula    = formula;
 }
Example #18
0
 public SynthErrorCodes TrackUpdateState(ref AccentRec Accents, SynthParamRec SynthParams)
 {
     return(SynthErrorCodes.eSynthDone);
 }
Example #19
0
 /* create new zeroed accent structure */
 public static void InitializeAccentZero(out AccentRec Accent)
 {
     Accent = new AccentRec();
 }
Example #20
0
            /* create a new oscillator user effect processor */
            public static SynthErrorCodes NewOscUserEffectProc(
                UserEffectSpecRec Template,
                ref AccentRec Accents,
                double HurryUp,
                double InitialFrequency,
                double FreqForMultisampling,
                out int PreOriginTimeOut,
                PlayTrackInfoRec TrackInfo,
                SynthParamRec SynthParams,
                out UserEffectProcRec effectOut)
            {
                effectOut        = null;
                PreOriginTimeOut = 0;

                /* allocate structure */
                UserEffectProcRec Proc = new UserEffectProcRec();

                SynthErrorCodes error = UserEffectSharedInit(Proc, Template, SynthParams);

                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                Proc.params_Osc = new UserEffectParamRec_Osc[Proc.paramCount];

                /* initialize argument evaluators */
                int MaxPreOrigin = 0;

                for (int i = 0; i < Proc.paramCount; i += 1)
                {
                    int OnePreOrigin;

                    Proc.params_Osc[i].Envelope = NewEnvelopeStateRecord(
                        GetUserEffectSpecParamEnvelope(Template, i),
                        ref Accents,
                        InitialFrequency,
                        1,
                        HurryUp,
                        out OnePreOrigin,
                        _PlayTrackParamGetter,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }

                    Proc.params_Osc[i].LFO = NewLFOGenerator(
                        GetUserEffectSpecParamLFO(Template, i),
                        out OnePreOrigin,
                        ref Accents,
                        InitialFrequency,
                        HurryUp,
                        1,
                        1,
                        FreqForMultisampling,
                        _PlayTrackParamGetter,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                }

                PreOriginTimeOut = MaxPreOrigin;

                for (int i = 0; i < Template.Items.Length; i++)
                {
                    if (Template.Items[i].Smoothed)
                    {
                        if (IsLFOSampleAndHold(Proc.params_Osc[i].LFO))
                        {
                            // degrade sample & hold, since smoothing is probably not what was intended
                            Proc.smoothingBuffers[i].degraded = true;
                        }
                    }
                }

                effectOut = Proc;
                return(SynthErrorCodes.eSynthDone);
            }
Example #21
0
            /* create a new oscillator nonlinear processor */
            public static NLProcUnifiedRec NewOscNLProcProcessor(
                NonlinProcSpecRec Template,
                ref AccentRec Accents,
                double HurryUp,
                double InitialFrequency,
                double FreqForMultisampling,
                out int PreOriginTimeOut,
                PlayTrackInfoRec TrackInfo,
                SynthParamRec SynthParams)
            {
                int OnePreOrigin;

                /* initialize common portion of structure */
                NLProcUnifiedRec NLProc = CommonNLStructAlloc(
                    Template,
                    SynthParams);

                NLProc.Oscillator = new NLOscRec();

                int MaxPreOrigin = 0;

                NLProc.Oscillator.InputScalingEnvelope = NewEnvelopeStateRecord(
                    GetNLProcInputEnvelope(Template),
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                NLProc.Oscillator.InputScalingLFO = NewLFOGenerator(
                    GetNLProcInputLFO(Template),
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                NLProc.Oscillator.OutputScalingEnvelope = NewEnvelopeStateRecord(
                    GetNLProcOutputEnvelope(Template),
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                NLProc.Oscillator.OutputScalingLFO = NewLFOGenerator(
                    GetNLProcOutputLFO(Template),
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                NLProc.Oscillator.WaveTableIndexEnvelope = NewEnvelopeStateRecord(
                    GetNLProcIndexEnvelope(Template),
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                NLProc.Oscillator.WaveTableIndexLFO = NewLFOGenerator(
                    GetNLProcIndexLFO(Template),
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                PreOriginTimeOut = MaxPreOrigin;

                return(NLProc);
            }
Example #22
0
        /* create a new envelope state record.  Accent factors have no effect with a value */
        /* of 1, attenuate at smaller values, and amplify at larger values. */
        public static EvalEnvelopeRec NewEnvelopeStateRecord(
            EnvelopeRec Template,
            ref AccentRec Accents,
            double FrequencyHertz,
            double Loudness,
            double HurryUp,
            out int PreOriginTime,
            ParamGetterMethod ParamGetter,
            object ParamGetterContext,
            SynthParamRec SynthParams)
        {
            EvalEnvelopeRec State = New(ref SynthParams.freelists.envelopeStateFreeList);

            // must assign all fields: State, State.PhaseVector

            State.NumPhases   = Template.NumPhases;
            State.PhaseVector = New(ref SynthParams.freelists.envelopeOnePhaseFreeList, Template.NumPhases); // cleared

#if DEBUG
            if ((Template.NumPhases != 0) && Template.ConstantShortcut)
            {
                // shouldn't specify shortcut and phase list at the same time
                Debug.Assert(false);
                throw new ArgumentException();
            }
#endif

            State.Template = Template;

            State.CurrentPhase          = -1;
            State.SustainPhase1         = Template.SustainPhase1;
            State.OriginalSustainPhase1 = Template.SustainPhase1;
            State.SustainPhase1Type     = Template.SustainPhase1Type;
            State.SustainPhase2         = Template.SustainPhase2;
            State.OriginalSustainPhase2 = Template.SustainPhase2;
            State.SustainPhase2Type     = Template.SustainPhase2Type;
            State.SustainPhase3         = Template.SustainPhase3;
            State.OriginalSustainPhase3 = Template.SustainPhase3;
            State.SustainPhase3Type     = Template.SustainPhase3Type;
            State.Origin                       = Template.Origin;
            State.ParamGetter                  = ParamGetter;
            State.ParamGetterContext           = ParamGetterContext;
            State.LastOutputtedValue           = 0;
            State.PreOriginTime                = 0;
            State.FrozenNoteAccentDifferential = new AccentRec();

            /* build initial delay transition */
            ResetLinearTransition(
                ref State.LinearTransition,
                0,
                0,
                1);
            State.LinearTransitionCounter       = 0;
            State.LinearTransitionTotalDuration = 0;
            State.EnvelopeUpdate      = _EnvUpdateLinearAbsolute;
            State.EnvelopeHasFinished = false;

            State.PerformGlobalPitchScaling = (0 != Template.GlobalPitchRateRolloff);

            // A note about accents to follow:
            // - The "Accents" parameter to this function comes from the FrozenNote - so they are the accent values in effect
            //   at the time the note was "frozen" (i.e. the accent defaults added to the individual note's adjustments).
            // - The "LiveAccents" parameter is the current accent defaults at time t (which should be equal to "Accents", at the
            //   the a note is initiated, but not necessarily before or after), since this event is occurring at time t.
            // - The "LiveTrackAccents" parameter is the current track effect accent values.
            // There is some redundancy here, but it is not being changed in case this is wrong and there are legacy
            // interactions that need to be preserved.
            AccentRec LiveAccents;
            AccentRec LiveTrackAccents;
#if DEBUG
            bool liveAccentInit = false;
#endif
            if (EnvelopeContainsFormula(Template)) // an optimization
            {
                /* get current live accents that do not contain any info from the note */
                ParamGetter(
                    ParamGetterContext,
                    out LiveAccents,
                    out LiveTrackAccents);
#if DEBUG
                liveAccentInit = true;
#endif
            }
            else
            {
                LiveAccents      = new AccentRec();
                LiveTrackAccents = new AccentRec();
            }

            /* build list of nodes */
            if (Template.ConstantShortcut)
            {
                State.NumPhases           = 0; /* make sure */
                State.CurrentPhase        = 0;
                State.LastOutputtedValue  = Template.ConstantShortcutValue;
                State.EnvelopeUpdate      = _EnvUpdateSustain;
                State.EnvelopeHasFinished = false;
            }
            else
            {
                State.LastOutputtedValue = 0;

                double           accumulatedError = 0;
                OneEnvPhaseRec[] PhaseVector      = State.PhaseVector;
                if (unchecked ((uint)State.NumPhases > (uint)PhaseVector.Length))
                {
                    throw new IndexOutOfRangeException();
                }
                EnvStepRec[] TemplatePhaseArray = Template.PhaseArray;
                if (unchecked ((uint)State.NumPhases > (uint)TemplatePhaseArray.Length))
                {
                    throw new IndexOutOfRangeException();
                }
                for (int i = 0; i < State.NumPhases; i++)
                {
                    Debug.Assert(PhaseVector[i].Equals(new OneEnvPhaseRec())); // verify cleared

                    PhaseVector[i].TransitionType = TemplatePhaseArray[i].TransitionType;
                    PhaseVector[i].TargetType     = TemplatePhaseArray[i].TargetType;
                    /* calculate the total duration.  the effect of accents is this: */
                    /*  - the accent is the base-2 log of a multiplier for the rate.  a value of 0 */
                    /*    does not change the rate.  -1 halves the rate, and 1 doubles the rate. */
                    /*  - the accent scaling factor is the base-2 log for scaling the accent. */
                    /*    a value of 0 eliminates the effect of the accent, a value of 1 does not */
                    /*    scale the accent. */
                    /*  - pitch has two factors:  normalization point and rolloff.  rolloff */
                    /*    determines how much the signal will decrease with each octave.  0 */
                    /*    removes effect, 1 halfs signal with each octave.  normalization point */
                    /*    determines what pitch will be the invariant point. */
                    double Temp;
                    if (TemplatePhaseArray[i].DurationFunction == null)
                    {
                        Temp = TemplatePhaseArray[i].Duration;
                    }
                    else
                    {
#if DEBUG
                        Debug.Assert(liveAccentInit);
#endif
                        SynthErrorCodes error = EnvelopeInitParamEval(
                            TemplatePhaseArray[i].DurationFunction,
                            ref Accents,
                            ref LiveTrackAccents,
                            SynthParams,
                            out Temp);
                        if (error != SynthErrorCodes.eSynthDone)
                        {
                            // TODO:
                        }
                    }
                    double preciseDuration = SynthParams.dEnvelopeRate
                                             * HurryUp
                                             * Temp
                                             * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentRate)
                                                             + (Math.Log(FrequencyHertz
                                                                         / TemplatePhaseArray[i].FrequencyRateNormalization)
                                                                * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyRateRolloff))
                                             + accumulatedError;
                    PhaseVector[i].Duration = (int)Math.Round(preciseDuration);
                    accumulatedError        = preciseDuration - PhaseVector[i].Duration;
                    /* the final amplitude scaling values are computed similarly to the rate */
                    /* scaling values. */
                    if (TemplatePhaseArray[i].EndPointFunction == null)
                    {
                        Temp = TemplatePhaseArray[i].EndPoint;
                    }
                    else
                    {
#if DEBUG
                        Debug.Assert(liveAccentInit);
#endif
                        SynthErrorCodes error = EnvelopeInitParamEval(
                            TemplatePhaseArray[i].EndPointFunction,
                            ref Accents,
                            ref LiveTrackAccents,
                            SynthParams,
                            out Temp);
                        if (error != SynthErrorCodes.eSynthDone)
                        {
                            // TODO:
                        }
                    }
                    PhaseVector[i].FinalAmplitude = Temp
                                                    * Template.OverallScalingFactor * Loudness
                                                    * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentAmp)
                                                                    + (Math.Log(FrequencyHertz
                                                                                / TemplatePhaseArray[i].FrequencyAmpNormalization)
                                                                       * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyAmpRolloff));

                    /* adjust initial countdown */
                    if (i < Template.Origin)
                    {
                        /* this occurs before the origin, so add it in */
                        State.PreOriginTime += PhaseVector[i].Duration;
                    }
                }
            }
            PreOriginTime = State.PreOriginTime;

            /* compute accent differentials */
            if (State.Template.Formula != null)
            {
#if DEBUG
                Debug.Assert(liveAccentInit);
#endif

                /* subtract composite accents ("Accents") from current live accents */
                AccentAdd(
                    -1,
                    ref Accents,
                    ref LiveAccents,
                    ref State.FrozenNoteAccentDifferential);
            }

            return(State);
        }
Example #23
0
            /* create a new oscillator vocoder */
            public static VocoderRec NewOscVocoder(
                VocoderSpecRec Template,
                ref AccentRec Accents,
                double HurryUp,
                double InitialFrequency,
                double FreqForMultisampling,
                out int PreOriginTimeOut,
                PlayTrackInfoRec TrackInfo,
                SynthParamRec SynthParams)
            {
                int OnePreOrigin;

                /* initialize common portion of structure */
                VocoderRec Vocoder = VocoderBuildCommonStructure(
                    Template,
                    SynthParams);

                Vocoder.Oscillator = new VocOscRec();

                /* initialize variant portion */
                int MaxPreOrigin = 0;

                Vocoder.Oscillator.OutputScalingEnvelope = NewEnvelopeStateRecord(
                    GetVocoderSpecOutputGainEnvelope(Template),
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                Vocoder.Oscillator.OutputScalingLFO = NewLFOGenerator(
                    GetVocoderSpecOutputGainLFO(Template),
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                Vocoder.Oscillator.WaveTableIndexEnvelope = NewEnvelopeStateRecord(
                    GetVocoderSpecIndexEnvelope(Template),
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                Vocoder.Oscillator.WaveTableIndexLFO = NewLFOGenerator(
                    GetVocoderSpecIndexLFO(Template),
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                PreOriginTimeOut = MaxPreOrigin;

                return(Vocoder);
            }
Example #24
0
            /* create a new FOF state object. */
            public SynthErrorCodes NewState(
                double FreqForMultisampling,
                ref AccentRec Accents,
                double Loudness,
                double HurryUp,
                out int PreOriginTimeOut,
                double StereoPosition,
                double InitialFrequency,
                double PitchDisplacementDepthLimit,
                double PitchDisplacementRateLimit,
                int PitchDisplacementStartPoint,
                PlayTrackInfoRec TrackInfo,
                SynthParamRec SynthParams,
                out IOscillator StateOut)
            {
                FOFTemplateRec Template = this;

                int OnePreOrigin;
                int NumberOfTables;

                PreOriginTimeOut = 0;
                StateOut         = null;

                FOFStateRec State = New(ref SynthParams.freelists.FOFStateRecFreeList);

                // must initilize all fields: State

                State.WaveTableSamplePosition             = new Fixed64(0);
                State.WaveTableSamplePositionDifferential = new Fixed64(0);
                State.WaveTableIndex         = 0;
                State.LeftLoudness           = 0;
                State.RightLoudness          = 0;
                State.FOFSamplingRateContour = 0;

                State.Template = Template;

                int MaxPreOrigin = 0;

                State.ActiveGrainList = null; /* no grains to begin with */

                State.NoteLoudnessScaling = Loudness * Template.OverallOscillatorLoudness;

                State.WaveTableWasDefined = GetMultiWaveTableReference(
                    Template.WaveTableSourceSelector,
                    FreqForMultisampling,
                    out State.WaveTableMatrix,
                    out State.FramesPerTable,
                    out NumberOfTables);
                State.NumberOfTablesMinus1 = NumberOfTables - 1;

                if (State.WaveTableWasDefined)
                {
                    /* we want the first grain to go on the first sampling point, so we */
                    /* set this up to start on the next interval. */
                    State.WaveTableSamplePosition = new Fixed64(State.FramesPerTable - State.FramesPerTable
                                                                * (InitialFrequency / SynthParams.dSamplingRate));
                }
                /* State.WaveTableSamplePositionDifferential specified in separate call */

                /* State.FramesPerTable > 0: */
                /*   if the wave table is empty, then we don't do any work (and we must not, */
                /*   since array accesses would cause a crash) */
                if (State.WaveTableWasDefined)
                {
                    if (!(State.FramesPerTable > 0))
                    {
                        State.WaveTableWasDefined = false;
                    }
                }

                /* State.WaveTableWasDefined: */
                /*   if there is no wave table defined for the current pitch, then we don't */
                /*   bother generating any data */
                /* (no action required) */

                State.PreStartCountdown = (int)(Template.TimeDisplacement * SynthParams.dEnvelopeRate + 0.5);
                if (-State.PreStartCountdown > MaxPreOrigin)
                {
                    MaxPreOrigin = -State.PreStartCountdown;
                }

                /* State.WaveTableIndex determined by envelope update */
                State.WaveTableIndexEnvelope = NewEnvelopeStateRecord(
                    Template.IndexEnvelopeTemplate,
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                State.IndexLFOGenerator = NewLFOGenerator(
                    Template.IndexLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                /* State.MonoLoudness, State.LeftLoudness, State.RightLoudness */
                /* are determined by the envelope update */
                StereoPosition += Template.StereoBias;
                if (StereoPosition < -1)
                {
                    StereoPosition = -1;
                }
                else if (StereoPosition > 1)
                {
                    StereoPosition = 1;
                }
                State.Panning = (float)StereoPosition;

                State.WaveTableLoudnessEnvelope = NewEnvelopeStateRecord(
                    Template.LoudnessEnvelopeTemplate,
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                State.LoudnessLFOGenerator = NewLFOGenerator(
                    Template.LoudnessLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                State.PitchLFO = NewLFOGenerator(
                    Template.PitchLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    PitchDisplacementDepthLimit,
                    PitchDisplacementRateLimit,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.PitchLFOStartCountdown = PitchDisplacementStartPoint;

                State.FOFSamplingRateEnvelope = NewEnvelopeStateRecord(
                    Template.FOFSamplingRateEnvelopeTemplate,
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                State.FOFSamplingRateLFOGenerator = NewLFOGenerator(
                    Template.FOFSamplingRateLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }

                State.OscEffectGenerator = null;
                if (Template.OscEffectTemplate != null)
                {
                    SynthErrorCodes Result = NewOscEffectGenerator(
                        Template.OscEffectTemplate,
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams,
                        out State.OscEffectGenerator);
                    if (Result != SynthErrorCodes.eSynthDone)
                    {
                        return(Result);
                    }
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                }

                PreOriginTimeOut = MaxPreOrigin;
                StateOut         = State;
                return(SynthErrorCodes.eSynthDone);
            }
Example #25
0
        /* retrigger envelopes from the origin point */
        public static void EnvelopeRetriggerFromOrigin(
            EvalEnvelopeRec State,
            ref AccentRec Accents,
            double FrequencyHertz,
            double Loudness,
            double HurryUp,
            bool ActuallyRetrigger,
            SynthParamRec SynthParams)
        {
            /* if we actually retrigger, then reset the state */
            if (ActuallyRetrigger)
            {
                State.CurrentPhase        = -1;
                State.EnvelopeHasFinished = false;
                while (State.CurrentPhase < State.Origin - 1)
                {
                    State.CurrentPhase += 1;
                }
                State.SustainPhase1           = State.OriginalSustainPhase1;
                State.SustainPhase2           = State.OriginalSustainPhase2;
                State.SustainPhase3           = State.OriginalSustainPhase3;
                State.LinearTransitionCounter = 0; /* force transition on next update */
                State.EnvelopeUpdate          = _EnvUpdateLinearAbsolute;
            }

            // A note about accents to follow:
            // - The "Accents" parameter to this function comes from the FrozenNote - so they are the accent values in effect
            //   at the time the note was "frozen" (i.e. the accent defaults added to the individual note's adjustments).
            // - The "LiveAccents" parameter is the current accent defaults at time t (which should be equal to "Accents", at the
            //   the a note is initiated, but not necessarily before or after), since this event is occurring at time t.
            // - The "LiveTrackAccents" parameter is the current track effect accent values.
            // There is some redundancy here, but it is not being changed in case this is wrong and there are legacy
            // interactions that need to be preserved.
            AccentRec LiveAccents;
            AccentRec LiveTrackAccents;

#if DEBUG
            bool liveAccentInit = false;
#endif
            if (EnvelopeContainsFormula(State.Template)) // an optimization
            {
                /* get current live accents that do not contain any info from the note */
                State.ParamGetter(
                    State.ParamGetterContext,
                    out LiveAccents,
                    out LiveTrackAccents);
#if DEBUG
                liveAccentInit = true;
#endif
            }
            else
            {
                LiveAccents      = new AccentRec();
                LiveTrackAccents = new AccentRec();
            }

            OneEnvPhaseRec[] PhaseVector = State.PhaseVector;
            if (unchecked ((uint)State.NumPhases > (uint)PhaseVector.Length))
            {
                throw new IndexOutOfRangeException();
            }
            EnvStepRec[] TemplatePhaseArray = State.Template.PhaseArray;
            if (unchecked ((uint)State.NumPhases > (uint)TemplatePhaseArray.Length))
            {
                throw new IndexOutOfRangeException();
            }

            /* no matter what, refill the parameters */
            double accumulatedError = 0;
            for (int i = 0; i < State.NumPhases; i++)
            {
                /* calculate the total duration.  the effect of accents is this: */
                /*  - the accent is the base-2 log of a multiplier for the rate.  a value of 0 */
                /*    does not change the rate.  -1 halves the rate, and 1 doubles the rate. */
                /*  - the accent scaling factor is the base-2 log for scaling the accent. */
                /*    a value of 0 eliminates the effect of the accent, a value of 1 does not */
                /*    scale the accent. */
                /*  - pitch has two factors:  normalization point and rolloff.  rolloff */
                /*    determines how much the signal will decrease with each octave.  0 */
                /*    removes effect, 1 halfs signal with each octave.  normalization point */
                /*    determines what pitch will be the invariant point. */
                double Temp;
                if (TemplatePhaseArray[i].DurationFunction == null)
                {
                    Temp = TemplatePhaseArray[i].Duration;
                }
                else
                {
#if DEBUG
                    Debug.Assert(liveAccentInit);
#endif
                    SynthErrorCodes error = EnvelopeInitParamEval(
                        TemplatePhaseArray[i].DurationFunction,
                        ref Accents,
                        ref LiveTrackAccents,
                        SynthParams,
                        out Temp);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        // TODO:
                    }
                }
                double preciseDuration = SynthParams.dEnvelopeRate
                                         * HurryUp
                                         * Temp
                                         * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentRate)
                                                         + (Math.Log(FrequencyHertz
                                                                     / TemplatePhaseArray[i].FrequencyRateNormalization)
                                                            * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyRateRolloff))
                                         + accumulatedError;
                PhaseVector[i].Duration = (int)Math.Round(preciseDuration);
                accumulatedError        = preciseDuration - PhaseVector[i].Duration;
                /* the final amplitude scaling values are computed similarly to the rate */
                /* scaling values. */
                if (TemplatePhaseArray[i].EndPointFunction == null)
                {
                    Temp = TemplatePhaseArray[i].EndPoint;
                }
                else
                {
#if DEBUG
                    Debug.Assert(liveAccentInit);
#endif
                    SynthErrorCodes error = EnvelopeInitParamEval(
                        TemplatePhaseArray[i].EndPointFunction,
                        ref Accents,
                        ref LiveTrackAccents,
                        SynthParams,
                        out Temp);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        // TODO:
                    }
                }
                PhaseVector[i].FinalAmplitude = Temp
                                                * State.Template.OverallScalingFactor * Loudness
                                                * Math.Pow(2, -(AccentProduct(ref Accents, ref TemplatePhaseArray[i].AccentAmp)
                                                                + (Math.Log(FrequencyHertz
                                                                            / TemplatePhaseArray[i].FrequencyAmpNormalization)
                                                                   * Constants.INVLOG2) * TemplatePhaseArray[i].FrequencyAmpRolloff));
            }

            /* recompute accent differentials incorporating new note's info */
            if (State.Template.Formula != null)
            {
#if DEBUG
                Debug.Assert(liveAccentInit);
#endif

                /* subtract composite accents ("Accents") from current live accents */
                AccentAdd(
                    -1,
                    ref Accents,
                    ref LiveAccents,
                    ref State.FrozenNoteAccentDifferential);
            }
        }
Example #26
0
        /* create a new oscillator effect generator */
        public static SynthErrorCodes NewOscEffectGenerator(
            EffectSpecListRec SpecList,
            ref AccentRec Accents,
            double HurryUp,
            double InitialFrequency,
            double FreqForMultisampling,
            out int PreOriginTimeOut,
            PlayTrackInfoRec TrackInfo,
            SynthParamRec SynthParams,
            out OscEffectGenRec GeneratorOut)
        {
            int OnePreOrigin;

            GeneratorOut     = null;
            PreOriginTimeOut = 0;

            OscEffectGenRec Generator = New(ref SynthParams.freelists.OscEffectGenRecFreeList);
            int             count     = Generator.count = GetEffectSpecListEnabledLength(SpecList);

            IOscillatorEffect[] List = Generator.List = New(ref SynthParams.freelists.IOscillatorEffectFreeList, count); // zeroed
            if (unchecked ((uint)count > (uint)List.Length))
            {
                Debug.Assert(false);
                throw new IndexOutOfRangeException();
            }

            int MaxPreOrigin = 0;

            /* build list of thingers */
            int j = 0;

            for (int i = 0; j < count; i++)
            {
                /* see if effect is enabled */
                if (!IsEffectFromEffectSpecListEnabled(SpecList, i))
                {
                    continue;
                }

                /* fill in fields */
                EffectTypes Type = GetEffectSpecListElementType(SpecList, i);
                switch (Type)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case EffectTypes.eDelayEffect:
                    List[j] = DelayUnifiedRec.NewOscUnifiedDelayLineProcessor(
                        GetDelayEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                    break;

                case EffectTypes.eNLProcEffect:
                    List[j] = NLProcUnifiedRec.NewOscNLProcProcessor(
                        GetNLProcEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                    break;

                case EffectTypes.eFilterEffect:
                    List[j] = FilterArrayRec.NewOscFilterArrayProcessor(
                        GetFilterEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                    break;

                case EffectTypes.eAnalyzerEffect:
                    List[j] = AnalyzerRec.NewAnalyzer(
                        GetAnalyzerEffectFromEffectSpecList(SpecList, i),
                        SynthParams);
                    break;

                case EffectTypes.eHistogramEffect:
                    List[j] = HistogramRec.NewHistogram(
                        GetHistogramEffectFromEffectSpecList(SpecList, i),
                        SynthParams);
                    break;

                case EffectTypes.eResamplerEffect:
                    List[j] = ResamplerRec.NewResampler(
                        GetResamplerEffectFromEffectSpecList(SpecList, i),
                        SynthParams);
                    break;

                case EffectTypes.eCompressorEffect:
                    List[j] = CompressorRec.NewOscCompressor(
                        GetCompressorEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                    break;

                case EffectTypes.eVocoderEffect:
                    List[j] = VocoderRec.NewOscVocoder(
                        GetVocoderEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams);
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                    break;

                case EffectTypes.eIdealLowpassEffect:
                    List[j] = IdealLPRec.NewIdealLP(
                        GetIdealLPEffectFromEffectSpecList(SpecList, i),
                        SynthParams);
                    break;

                case EffectTypes.eUserEffect:
                {
                    UserEffectProcRec userEffect;
                    SynthErrorCodes   error = UserEffectProcRec.NewOscUserEffectProc(
                        GetUserEffectFromEffectSpecList(SpecList, i),
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams,
                        out userEffect);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        return(error);
                    }
                    List[j] = userEffect;
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                }
                break;

                case EffectTypes.ePluggableEffect:
                {
                    PluggableSpec Spec = GetPluggableEffectFromEffectSpecList(SpecList, i);
                    Debug.Assert(Spec is PluggableOscSpec);
                    PluggableOscEffectTemplate template = new PluggableOscEffectTemplate(
                        (PluggableOscSpec)Spec,
                        SynthParams);
                    IOscillatorEffect effect;
                    SynthErrorCodes   error = template.Create(
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams,
                        out effect);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        return(error);
                    }
                    List[j] = effect;
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                }
                break;
                }

                j++;
            }
            Debug.Assert(j == count);

            PreOriginTimeOut = MaxPreOrigin;

            GeneratorOut = Generator;
            return(SynthErrorCodes.eSynthDone);
        }
Example #27
0
            /* restart a FOF oscillator.  this is used for tie continuations */
            public void Restart(
                ref AccentRec NewAccents,
                double NewLoudness,
                double NewHurryUp,
                bool RetriggerEnvelopes,
                double NewStereoPosition,
                double NewInitialFrequency,
                double PitchDisplacementDepthLimit,
                double PitchDisplacementRateLimit,
                SynthParamRec SynthParams)
            {
                FOFStateRec State = this;

                NewStereoPosition += State.Template.StereoBias;
                if (NewStereoPosition < -1)
                {
                    NewStereoPosition = -1;
                }
                else if (NewStereoPosition > 1)
                {
                    NewStereoPosition = 1;
                }
                State.Panning = (float)NewStereoPosition;

                State.NoteLoudnessScaling = NewLoudness * State.Template.OverallOscillatorLoudness;

                EnvelopeRetriggerFromOrigin(
                    State.WaveTableIndexEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    RetriggerEnvelopes,
                    SynthParams);
                EnvelopeRetriggerFromOrigin(
                    State.WaveTableLoudnessEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    RetriggerEnvelopes,
                    SynthParams);
                EnvelopeRetriggerFromOrigin(
                    State.FOFSamplingRateEnvelope,
                    ref NewAccents,
                    NewInitialFrequency,
                    1,
                    NewHurryUp,
                    RetriggerEnvelopes,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    State.IndexLFOGenerator,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    RetriggerEnvelopes,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    State.LoudnessLFOGenerator,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    RetriggerEnvelopes,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    State.PitchLFO,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    PitchDisplacementDepthLimit,
                    PitchDisplacementRateLimit,
                    RetriggerEnvelopes,
                    SynthParams);
                LFOGeneratorRetriggerFromOrigin(
                    State.FOFSamplingRateLFOGenerator,
                    ref NewAccents,
                    NewInitialFrequency,
                    NewHurryUp,
                    1,
                    1,
                    RetriggerEnvelopes,
                    SynthParams);
                if (State.OscEffectGenerator != null)
                {
                    OscEffectGeneratorRetriggerFromOrigin(
                        State.OscEffectGenerator,
                        ref NewAccents,
                        NewInitialFrequency,
                        NewHurryUp,
                        RetriggerEnvelopes,
                        SynthParams);
                }
                /* do not reset PitchLFOStartCountdown since we can't give it a proper value */
                /* to do the expected thing, and we'll be interrupting the phase of the LFO */
                /* wave generator */
            }
            /* create a new wave table state object. */
            public SynthErrorCodes NewState(
                double FreqForMultisampling,
                ref AccentRec Accents,
                double Loudness,
                double HurryUp,
                out int PreOriginTimeOut,
                double StereoPosition,
                double InitialFrequency,
                double PitchDisplacementDepthLimit,
                double PitchDisplacementRateLimit,
                int PitchDisplacementStartPoint,
                PlayTrackInfoRec TrackInfo,
                SynthParamRec SynthParams,
                out IOscillator StateOut)
            {
                WaveTableTemplateRec Template = this;

                int OnePreOrigin;

                PreOriginTimeOut = 0;
                StateOut         = null;

                WaveTableStateRec State = New(ref SynthParams.freelists.waveTableStateFreeList);

                // all fields must be assigned: State

                // conservative zero-initialization
                State.WaveTableSamplePositionDifferential = new Fixed64(0);

                State.Template = Template;

                int MaxPreOrigin = 0;

                State.WaveTableSamplePosition = new Fixed64(0);
                /* State.WaveTableSamplePositionDifferential specified in separate call */

                State.NoteLoudnessScaling = Loudness * Template.OverallOscillatorLoudness;

                int NumberOfTables;

                State.WaveTableWasDefined = GetMultiWaveTableReference(
                    Template.WaveTableSourceSelector,
                    FreqForMultisampling,
                    out State.WaveTableMatrix,
                    out State.FramesPerTable,
                    out NumberOfTables);
                State.NumberOfTablesMinus1 = NumberOfTables - 1;

                State.FramesPerTableOverFinalOutputSamplingRate
                    = (double)State.FramesPerTable / SynthParams.dSamplingRate;

                /* State.FramesPerTable > 0: */
                /*   if the wave table is empty, then we don't do any work (and we must not, */
                /*   since array accesses would cause a crash) */
                if (State.WaveTableWasDefined)
                {
                    if (!(State.FramesPerTable > 0))
                    {
                        State.WaveTableWasDefined = false;
                    }
                }

                State.PreStartCountdown = (int)((Template.TimeDisplacement
                                                 * SynthParams.dEnvelopeRate) + 0.5);
                if (-State.PreStartCountdown > MaxPreOrigin)
                {
                    MaxPreOrigin = -State.PreStartCountdown;
                }

                /* State.WaveTableIndex determined by envelope update */
                State.WaveTableIndexEnvelope = NewEnvelopeStateRecord(
                    Template.IndexEnvelopeTemplate,
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.IndexLFOGenerator = NewLFOGenerator(
                    Template.IndexLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.PreviousWaveTableIndex = 0;
                State.WaveTableIndex         = 0;

                /* State.MonoLoudness, State.LeftLoudness, State.RightLoudness */
                /* are determined by the envelope update */
                StereoPosition += Template.StereoBias;
                if (StereoPosition < -1)
                {
                    StereoPosition = -1;
                }
                else if (StereoPosition > 1)
                {
                    StereoPosition = 1;
                }
                State.Panning = (float)StereoPosition;
                State.WaveTableLoudnessEnvelope = NewEnvelopeStateRecord(
                    Template.LoudnessEnvelopeTemplate,
                    ref Accents,
                    InitialFrequency,
                    1,
                    HurryUp,
                    out OnePreOrigin,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.LoudnessLFOGenerator = NewLFOGenerator(
                    Template.LoudnessLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    1,
                    1,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.PreviousLoudness = 0;
                State.Loudness         = 0;

                State.PitchLFO = NewLFOGenerator(
                    Template.PitchLFOTemplate,
                    out OnePreOrigin,
                    ref Accents,
                    InitialFrequency,
                    HurryUp,
                    PitchDisplacementDepthLimit,
                    PitchDisplacementRateLimit,
                    FreqForMultisampling,
                    _PlayTrackParamGetter,
                    TrackInfo,
                    SynthParams);
                if (OnePreOrigin > MaxPreOrigin)
                {
                    MaxPreOrigin = OnePreOrigin;
                }
                State.PitchLFOStartCountdown = PitchDisplacementStartPoint;

                State.OscEffectGenerator = null;
                if (Template.OscEffectTemplate != null)
                {
                    SynthErrorCodes Result = NewOscEffectGenerator(
                        Template.OscEffectTemplate,
                        ref Accents,
                        HurryUp,
                        InitialFrequency,
                        FreqForMultisampling,
                        out OnePreOrigin,
                        TrackInfo,
                        SynthParams,
                        out State.OscEffectGenerator);
                    if (Result != SynthErrorCodes.eSynthDone)
                    {
                        return(Result);
                    }
                    if (OnePreOrigin > MaxPreOrigin)
                    {
                        MaxPreOrigin = OnePreOrigin;
                    }
                }

                State.EnableCrossWaveTableInterpolation = Template.EnableCrossWaveTableInterpolation;

                PreOriginTimeOut = MaxPreOrigin;
                StateOut         = State;
                return(SynthErrorCodes.eSynthDone);
            }