Beispiel #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);
            }
Beispiel #2
0
 public static void SetUserEffectSpecParamSmoothed(
     UserEffectSpecRec Spec,
     int Index,
     bool smoothed)
 {
     Spec.Items[Index].Smoothed = smoothed;
 }
Beispiel #3
0
 /* add a user effect to the spec list */
 public static void AddUserEffectToEffectSpecList(
     EffectSpecListRec EffectSpecList,
     UserEffectSpecRec UserEffectSpec,
     bool EnabledFlag)
 {
     AddGenericToEffectSpecList(EffectSpecList, EffectTypes.eUserEffect, UserEffectSpec, EnabledFlag);
 }
Beispiel #4
0
 /* set various attributes */
 public static void PutUserEffectSpecParamAccent(
     UserEffectSpecRec Spec,
     int Index,
     double Value,
     int AccentNum)
 {
     SetAccentMemberValue(ref Spec.Items[Index].ParamAccent, AccentNum, Value);
 }
Beispiel #5
0
 /* retrieve various attributes */
 public static void GetUserEffectSpecParamAgg(
     UserEffectSpecRec Spec,
     int Index,
     out ScalarParamEvalRec ParamsOut)
 {
     InitScalarParamEval(
         Spec.Items[Index].Param,
         ref Spec.Items[Index].ParamAccent,
         Spec.Items[Index].ParamFormula,
         out ParamsOut);
 }
Beispiel #6
0
        /* create new param */
        public static void AddUserEffectSpecParam(
            UserEffectSpecRec Spec,
            out int Index)
        {
            ItemRec Item = new ItemRec();

            Index = Spec.Items.Length;
            Array.Resize(ref Spec.Items, Spec.Items.Length + 1);
            Spec.Items[Index] = Item;

            Item.ParamEnvelope = NewEnvelope();
            Item.ParamLFO      = NewLFOListSpecifier();
        }
Beispiel #7
0
        /* create a new user effect processor specifier.  name block is deleted */
        public static UserEffectSpecRec NewUserEffectSpec(
            string InitFuncName,
            string[] ProcessDataFuncNames,
            DataTypes[] workspaces)
        {
            UserEffectSpecRec Spec = new UserEffectSpecRec();

            Spec.Items = new ItemRec[0];

            Spec.workspaces           = workspaces;
            Spec.InitFuncName         = InitFuncName;         // can be null
            Spec.ProcessDataFuncNames = ProcessDataFuncNames; // can be null

            return(Spec);
        }
Beispiel #8
0
        public static void UserEffectGetInitSignature(
            UserEffectSpecRec UserEffect,
            out DataTypes[] argsTypesOut,
            out DataTypes returnTypeOut)
        {
            List <DataTypes> argsTypes = new List <DataTypes>();

            argsTypes.Add(DataTypes.eDouble);          // 't'
            argsTypes.Add(DataTypes.eDouble);          // 'bpm'
            argsTypes.Add(DataTypes.eDouble);          // 'samplingRate'
            argsTypes.Add(DataTypes.eInteger);         // 'maxSampleCount'
            argsTypes.AddRange(UserEffect.workspaces); // user-specified workspace arrays

            argsTypesOut  = argsTypes.ToArray();
            returnTypeOut = DataTypes.eBoolean;
        }
Beispiel #9
0
        /* set various attributes */
        public static void PutUserEffectSpecParam(
            UserEffectSpecRec Spec,
            int Index,
            double Param,
            PcodeRec ParamFormula)
        {
#if DEBUG
            if (Spec.Items[Index].ParamFormula != null)
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
#endif
            Spec.Items[Index].ParamFormula = ParamFormula;
            Spec.Items[Index].Param        = Param;
        }
Beispiel #10
0
        public static void UserEffectGetDataSignature(
            UserEffectSpecRec UserEffect,
            out DataTypes[] argsTypesOut,
            out DataTypes returnTypeOut)
        {
            List <DataTypes> argsTypes = new List <DataTypes>();

            argsTypes.Add(DataTypes.eDouble);          // 't'
            argsTypes.Add(DataTypes.eDouble);          // 'bpm'
            argsTypes.Add(DataTypes.eDouble);          // 'samplingRate'
            argsTypes.Add(DataTypes.eArrayOfFloat);    // 'leftData'
            argsTypes.Add(DataTypes.eArrayOfFloat);    // 'rightData'
            argsTypes.Add(DataTypes.eInteger);         // 'sampleCount'
            argsTypes.AddRange(UserEffect.workspaces); // user-specified workspace arrays
            for (int i = 0; i < UserEffect.Items.Length; i++)
            {
                argsTypes.Add(UserEffect.Items[i].Smoothed ? DataTypes.eArrayOfFloat : DataTypes.eDouble); // user-specified control param
            }

            argsTypesOut  = argsTypes.ToArray();
            returnTypeOut = DataTypes.eBoolean;
        }
Beispiel #11
0
 public static DataTypes[] UserEffectGetWorkspaceTypes(
     UserEffectSpecRec Spec)
 {
     return(Spec.workspaces);
 }
