/* 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); }
public static void SetUserEffectSpecParamSmoothed( UserEffectSpecRec Spec, int Index, bool smoothed) { Spec.Items[Index].Smoothed = smoothed; }
/* add a user effect to the spec list */ public static void AddUserEffectToEffectSpecList( EffectSpecListRec EffectSpecList, UserEffectSpecRec UserEffectSpec, bool EnabledFlag) { AddGenericToEffectSpecList(EffectSpecList, EffectTypes.eUserEffect, UserEffectSpec, EnabledFlag); }
/* set various attributes */ public static void PutUserEffectSpecParamAccent( UserEffectSpecRec Spec, int Index, double Value, int AccentNum) { SetAccentMemberValue(ref Spec.Items[Index].ParamAccent, AccentNum, Value); }
/* 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); }
/* 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(); }
/* 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); }
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; }
/* 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; }
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; }
public static DataTypes[] UserEffectGetWorkspaceTypes( UserEffectSpecRec Spec) { return(Spec.workspaces); }
public static bool GetUserEffectSpecNoOversampling( UserEffectSpecRec Spec) { return(Spec.NoOversampling); }
public static void SetUserEffectSpecNoOversampling( UserEffectSpecRec Spec, bool NoOversampling) { Spec.NoOversampling = NoOversampling; }
/* get function symbols (NIL = not specified) */ public static string GetUserEffectSpecInitFuncName(UserEffectSpecRec Spec) { return(Spec.InitFuncName); }
/* 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); }
/* get enveloping things */ public static LFOListSpecRec GetUserEffectSpecParamLFO( UserEffectSpecRec Spec, int Index) { return(Spec.Items[Index].ParamLFO); }
/* get enveloping things */ public static EnvelopeRec GetUserEffectSpecParamEnvelope( UserEffectSpecRec Spec, int Index) { return(Spec.Items[Index].ParamEnvelope); }
/* get function symbols (NIL = not specified) */ public static string[] GetUserEffectSpecProcessDataFuncNames(UserEffectSpecRec Spec) { return(Spec.ProcessDataFuncNames); }
public static bool GetUserEffectSpecParamSmoothed( UserEffectSpecRec Spec, int Index) { return(Spec.Items[Index].Smoothed); }
/* get count of parameters */ public static int GetUserEffectSpecParamCount(UserEffectSpecRec Spec) { return(Spec.Items.Length); }
/* 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); }