Пример #1
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);
            }
Пример #2
0
            /* shared initialization */
            private static SynthErrorCodes UserEffectSharedInit(
                UserEffectProcRec Proc,
                UserEffectSpecRec Template,
                SynthParamRec SynthParams)
            {
                Proc.disableOversampling = GetUserEffectSpecNoOversampling(Template);

                double sr = SynthParams.dSamplingRate;

                if (!((SynthParams.iOversampling == 1) || !Proc.disableOversampling))
                {
                    sr /= SynthParams.iOversampling;
                }

                /* init func */
                {
                    string FuncName = GetUserEffectSpecInitFuncName(Template);
                    if (FuncName != null)
                    {
                        FuncCodeRec FuncCode = SynthParams.CodeCenter.ObtainFunctionHandle(FuncName);
                        if (FuncCode == null)
                        {
                            // Function missing; should have been found by CheckUnreferencedThings
                            Debug.Assert(false);
                            throw new ArgumentException();
                        }

                        DataTypes[] argsTypes;
                        DataTypes   returnType;
                        UserEffectGetInitSignature(Template, out argsTypes, out returnType);
                        FunctionSignature expectedSignature = new FunctionSignature(argsTypes, returnType);
                        FunctionSignature actualSignature   = new FunctionSignature(
                            FuncCode.GetFunctionParameterTypeList(),
                            FuncCode.GetFunctionReturnType());
                        if (!FunctionSignature.Equals(expectedSignature, actualSignature))
                        {
                            // Function type mismatch; should have been found by CheckUnreferencedThings
                            Debug.Assert(false);
                            throw new ArgumentException();
                        }

                        Proc.InitFunc = FuncCode.GetFunctionPcode();
                    }
                }

                /* data func */
                {
                    DataTypes[] argsTypes;
                    DataTypes   returnType;
                    UserEffectGetDataSignature(Template, out argsTypes, out returnType);
                    FunctionSignature expectedSignature = new FunctionSignature(argsTypes, returnType);

                    foreach (string FuncName in GetUserEffectSpecProcessDataFuncNames(Template))
                    {
                        FuncCodeRec FuncCode = SynthParams.CodeCenter.ObtainFunctionHandle(FuncName);
                        if (FuncCode == null)
                        {
                            // Function missing; should have been found by CheckUnreferencedThings
                            Debug.Assert(false);
                            throw new ArgumentException();
                        }

                        FunctionSignature actualSignature = new FunctionSignature(
                            FuncCode.GetFunctionParameterTypeList(),
                            FuncCode.GetFunctionReturnType());
                        if (FunctionSignature.Equals(expectedSignature, actualSignature))
                        {
                            Proc.DataFunc = FuncCode.GetFunctionPcode();
                            break;
                        }
                    }
                    if (Proc.DataFunc == null)
                    {
                        // None matched -- should have been found by CheckUnreferencedThings
                        Debug.Assert(false);
                        throw new ArgumentException();
                    }
                }

                Proc.paramCount           = GetUserEffectSpecParamCount(Template);
                Proc.paramResults         = new double[Proc.paramCount];
                Proc.paramResultsPrevious = new double[Proc.paramCount];

                // create state objects
                DataTypes[] stateTypes = UserEffectGetWorkspaceTypes(Template);
                Proc.userState = new ArrayHandle[stateTypes.Length];
                for (int i = 0; i < Proc.userState.Length; i++)
                {
                    switch (stateTypes[i])
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case DataTypes.eArrayOfInteger:
                        Proc.userState[i] = new ArrayHandleInt32(new int[0]);
                        break;

                    case DataTypes.eArrayOfFloat:
                        Proc.userState[i] = new ArrayHandleFloat(new float[0]);
                        break;

                    case DataTypes.eArrayOfDouble:
                        Proc.userState[i] = new ArrayHandleDouble(new double[0]);
                        break;
                    }
                }

                Proc.smoothingBuffers = new SmoothingEntry[Template.Items.Length];
                for (int i = 0; i < Template.Items.Length; i++)
                {
                    if (Template.Items[i].Smoothed)
                    {
                        float[] vector = new float[SynthParams.nAllocatedPointsOneChannel];
                        Proc.smoothingBuffers[i].vector      = vector;
                        Proc.smoothingBuffers[i].arrayHandle = new ArrayHandleFloat(vector);
                    }
                }

                /* initialize user state */
                if (Proc.InitFunc != null)
                {
                    int argCount = 1                       /*retval*/
                                   + 1                     /*t*/
                                   + 1                     /*bpm*/
                                   + 1                     /*samplingRate*/
                                   + 1                     /*maxSampleCount*/
                                   + Proc.userState.Length /*user state arrays*/
                                   + 1 /*retaddr*/;
                    SynthParams.FormulaEvalContext.EmptyParamStackEnsureCapacity(argCount);

                    StackElement[] StackBase;
                    int            StackNumElements;
                    SynthParams.FormulaEvalContext.GetRawStack(out StackBase, out StackNumElements);

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

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

                    StackBase[StackNumElements++].Data.Double = sr;                                      /* samplingRate */

                    StackBase[StackNumElements++].Data.Integer = SynthParams.nAllocatedPointsOneChannel; /* maxSampleCount */

                    for (int i = 0; i < Proc.userState.Length; i++)
                    {
                        StackBase[StackNumElements++].reference.arrayHandleGeneric = Proc.userState[i]; // user state
                    }

                    StackNumElements++; /* return address placeholder */

                    SynthParams.FormulaEvalContext.UpdateRawStack(StackBase, StackNumElements);

                    EvalErrInfoRec ErrorInfo;
                    EvalErrors     Error = PcodeSystem.EvaluatePcode(
                        SynthParams.FormulaEvalContext,
                        Proc.InitFunc,
                        SynthParams.CodeCenter,
                        out ErrorInfo,
                        PcodeExternsNull.Default,
                        ref SynthParams.pcodeThreadContext);
                    if (Error != EvalErrors.eEvalNoError)
                    {
                        SynthParams.ErrorInfo.ErrorEx           = SynthErrorSubCodes.eSynthErrorExUserEffectFunctionEvalError;
                        SynthParams.ErrorInfo.UserEvalErrorCode = Error;
                        SynthParams.ErrorInfo.UserEvalErrorInfo = ErrorInfo;
                        return(SynthErrorCodes.eSynthErrorEx);
                    }
                    Debug.Assert(SynthParams.FormulaEvalContext.GetStackNumElements() == 1); // return value

                    SynthParams.FormulaEvalContext.Clear();
                }

                // initialize sample data in/out staging areas
                Proc.leftWorkspace        = new float[SynthParams.nAllocatedPointsOneChannel];
                Proc.leftWorkspaceHandle  = new ArrayHandleFloat(null);
                Proc.rightWorkspace       = new float[SynthParams.nAllocatedPointsOneChannel];
                Proc.rightWorkspaceHandle = new ArrayHandleFloat(null);

                return(SynthErrorCodes.eSynthDone);
            }