Beispiel #12
0
 public static bool GetUserEffectSpecNoOversampling(
     UserEffectSpecRec Spec)
 {
     return(Spec.NoOversampling);
 }
Beispiel #13
0
 public static void SetUserEffectSpecNoOversampling(
     UserEffectSpecRec Spec,
     bool NoOversampling)
 {
     Spec.NoOversampling = NoOversampling;
 }
Beispiel #14
0
 /* get function symbols (NIL = not specified) */
 public static string GetUserEffectSpecInitFuncName(UserEffectSpecRec Spec)
 {
     return(Spec.InitFuncName);
 }
Beispiel #15
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);
            }
Beispiel #16
0
 /* get enveloping things */
 public static LFOListSpecRec GetUserEffectSpecParamLFO(
     UserEffectSpecRec Spec,
     int Index)
 {
     return(Spec.Items[Index].ParamLFO);
 }
Beispiel #17
0
 /* get enveloping things */
 public static EnvelopeRec GetUserEffectSpecParamEnvelope(
     UserEffectSpecRec Spec,
     int Index)
 {
     return(Spec.Items[Index].ParamEnvelope);
 }
Beispiel #18
0
 /* get function symbols (NIL = not specified) */
 public static string[] GetUserEffectSpecProcessDataFuncNames(UserEffectSpecRec Spec)
 {
     return(Spec.ProcessDataFuncNames);
 }
Beispiel #19
0
 public static bool GetUserEffectSpecParamSmoothed(
     UserEffectSpecRec Spec,
     int Index)
 {
     return(Spec.Items[Index].Smoothed);
 }
Beispiel #20
0
 /* get count of parameters */
 public static int GetUserEffectSpecParamCount(UserEffectSpecRec Spec)
 {
     return(Spec.Items.Length);
 }
Beispiel #21
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);
            }
        /* check user effect */
        public static SynthErrorCodes CheckUserEffectForUnreferencedSamples(
            UserEffectSpecRec UserEffect,
            CheckUnrefParamRec Param)
        {
            /* init func */
            {
                string FuncName = GetUserEffectSpecInitFuncName(UserEffect);
                if (FuncName != null) /* optional */
                {
                    FuncCodeRec FuncCode = Param.CodeCenter.ObtainFunctionHandle(FuncName);
                    if (FuncCode == null)
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExUndefinedFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        return(SynthErrorCodes.eSynthErrorEx);
                    }

                    DataTypes[] argsTypes;
                    DataTypes   returnType;
                    UserEffectGetInitSignature(UserEffect, out argsTypes, out returnType);
                    FunctionSignature expectedSignature = new FunctionSignature(argsTypes, returnType);
                    FunctionSignature actualSignature   = new FunctionSignature(
                        FuncCode.GetFunctionParameterTypeList(),
                        FuncCode.GetFunctionReturnType());
                    if (!FunctionSignature.Equals(expectedSignature, actualSignature))
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExTypeMismatchFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        Param.ErrorInfo.ExtraInfo    = String.Format(
                            "{0}{0}Expected:{0}{1}{0}{0}Actual:{0}{2}",
                            Environment.NewLine,
                            expectedSignature,
                            actualSignature);
                        return(SynthErrorCodes.eSynthErrorEx);
                    }
                }
            }

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

                bool matched = false;
                List <KeyValuePair <string, FunctionSignature> > actualSignatures = new List <KeyValuePair <string, FunctionSignature> >();
                foreach (string FuncName in GetUserEffectSpecProcessDataFuncNames(UserEffect))
                {
                    FuncCodeRec FuncCode = Param.CodeCenter.ObtainFunctionHandle(FuncName);
                    if (FuncCode == null)
                    {
                        Param.ErrorInfo.ErrorEx      = SynthErrorSubCodes.eSynthErrorExUndefinedFunction;
                        Param.ErrorInfo.FunctionName = FuncName;
                        return(SynthErrorCodes.eSynthErrorEx);
                    }

                    FunctionSignature actualSignature = new FunctionSignature(
                        FuncCode.GetFunctionParameterTypeList(),
                        FuncCode.GetFunctionReturnType());
                    actualSignatures.Add(new KeyValuePair <string, FunctionSignature>(FuncName, actualSignature));
                    if (FunctionSignature.Equals(expectedSignature, actualSignature))
                    {
                        matched = true;
                        break;
                    }
                }
                if (!matched)
                {
                    StringBuilder extraInfo = new StringBuilder();
                    extraInfo.AppendLine();
                    extraInfo.AppendLine();
                    extraInfo.AppendLine(String.Format("Expected - {0}", expectedSignature));
                    foreach (KeyValuePair <string, FunctionSignature> actualSignature in actualSignatures)
                    {
                        extraInfo.AppendLine();
                        extraInfo.AppendLine(String.Format("Actual - {0}{1}", actualSignature.Key, actualSignature.Value));
                    }
                    Param.ErrorInfo.ErrorEx   = SynthErrorSubCodes.eSynthErrorExTypeMismatchFunctionMultiple;
                    Param.ErrorInfo.ExtraInfo = extraInfo.ToString();
                    return(SynthErrorCodes.eSynthErrorEx);
                }
            }

            return(SynthErrorCodes.eSynthDone);
        }