Example #1
0
            /* apply filter to an array of values, adding result to output array */
            public void Apply(
                float[] XinVector,
                int XinVectorOffset,
                float[] YoutVector,
                int YoutVectorOffset,
                int VectorLength,
                float OutputScaling,
                SynthParamRec SynthParams)
            {
                SecondOrderResonRec Filter = this;

                float Ym1 = Filter.Ym1;
                float Ym2 = Filter.Ym2;
                float A0  = Filter.A0;
                float B1  = Filter.B1;
                float B2  = Filter.B2;

                for (int i = 0; i < VectorLength; i += 1)
                {
                    float Xin      = XinVector[i + XinVectorOffset];
                    float OrigYOut = YoutVector[i + YoutVectorOffset];
                    float Y        = A0 * Xin - B1 * Ym1 - B2 * Ym2;
                    Ym2 = Ym1;
                    Ym1 = Y;
                    YoutVector[i + YoutVectorOffset] = OrigYOut + Y * OutputScaling;
                }

                Filter.Ym1 = Ym1;
                Filter.Ym2 = Ym2;
            }
            public void Init(
                int LowpassOrder,
                int BandpassOrder,
                SynthParamRec SynthParams)
            {
                this.OldCutoff    = -1e300;
                this.OldBandwidth = -1e300;
                this.OldGain      = -1e300;

#if DEBUG
                if ((LowpassOrder < 0) || (LowpassOrder % 2 != 0))
                {
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
                if ((BandpassOrder < 0) || (BandpassOrder % 2 != 0))
                {
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif

                this.NumLowpassSections  = LowpassOrder / 2;
                this.NumBandpassSections = BandpassOrder / 2;

                /* allocate iir workspace */
                this.iir = New(ref SynthParams.freelists.iir2DirectIFreeList, this.NumLowpassSections + this.NumBandpassSections);
            }
Example #3
0
        /* generate effect cycle.  this is called once per envelope tick to apply */
        /* effects to data generated during this envelope clock cycle. */
        public static SynthErrorCodes ApplyOscEffectGenerator(
            OscEffectGenRec Generator,
            float[] workspace,
            int lOffset,
            int rOffset,
            int nActualFrames,
            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++)
            {
                SynthErrorCodes error = List[i].Apply(
                    workspace,
                    lOffset,
                    rOffset,
                    nActualFrames,
                    SynthParams);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
Example #4
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);
            }
        }
Example #5
0
        /* update envelopes for effects */
        public static SynthErrorCodes OscEffectGeneratorUpdateEnvelopes(
            OscEffectGenRec Generator,
            double OscillatorFrequency,
            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++)
            {
                SynthErrorCodes error = List[i].OscUpdateEnvelopes(
                    OscillatorFrequency,
                    SynthParams);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
Example #6
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);
            }
        /* hand off command to be handled by effect generator.  the command will be scheduled */
        /* to occur at the time ScanningGapFrontInEnvelopeTicks (which will be */
        /* ScanningGapWidthInEnvelopeTicks in the future from now). */
        public static void TrackEffectHandleCommand(
            TrackEffectGenRec Generator,
            CommandNoteObjectRec Command,
            int ScanningGapFrontInEnvelopeTicks,
            SynthParamRec SynthParams)
        {
            /* don't bother unless there are effects to process */
            if (Generator.List != null)
            {
                CommandConsCell Cell = new CommandConsCell();

                /* fill in data fields */
                Cell.Command   = Command;
                Cell.StartTime = ScanningGapFrontInEnvelopeTicks;

                /* insert into list */
                /* there is no need to sort, since the start time of commands can't */
                /* be adjusted.  just append to the list */
                Cell.Next = null;
                if (Generator.ScanningGapListTail == null)
                {
                    Generator.ScanningGapListHead = Cell;
                }
                else
                {
                    Generator.ScanningGapListTail.Next = Cell;
                }
                Generator.ScanningGapListTail = Cell;
            }
        }