Пример #3
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);
            }
Пример #4
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);
        }
        /* create a new track effect generator */
        public static SynthErrorCodes NewTrackEffectGenerator(
            EffectSpecListRec SpecList,
            SynthParamRec SynthParams,
            out TrackEffectGenRec GeneratorOut)
        {
            GeneratorOut = null;

            TrackEffectGenRec Generator = new TrackEffectGenRec();

            Generator.Enable         = true;
            Generator.AutoQuiescence = EffectSpecListIsAutoQuiescenceEnabled(SpecList);
            if (Generator.AutoQuiescence)
            {
                Generator.Enable    = false; /* start with it off in this case */
                Generator.GateLevel = (float)(Math.Pow(
                                                  2,
                                                  EffectSpecListGetAutoQuiescenceDecibels(SpecList) * (1 / -6.0205999132796239))
                                              / SynthParams.fOverallVolumeScaling);
                Generator.WindowDuration = (int)(SynthParams.dEnvelopeRate
                                                 * EffectSpecListGetAutoQuiescenceWindowDuration(SpecList));
                Generator.CurrentWindowDuration = 0;
            }

            /* this is the current envelope update index for removing things from the */
            /* scanning gap list (i.e. the back edge of the scanning gap) */
            /* by setting this negative, we cause the scanning gap to open. */
            Generator.ExecutionIndex = -SynthParams.iScanningGapWidthInEnvelopeTicks;

            /* initialize accent trackers */
            InitAccentTracker(ref Generator.Accents0);
            InitAccentTracker(ref Generator.Accents1);
            InitAccentTracker(ref Generator.Accents2);
            InitAccentTracker(ref Generator.Accents3);
            InitAccentTracker(ref Generator.Accents4);
            InitAccentTracker(ref Generator.Accents5);
            InitAccentTracker(ref Generator.Accents6);
            InitAccentTracker(ref Generator.Accents7);

            /* build list of thingers */
            OneEffectRec Appender = null;
            int          l        = GetEffectSpecListLength(SpecList);

            for (int i = 0; i < l; i += 1)
            {
                /* see if effect is enabled */
                if (IsEffectFromEffectSpecListEnabled(SpecList, i))
                {
                    OneEffectRec Effect = new OneEffectRec();

                    /* link */
                    Effect.Next = null;
                    if (Appender == null)
                    {
                        Generator.List = Effect;
                    }
                    else
                    {
                        Appender.Next = Effect;
                    }
                    Appender = Effect;

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

                    case EffectTypes.eDelayEffect:
                        Effect.u = DelayUnifiedRec.NewTrackDelayLineProcessor(
                            GetDelayEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eNLProcEffect:
                        Effect.u = NLProcUnifiedRec.NewTrackNLProcProcessor(
                            GetNLProcEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eFilterEffect:
                        Effect.u = FilterArrayRec.NewTrackFilterArrayProcessor(
                            GetFilterEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eAnalyzerEffect:
                        Effect.u = AnalyzerRec.NewAnalyzer(
                            GetAnalyzerEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eHistogramEffect:
                        Effect.u = HistogramRec.NewHistogram(
                            GetHistogramEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eResamplerEffect:
                        Effect.u = ResamplerRec.NewResampler(
                            GetResamplerEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eCompressorEffect:
                        Effect.u = CompressorRec.NewTrackCompressor(
                            GetCompressorEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eVocoderEffect:
                        Effect.u = VocoderRec.NewTrackVocoder(
                            GetVocoderEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eIdealLowpassEffect:
                        Effect.u = IdealLPRec.NewIdealLP(
                            GetIdealLPEffectFromEffectSpecList(SpecList, i),
                            SynthParams);
                        break;

                    case EffectTypes.eConvolverEffect:
                    {
                        ConvolverRec    ConvolverEffect;
                        SynthErrorCodes Result = ConvolverRec.NewConvolver(
                            GetConvolverEffectFromEffectSpecList(SpecList, i),
                            SynthParams,
                            out ConvolverEffect);
                        if (Result != SynthErrorCodes.eSynthDone)
                        {
                            return(Result);
                        }
                        Effect.u = ConvolverEffect;
                    }
                    break;

                    case EffectTypes.eUserEffect:
                    {
                        UserEffectProcRec userEffect;
                        SynthErrorCodes   error = UserEffectProcRec.NewTrackUserEffectProc(
                            GetUserEffectFromEffectSpecList(SpecList, i),
                            SynthParams,
                            out userEffect);
                        if (error != SynthErrorCodes.eSynthDone)
                        {
                            return(error);
                        }
                        Effect.u = userEffect;
                    }
                    break;

                    case EffectTypes.ePluggableEffect:
                    {
                        PluggableSpec Spec = GetPluggableEffectFromEffectSpecList(SpecList, i);
                        Debug.Assert(Spec is PluggableTrackSpec);
                        PluggableTrackEffectTemplate Template = new PluggableTrackEffectTemplate(
                            (PluggableTrackSpec)Spec,
                            SynthParams);
                        ITrackEffect    effect;
                        SynthErrorCodes error = Template.Create(
                            SynthParams,
                            out effect);
                        if (error != SynthErrorCodes.eSynthDone)
                        {
                            return(error);
                        }
                        Effect.u = effect;
                    }
                    break;
                    }
                }
            }

            GeneratorOut = Generator;
            return(SynthErrorCodes.eSynthDone);
        }