Example #1
0
        /* add an item */
        public static void SequencerTableInsert(
            SequencerTableRec Table,
            string Name,
            PlayTrackInfoRec Object)
        {
            List <PlayTrackInfoRec> Array;

            if (!Table.NameToArray.TryGetValue(Name, out Array))
            {
                Array = new List <PlayTrackInfoRec>();
                Table.NameToArray.Add(Name, Array);
            }

            Array.Add(Object);
        }
Example #2
0
 /* remove an object */
 public static void SequencerTableRemoveObject(
     SequencerTableRec Table,
     PlayTrackInfoRec Object)
 {
     foreach (KeyValuePair <string, List <PlayTrackInfoRec> > entry in Table.NameToArray)
     {
         int i = entry.Value.IndexOf(Object);
         if (i >= 0)
         {
             entry.Value.RemoveAt(i);
             return;
         }
     }
     // object was not found
     Debug.Assert(false);
     throw new InvalidOperationException();
 }
Example #3
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 #4
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 #5
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);
            }
            /* 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);
            }
Example #7
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 #8
0
        /* construct a new oscillator bank state object based on the note.  the note is */
        /* assumed to start "now" in terms of the parameters in the ParameterUpdator.  */
        /* the ScanningGapWidth is the number of envelope clock ticks in the current scanning */
        /* gap.  this is used to determine how far later than "now" in terms of the back */
        /* edge of the scanning gap (different from above) the osc bank should start playing. */
        /* *WhenToStartPlayingOut returns the number of envelope ticks after the back edge */
        /* of the scanning gap that the note should be started. */
        /*     <already played>       |    <scanning gap>     |    <not yet analyzed> */
        /*   time ---.    time ---.    time ---.    time ---.    time ---.   time ---. */
        /*                            ^A                      ^B     */
        /* point A is the back edge of the scanning gap.  as this edge moves forward in time, */
        /*   oscillator bank state objects are removed from the queue and playback is commenced */
        /*   for them. */
        /* point B is the front edge of the scanning gap.  as this edge moves forward in time, */
        /*   notes are extracted from the track and state bank objects are created for them. */
        /*   ParameterUpdator always reflects parameters at this point in time. */
        public static SynthErrorCodes NewOscBankState(
            OscBankTemplateRec Template,
            out int WhenToStartPlayingOut,
            NoteNoteObjectRec Note,
            double EnvelopeTicksPerDurationTick,
            short PitchIndexAdjust,
            PlayTrackInfoRec TrackInfo,
            SynthParamRec SynthParams,
            out OscStateBankRec StateOut)
        {
            int ThisPreOriginTime;
            int StartPointAdjust;

            WhenToStartPlayingOut = 0;
            StateOut = null;

            int MaxOscillatorPreOriginTime = 0;

            OscStateBankRec State = New(ref SynthParams.freelists.oscStateBankFreeList);

            // all fields must be assigned: State

            State.PortamentoHertz      = false;
            State.TotalPortamentoTicks = 0;
            State.InitialFrequency     = 0;
            State.FinalFrequency       = 0;

            State.BankTemplate = Template;

            /* freeze the parameters */
            FrozenNoteRec FrozenNote = new FrozenNoteRec();

            FixNoteParameters(
                Template.ParamUpdator,
                Note,
                out StartPointAdjust,
                EnvelopeTicksPerDurationTick,
                PitchIndexAdjust,
                ref FrozenNote,
                SynthParams);


            /* this calculates the differential values for periodic pitch displacements */
            State.PitchLFO = NewLFOGenerator(
                Template.PitchLFOTemplate,
                out ThisPreOriginTime,
                ref FrozenNote.Accents,
                FrozenNote.NominalFrequency,
                FrozenNote.HurryUpFactor,
                FrozenNote.PitchDisplacementDepthLimit,
                FrozenNote.PitchDisplacementRateLimit,
                FrozenNote.MultisampleFrequency,
                _PlayTrackParamGetter,
                TrackInfo,
                SynthParams);
            if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
            {
                MaxOscillatorPreOriginTime = ThisPreOriginTime;
            }

            /* list of oscillators that this oscillator bank is comprised of */
            State.OscillatorList = null;
            for (int i = 0; i < Template.NumOscillatorsInBank; i++)
            {
                OscStateRec OneState = New(ref SynthParams.freelists.oscStateFreeList);

                // all fields must be assigned: OneState

                /* link it in */
                OneState.Next        = State.OscillatorList;
                State.OscillatorList = OneState;

                /* copy over the function vectors */
                OneState.Template = Template.TemplateArray[i];

                /* create the oscillator */
                SynthErrorCodes Result = OneState.Template.TemplateReference.NewState(
                    FrozenNote.MultisampleFrequency,
                    ref FrozenNote.Accents,
                    FrozenNote.LoudnessAdjust * Template.InstrOverallLoudness,
                    FrozenNote.HurryUpFactor,
                    out ThisPreOriginTime,
                    FrozenNote.StereoPosition,
                    FrozenNote.NominalFrequency,
                    FrozenNote.PitchDisplacementDepthLimit,
                    FrozenNote.PitchDisplacementRateLimit,
                    FrozenNote.PitchDisplacementStartPoint,
                    TrackInfo,
                    SynthParams,
                    out OneState.StateReference);
                if (Result != SynthErrorCodes.eSynthDone)
                {
                    return(Result);
                }
                if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
                {
                    MaxOscillatorPreOriginTime = ThisPreOriginTime;
                }
            }

            State.CombinedOscEffectGenerator = null;
            if ((Template.CombinedOscillatorEffects != null) && (GetEffectSpecListLength(Template.CombinedOscillatorEffects) > 0))
            {
                SynthErrorCodes Result = NewOscEffectGenerator(
                    Template.CombinedOscillatorEffects,
                    ref FrozenNote.Accents,
                    FrozenNote.HurryUpFactor,
                    FrozenNote.NominalFrequency,
                    FrozenNote.MultisampleFrequency,
                    out ThisPreOriginTime,
                    TrackInfo,
                    SynthParams,
                    out State.CombinedOscEffectGenerator);
                if (Result != SynthErrorCodes.eSynthDone)
                {
                    return(Result);
                }
                if (ThisPreOriginTime > MaxOscillatorPreOriginTime)
                {
                    MaxOscillatorPreOriginTime = ThisPreOriginTime;
                }
            }
            /* else no combined oscillator effects, State.CombinedOscEffectGenerator is null */

            /* if this object ties to a note, then this is the note */
            /* to tie to.  this is used for finding existing oscillators */
            /* for tie continuations. */
            State.TieToNote = Note._Tie;

            /* portamento control parameters */
            State.PortamentoCounter = 0;
            State.CurrentFrequency  = FrozenNote.NominalFrequency;


            /* fix up pre-origin times */
            OscStateRec StateScan = State.OscillatorList;

            while (StateScan != null)
            {
                StateScan.StateReference.FixUpPreOrigin(
                    MaxOscillatorPreOriginTime);
                StateScan = StateScan.Next;
            }
            LFOGeneratorFixEnvelopeOrigins(
                State.PitchLFO,
                MaxOscillatorPreOriginTime);
            if (State.CombinedOscEffectGenerator != null)
            {
                FixUpOscEffectGeneratorPreOrigin(
                    State.CombinedOscEffectGenerator,
                    MaxOscillatorPreOriginTime);
            }

            /* various counters (in terms of envelope ticks) */
            if (State.TieToNote == null)
            {
                State.Release1Countdown = FrozenNote.ReleasePoint1 + MaxOscillatorPreOriginTime;
                State.Release2Countdown = FrozenNote.ReleasePoint2 + MaxOscillatorPreOriginTime;
                State.Release3Countdown = FrozenNote.ReleasePoint3 + MaxOscillatorPreOriginTime;
            }
            else
            {
                /* for ties, only honor releases from start */
                if (FrozenNote.Release1FromStart)
                {
                    State.Release1Countdown = FrozenNote.ReleasePoint1 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release1Countdown = -1;
                }
                if (FrozenNote.Release2FromStart)
                {
                    State.Release2Countdown = FrozenNote.ReleasePoint2 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release2Countdown = -1;
                }
                if (FrozenNote.Release3FromStart)
                {
                    State.Release3Countdown = FrozenNote.ReleasePoint3 + MaxOscillatorPreOriginTime;
                }
                else
                {
                    State.Release3Countdown = -1;
                }
            }
            State.PitchLFOStartCountdown = FrozenNote.PitchDisplacementStartPoint
                                           /*+ MaxOscillatorPreOriginTime*/;
            /* pre origin relationship must be preserved for */
            /* pitch LFO trigger */

            /* done */
            WhenToStartPlayingOut = StartPointAdjust - MaxOscillatorPreOriginTime;
            StateOut = State;
            return(SynthErrorCodes.eSynthDone);
        }
Example #9
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);
        }