Example #8
0
            /* apply filter to an array of values, adding result to output array */
            public void Apply(
                float[] XinVector,
                int XinVectorOffset,
                float[] YoutVector,
                int YoutVectorOffset,
                int VectorLength,
                float OutputScaling,
                SynthParamRec SynthParams)
            {
                SecondOrderZeroRec Filter = this;

                float Xm1 = Filter.Xm1;
                float Xm2 = Filter.Xm2;
                float A0  = Filter.A0;
                float A1  = Filter.A1;
                float A2  = Filter.A2;

                for (int i = 0; i < VectorLength; i += 1)
                {
                    float Xin      = XinVector[i + XinVectorOffset];
                    float OrigYOut = YoutVector[i + YoutVectorOffset];
                    float Y        = A0 * Xin + A1 * Xm1 + A2 * Xm2;
                    Xm2 = Xm1;
                    Xm1 = Xin;
                    YoutVector[i + YoutVectorOffset] = OrigYOut + Y * OutputScaling;
                }

                Filter.Xm1 = Xm1;
                Filter.Xm2 = Xm2;
            }
Example #9
0
 public static void FreeEnvelopeStateRecord(
     ref EvalEnvelopeRec State,
     SynthParamRec SynthParams)
 {
     Free(ref SynthParams.freelists.envelopeOnePhaseFreeList, ref State.PhaseVector);
     Free(ref SynthParams.freelists.envelopeStateFreeList, ref State);
 }
Example #10
0
            public unsafe FFTSimple(int n, FFT share)
                : base(n, 1)
            {
                if (share != null)
                {
                    if (n > share.N)
                    {
                        Debug.Assert(false);
                        throw new ArgumentException();
                    }
                    // share workspace
                    this.workspace  = share.Base;
                    this.hWorkspace = GCHandle.Alloc(this.workspace, GCHandleType.Pinned);
                    this.offset     = share.Offset;
                }
                else
                {
                    // allocate workspace
                    int count = n + 2;
                    this.workspace  = new float[count + SynthParamRec.WORKSPACEALIGNBYTES];
                    this.hWorkspace = GCHandle.Alloc(this.workspace, GCHandleType.Pinned);
                    fixed(float *pWorkspace0 = &(this.workspace[0]))
                    {
                        IntPtr iWorkspace0 = new IntPtr(pWorkspace0);

                        this.offset = 0;
                        SynthParamRec.Align(iWorkspace0, ref this.offset, SynthParamRec.WORKSPACEALIGNBYTES, SizeOfFloat);
                        Debug.Assert(this.offset + count <= this.workspace.Length);
                    }
                }
            }
Example #11
0
            /* initialize common parts of nlproc structure */
            private static NLProcUnifiedRec CommonNLStructAlloc(
                NonlinProcSpecRec Template,
                SynthParamRec SynthParams)
            {
                NLProcUnifiedRec NLProc = new NLProcUnifiedRec();

                /* get the wave table to use for this instance */
                string Name = GetNLProcSpecWaveTableName(Template);

                if (!WaveSampDictGetWaveTableInfo(
                        SynthParams.Dictionary,
                        Name,
                        out NLProc.WaveTableMatrix,
                        out NLProc.FramesPerTable,
                        out NLProc.NumberOfTables))
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
                NLProc.NumberOfTablesMinus1 = NLProc.NumberOfTables - 1;

                NLProc.clampOverflow = GetNLProcOverflowMode(Template) == NonlinProcOverflowMode.Clamp;

                return(NLProc);
            }
        /* 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 #13
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 #14
0
            public void Finalize(
                SynthParamRec SynthParams,
                bool writeOutputLogs)
            {
                if (Oscillator != null)
                {
                    FreeEnvelopeStateRecord(
                        ref Oscillator.InputScalingEnvelope,
                        SynthParams);
                    FreeLFOGenerator(
                        ref Oscillator.InputScalingLFO,
                        SynthParams);

                    FreeEnvelopeStateRecord(
                        ref Oscillator.OutputScalingEnvelope,
                        SynthParams);
                    FreeLFOGenerator(
                        ref Oscillator.OutputScalingLFO,
                        SynthParams);

                    FreeEnvelopeStateRecord(
                        ref Oscillator.WaveTableIndexEnvelope,
                        SynthParams);
                    FreeLFOGenerator(
                        ref Oscillator.WaveTableIndexLFO,
                        SynthParams);
                }
            }
Example #15
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);
     }
 }
Example #16
0
            /* update user effect processor state with accent information */
            public SynthErrorCodes OscUpdateEnvelopes(
                double OscillatorFrequency,
                SynthParamRec SynthParams)
            {
                double[] paramResultsTemp = this.paramResultsPrevious;
                this.paramResultsPrevious = this.paramResults;
                this.paramResults         = paramResultsTemp;

                for (int i = 0; i < this.paramCount; i += 1)
                {
                    SynthErrorCodes error = SynthErrorCodes.eSynthDone;
                    this.paramResults[i] = LFOGenUpdateCycle(
                        this.params_Osc[i].LFO,
                        EnvelopeUpdate(
                            this.params_Osc[i].Envelope,
                            OscillatorFrequency,
                            SynthParams,
                            ref error),
                        OscillatorFrequency,
                        SynthParams,
                        ref error);
                    if (error != SynthErrorCodes.eSynthDone)
                    {
                        return(error);
                    }
                }

                return(SynthErrorCodes.eSynthDone);
            }
