/* create a new wave table template */
            public static WaveTableTemplateRec NewWaveTableTemplate(
                OscillatorRec Oscillator,
                SynthParamRec SynthParams)
            {
#if DEBUG
                if (OscillatorGetWhatKindItIs(Oscillator) != OscillatorTypes.eOscillatorWaveTable)
                {
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif

                WaveTableTemplateRec Template = new WaveTableTemplateRec();

                Template.WaveTableSourceSelector = NewMultiWaveTable(
                    OscillatorGetSampleIntervalList(Oscillator),
                    SynthParams.Dictionary);

                Template.OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);

                /* it might be better to handle divisor and multiplier separately -- we would */
                /* want to do that if we were trying to guarantee that all harmonic */
                /* oscillators ran in lock-step */
                Template.FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
                                               / OscillatorGetFrequencyDivisor(Oscillator);
                Template.FrequencyAdder = OscillatorGetFrequencyAdder(Oscillator);

                Template.StereoBias       = OscillatorGetStereoBias(Oscillator);
                Template.TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);

                /* these are just references */
                Template.LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
                Template.LoudnessLFOTemplate      = OscillatorGetLoudnessLFOList(Oscillator);
                Template.IndexEnvelopeTemplate    = OscillatorGetExcitationEnvelope(Oscillator);
                Template.IndexLFOTemplate         = OscillatorGetExcitationLFOList(Oscillator);

                /* more references */
                Template.PitchLFOTemplate  = GetOscillatorFrequencyLFOList(Oscillator);
                Template.OscEffectTemplate = GetOscillatorEffectList(Oscillator);
                if (GetEffectSpecListLength(Template.OscEffectTemplate) == 0)
                {
                    Template.OscEffectTemplate = null;
                }

                Template.EnableCrossWaveTableInterpolation = OscillatorGetEnableCrossWaveTableInterpolation(Oscillator);

                return(Template);
            }
            /* 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);
            }
예제 #3
0
        /* construct an oscillator bank template record.  various parameters are passed in */
        /* which are needed for synthesis.  ParameterUpdator is the parameter information */
        /* record for the whole track of which this is a part. */
        public static OscBankTemplateRec NewOscBankTemplate(
            InstrumentRec InstrumentDefinition,
            IncrParamUpdateRec ParameterUpdator,
            SynthParamRec SynthParams)
        {
            OscillatorListRec OscillatorListObject;

            OscBankTemplateRec Template = new OscBankTemplateRec();

            /* the oscillator bank template contains all of the information needed for */
            /* constructing oscillators as notes are to be executed. */
            /* number of oscillators in a bank. */
            OscillatorListObject = GetInstrumentOscillatorList(InstrumentDefinition);

            /* get LFO information */
            Template.PitchLFOTemplate = GetInstrumentFrequencyLFOList(InstrumentDefinition);

            Template.ParamUpdator = ParameterUpdator;

            Template.InstrOverallLoudness = GetInstrumentOverallLoudness(InstrumentDefinition);

            Template.CombinedOscillatorEffects = GetInstrumentCombinedOscEffectSpecList(InstrumentDefinition);
            if (0 == GetEffectSpecListLength(Template.CombinedOscillatorEffects))
            {
                /* if no effects, then set to null, so we don't do any processing */
                Template.CombinedOscillatorEffects = null;
            }

            /* vector containing templates for all of the oscillators */
            Template.NumOscillatorsInBank = GetOscillatorListLength(OscillatorListObject);
            Template.TemplateArray        = new OscBankVectorRec[Template.NumOscillatorsInBank];

            /* build entry for each oscillator */
            for (int i = 0; i < Template.NumOscillatorsInBank; i++)
            {
                OscillatorRec    Osc  = GetOscillatorFromList(OscillatorListObject, i);
                OscBankVectorRec Osc1 = Template.TemplateArray[i] = new OscBankVectorRec();

                switch (OscillatorGetWhatKindItIs(Osc))
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case OscillatorTypes.eOscillatorSampled:
                    Osc1.TemplateReference = SampleTemplateRec.NewSampleTemplate(Osc, SynthParams);
                    break;

                case OscillatorTypes.eOscillatorWaveTable:
                    Osc1.TemplateReference = WaveTableTemplateRec.NewWaveTableTemplate(Osc, SynthParams);
                    break;

                case OscillatorTypes.eOscillatorFOF:
                    Osc1.TemplateReference = FOFTemplateRec.NewFOFTemplate(Osc, SynthParams);
                    break;

                case OscillatorTypes.eOscillatorAlgorithm:
                    Osc1.TemplateReference = AlgorithmicTemplateRec.NewAlgorithmicTemplate(Osc, SynthParams);
                    break;

                case OscillatorTypes.eOscillatorFMSynth:
                    Osc1.TemplateReference = FMSynthTemplateRec.NewFMSynthTemplate(Osc, SynthParams);
                    break;

                case OscillatorTypes.eOscillatorPluggable:
                    Osc1.TemplateReference = new PluggableOscillatorTemplate(Osc, SynthParams);
                    break;
                }
            }

            return(Template);
        }