Example #17
0
            /* create a new track user effect processor */
            public static SynthErrorCodes NewTrackUserEffectProc(
                UserEffectSpecRec Template,
                SynthParamRec SynthParams,
                out UserEffectProcRec effectOut)
            {
                effectOut = null;

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

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

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

                Proc.params_Track = new UserEffectParamRec_Track[Proc.paramCount];

                /* initialize argument evaluators */
                for (int i = 0; i < Proc.paramCount; i += 1)
                {
                    GetUserEffectSpecParamAgg(
                        Template,
                        i,
                        out Proc.params_Track[i].Eval);
                }

                effectOut = Proc;
                return(SynthErrorCodes.eSynthDone);
            }
Example #18
0
            /* apply filter to an array of values, adding result to output array */
            public void Apply(
                float[] XinVector,
                int XinVectorOffset,
                float[] YoutVector,
                int YoutVectorOffset,
                int VectorLength,
                float OutputScaling,
                SynthParamRec SynthParams)
            {
                ParametricEqualizerRec Filter = this;

                float State1 = Filter.State1;
                float State0 = Filter.State0;
                float A      = Filter.A;
                float B      = Filter.B;
                float K      = Filter.K;

                float OneMinusK = 1 - K;
                float OnePlusK  = 1 + K;

                for (int i = 0; i < VectorLength; i += 1)
                {
                    float Xin      = XinVector[i + XinVectorOffset];
                    float OrigYOut = YoutVector[i + YoutVectorOffset];
                    float Allpass  = A * (Xin - A * State1) + State1;
                    float Outval   = .5f * (OnePlusK * Xin + OneMinusK * Allpass);
                    float Temp     = Xin - A * State1 - B * State0;
                    State1 = B * Temp + State0;
                    State0 = Temp;
                    YoutVector[i + YoutVectorOffset] = OrigYOut + Outval * OutputScaling;
                }

                Filter.State1 = State1;
                Filter.State0 = State0;
            }
        /* 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);
        }
Example #20
0
 public void Finalize(
     SynthParamRec SynthParams,
     bool writeOutputLogs)
 {
     Coefficients.Dispose();
     LeftState.Dispose();
     RightState.Dispose();
 }
        /* apply effects to data generated during this envelope clock cycle.  this is the */
        /* second half of the control-update cycle. */
        public static SynthErrorCodes ApplyTrackEffectGenerator(
            TrackEffectGenRec Generator,
            float[] workspace,
            int nActualFrames,
            int lOffset,
            int rOffset,
            SynthParamRec SynthParams)
        {
            OneEffectRec Scan = Generator.List;

            if (Scan != null)
            {
                /* auto-quiescence prepass -- if input exceeds level, then enable */
                if (Generator.AutoQuiescence)
                {
                    AutoQuiescenceDetector(
                        Generator,
                        workspace,
                        lOffset,
                        rOffset,
                        nActualFrames,
                        true /*examining input data*/);
                }

                if (Generator.Enable)
                {
                    while (Scan != null)
                    {
                        SynthErrorCodes error = Scan.u.Apply(
                            workspace,
                            lOffset,
                            rOffset,
                            nActualFrames,
                            SynthParams);
                        if (error != SynthErrorCodes.eSynthDone)
                        {
                            return(error);
                        }
                        Scan = Scan.Next;
                    }

                    /* auto-quiescence postpass -- if effects were applied, then */
                    /* examine the output */
                    if (Generator.AutoQuiescence)
                    {
                        AutoQuiescenceDetector(
                            Generator,
                            workspace,
                            lOffset,
                            rOffset,
                            nActualFrames,
                            false /*examining output data*/);
                    }
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }
Example #22
0
        /* perform a single cycle of the envelope and return the amplitude for it's */
        /* point.  should be called at key-down to obtain initial amplitude. */
        public static double EnvelopeUpdate(
            EvalEnvelopeRec State,
            double OscillatorPitch,
            SynthParamRec SynthParams,
            ref SynthErrorCodes ErrorRef)
        {
            if (ErrorRef != SynthErrorCodes.eSynthDone)
            {
                return(0);
            }

            /* evaluate the segment generator */
            double Temp = State.EnvelopeUpdate(State);

            /* apply optional pitch scaling */
            if (State.PerformGlobalPitchScaling)
            {
                Temp = Temp * Math.Pow(2, -(Math.Log(OscillatorPitch
                                                     / State.Template.GlobalPitchRateNormalization) * Constants.INVLOG2)
                                       * State.Template.GlobalPitchRateRolloff);
            }

            /* apply optional transformation formula */
            if (State.Template.Formula != null)
            {
                AccentRec Accents;
                AccentRec TrackAccents;

                /* get current live accent info */
                State.ParamGetter(
                    State.ParamGetterContext,
                    out Accents,
                    out TrackAccents);

                /* add in the original differential that the note provided */
                AccentAdd(
                    1,
                    ref State.FrozenNoteAccentDifferential,
                    ref Accents,
                    ref Accents);

                /* evaluate */
                SynthErrorCodes error = EnvelopeParamEval(
                    Temp,
                    State.Template.Formula,
                    ref Accents,
                    ref TrackAccents,
                    SynthParams,
                    out Temp);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    ErrorRef = error;
                    return(0);
                }
            }

            return(Temp);
        }
Example #23
0
            /* build common stuff */
            private static VocoderRec VocoderBuildCommonStructure(
                VocoderSpecRec Template,
                SynthParamRec SynthParams)
            {
                int BandCount;
                int OrderCount;

                float[][] WaveTableMatrix;
                int       FramesPerTable;
                int       NumberOfTables;

                if (!WaveSampDictGetWaveTableInfo(
                        SynthParams.Dictionary,
                        GetVocoderSpecWaveTableName(Template),
                        out WaveTableMatrix,
                        out FramesPerTable,
                        out NumberOfTables))
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }

                BandCount  = GetVocoderMaxNumBands(Template);
                OrderCount = GetVocoderFilterOrder(Template) / 2;
                if (BandCount > FramesPerTable / VOC_FIELDCOUNT)
                {
                    BandCount = FramesPerTable / VOC_FIELDCOUNT;
                }

                VocoderRec Vocoder = new VocoderRec();

                Vocoder.CombinedGainFactorVector = new float[2 * BandCount];
                Vocoder.FilterVector             = new ButterworthBandpassRec[2 * BandCount * OrderCount];

                Vocoder.BandCount  = BandCount;
                Vocoder.OrderCount = OrderCount;

                Vocoder.ForceFilterUpdate      = true;
                Vocoder.PreviousOutputScaling  = 0;
                Vocoder.PreviousWaveTableIndex = -1;

                Vocoder.WaveTableMatrix      = WaveTableMatrix;
                Vocoder.FramesPerTable       = FramesPerTable;
                Vocoder.NumberOfTablesMinus1 = NumberOfTables - 1;

                Vocoder.EnableCrossWaveTableInterpolation = VocoderGetEnableCrossWaveTableInterpolation(Template);

                /* initialize band matrix */
                for (int i = 0; i < 2 * BandCount * OrderCount; i++)
                {
                    Vocoder.FilterVector[i] = new ButterworthBandpassRec();
                }

                return(Vocoder);
            }
Example #24
0
            /* update vocoder state with accent information */
            public SynthErrorCodes OscUpdateEnvelopes(
                double OscillatorFrequency,
                SynthParamRec SynthParams)
            {
                SynthErrorCodes error;
                double          DoubleTemp;

                error = SynthErrorCodes.eSynthDone;
                this.CurrentOutputScaling = LFOGenUpdateCycle(
                    this.Oscillator.OutputScalingLFO,
                    EnvelopeUpdate(
                        this.Oscillator.OutputScalingEnvelope,
                        OscillatorFrequency,
                        SynthParams,
                        ref error),
                    OscillatorFrequency,
                    SynthParams,
                    ref error);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }

                error      = SynthErrorCodes.eSynthDone;
                DoubleTemp = this.NumberOfTablesMinus1 *
                             LFOGenUpdateCycle(
                    this.Oscillator.WaveTableIndexLFO,
                    EnvelopeUpdate(
                        this.Oscillator.WaveTableIndexEnvelope,
                        OscillatorFrequency,
                        SynthParams,
                        ref error),
                    OscillatorFrequency,
                    SynthParams,
                    ref error);
                if (error != SynthErrorCodes.eSynthDone)
                {
                    return(error);
                }
                if (DoubleTemp < 0)
                {
                    DoubleTemp = 0;
                }
                else if (DoubleTemp > this.NumberOfTablesMinus1)
                {
                    DoubleTemp = this.NumberOfTablesMinus1;
                }
                this.CurrentWaveTableIndex = DoubleTemp;

                return(SynthErrorCodes.eSynthDone);
            }
Example #25
0
            public unsafe AlignedWorkspace(int count)
            {
                this.length     = count;
                this.workspace  = new float[count + SynthParamRec.WORKSPACEALIGNBYTES];
                this.hWorkspace = GCHandle.Alloc(this.workspace, GCHandleType.Pinned);
                fixed(float *pWorkspace0 = &(this.workspace[0]))
                {
                    IntPtr iWorkspace0 = new IntPtr(pWorkspace0);

                    this.offset = 0;
                    SynthParamRec.Align(iWorkspace0, ref this.offset, SynthParamRec.WORKSPACEALIGNBYTES, SizeOfFloat);
                    Debug.Assert(this.offset + count <= this.workspace.Length);
                }
            }
Example #26
0
            public SynthErrorCodes Apply(
                float leftLoudness,
                float rightLoudness,
                float[] workspace32Base,
                int lOffset,
                int rOffset,
                int[] smoothedOffsets,
                bool[] smoothedNonConst,
                int[] scratchWorkspaces32Offsets,
                double[] scratchWorkspace64Base,
                int[] scratchWorksace64Offsets,
                int nActualFrames,
                SynthParamRec SynthParams)
            {
                double delta = TWOPI * pitch / SynthParams.dSamplingRate;

                if (smoothed)
                {
                    for (int i = 0; i < nActualFrames; i++)
                    {
                        float smoothedLoudness = workspace32Base[i + smoothedOffsets[0]];
                        float v = (float)Math.Sin(phase) * smoothedLoudness;
                        workspace32Base[i + lOffset] += v * leftLoudness;
                        workspace32Base[i + rOffset] += v * rightLoudness;
                        phase += delta;
                        while (phase >= TWOPI)
                        {
                            phase -= TWOPI;
                        }
                    }
                }
                else
                {
                    leftLoudness  *= (float)loudness;
                    rightLoudness *= (float)loudness;
                    for (int i = 0; i < nActualFrames; i++)
                    {
                        float v = (float)Math.Sin(phase);
                        workspace32Base[i + lOffset] += v * leftLoudness;
                        workspace32Base[i + rOffset] += v * rightLoudness;
                        phase += delta;
                        while (phase >= TWOPI)
                        {
                            phase -= TWOPI;
                        }
                    }
                }
                return(SynthErrorCodes.eSynthDone);
            }
Example #27
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 #28
0
            public unsafe FFTW(int n, int concurrency, FFT share)
                : base(n, 1f / n)
            {
                Debug.Assert(lockObject != null);
                lock (lockObject)
                {
                    if (share != null)
                    {
                        if (n > share.N)
                        {
                            Debug.Assert(false);
                            throw new ArgumentException();
                        }
                        // share workspace
                        this.workspace  = share.Base;
                        this.hWorkspace = GCHandle.Alloc(this.workspace, GCHandleType.Pinned);
                        this.offset     = share.Offset;
                    }
                    else
                    {
                        // allocate workspace
                        int count = n + 2;
                        this.workspace  = new float[count + SynthParamRec.WORKSPACEALIGNBYTES];
                        this.hWorkspace = GCHandle.Alloc(this.workspace, GCHandleType.Pinned);
                        fixed(float *pWorkspace0 = &(this.workspace[0]))
                        {
                            IntPtr iWorkspace0 = new IntPtr(pWorkspace0);

                            this.offset = 0;
                            SynthParamRec.Align(iWorkspace0, ref this.offset, SynthParamRec.WORKSPACEALIGNBYTES, SizeOfFloat);
                            Debug.Assert(this.offset + count <= this.workspace.Length);
                        }
                    }

                    // create plan
                    IntPtr baseAddr = new IntPtr(this.hWorkspace.AddrOfPinnedObject().ToInt64() + this.offset * SizeOfFloat);
                    int    align    = fftwf_alignment_of(baseAddr);
                    if (align != 0)
                    {
                        // we are not aligning properly for SIMD
                        Dispose();
                        Debug.Assert(false);
                        throw new InvalidOperationException();
                    }
                    fftwf_plan_with_nthreads(Math.Min(concurrency, 1));
                    this.planf = fftwf_plan_dft_r2c_1d(n, baseAddr, baseAddr, FFTW_DESTROY_INPUT);
                    this.plani = fftwf_plan_dft_c2r_1d(n, baseAddr, baseAddr, FFTW_DESTROY_INPUT);
                }
            }
Example #29
0
            /* create a new ideal lowpass processor */
            public static IdealLPRec NewIdealLP(
                IdealLPSpecRec Template,
                SynthParamRec SynthParams)
            {
                IdealLPRec IdealLP = new IdealLPRec();

                IdealLP.Cutoff = IdealLowpassSpecGetCutoff(Template);
                IdealLP.Order  = IdealLowpassSpecGetOrder(Template);
#if DEBUG
                if ((IdealLP.Order < 1) || ((IdealLP.Order % 2) == 0))
                {
                    // order must be positive odd integer
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif
                IdealLP.Order &= 0x1fffffff; /* some sanity -- will result in out of mem instead of gpf */

                IdealLP.OneChannelLength = 1;
                while (IdealLP.OneChannelLength < IdealLP.Order)
                {
                    IdealLP.OneChannelLength = IdealLP.OneChannelLength << 1;
                }

                IdealLP.Coefficients = new AlignedWorkspace(IdealLP.Order);

                int vectorPadding = 0;
#if VECTOR
                if (EnableVector)
                {
                    vectorPadding = Vector <float> .Count - 1;
                }
#endif
                IdealLP.LeftState  = new AlignedWorkspace(IdealLP.OneChannelLength + vectorPadding);
                IdealLP.RightState = new AlignedWorkspace(IdealLP.OneChannelLength + vectorPadding);

                IdealLP.FilterEnabled = GenerateIdealLowPassImpulse(
                    IdealLP.Coefficients.Base,
                    IdealLP.Coefficients.Offset,
                    IdealLP.Order,
                    IdealLP.Cutoff,
                    SynthParams.dSamplingRate);
                if (SynthParams.iSamplingRate < GetIdealLowpassMinSamplingRate(Template))
                {
                    IdealLP.FilterEnabled = false;
                }

                return(IdealLP);
            }
            /* 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);
            }