/* 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); }
public PcodeEvaluationErrorInfo(EvalErrors EvaluationError, EvalErrInfoRec ErrorInfo, PcodeRec AnonymousFunction, CodeCenterRec CodeCenter) { int ErrorLineNumberEvaluation; string Name; FuncCodeRec ErrorFunction = CodeCenter.GetFunctionFromOpcode(ErrorInfo.OffendingPcode); if (ErrorFunction != null) { Name = ErrorFunction.GetFunctionFilename(); ErrorLineNumberEvaluation = ErrorFunction.GetFunctionPcode().GetLineNumberForInstruction(ErrorInfo.OffendingInstruction); } else { Name = "<anonymous>"; ErrorLineNumberEvaluation = AnonymousFunction.GetLineNumberForInstruction(ErrorInfo.OffendingInstruction); } this.module = Name; this.errorText = PcodeSystem.GetPcodeErrorMessage(EvaluationError); this.lineNumber = ErrorLineNumberEvaluation; }
private void Eval() { if (!mainWindow.MakeUpToDate()) { return; } int ErrorLineNumberCompilation; DataTypes ReturnType; PcodeRec FuncCode; Compiler.ASTExpression AST; CompileErrors CompileError = Compiler.CompileSpecialFunction( mainWindow.Document.CodeCenter, new FunctionParamRec[] { new FunctionParamRec("frames", DataTypes.eInteger), new FunctionParamRec("tables", DataTypes.eInteger), new FunctionParamRec("data", DataTypes.eArrayOfFloat), }, out ErrorLineNumberCompilation, out ReturnType, textBoxFormula.Text, false/*suppressCILEmission*/, out FuncCode, out AST); if (CompileError != CompileErrors.eCompileNoError) { textBoxFormula.Focus(); textBoxFormula.SetSelectionLine(ErrorLineNumberCompilation - 1); textBoxFormula.ScrollToSelection(); LiteralBuildErrorInfo errorInfo = new LiteralBuildErrorInfo(Compiler.GetCompileErrorString(CompileError), ErrorLineNumberCompilation); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } using (ParamStackRec ParamList = new ParamStackRec()) { int numFrames = waveTableObject.WaveTableData.NumFrames; int numTables = waveTableObject.WaveTableData.NumTables; float[] vector = new float[numFrames * numTables]; ArrayHandleFloat dataHandle = new ArrayHandleFloat(vector); int initialCapacity = 1/*frames*/ + 1/*tables*/ + 1/*data*/ + 1/*retaddr*/; ParamList.EmptyParamStackEnsureCapacity(initialCapacity); ParamList.AddIntegerToStack(numFrames); ParamList.AddIntegerToStack(numTables); ParamList.AddArrayToStack(dataHandle); ParamList.AddIntegerToStack(0); /* return address placeholder */ for (int i = 0; i < numTables; i++) { WaveTableStorageRec.Table table = waveTableObject.WaveTableData.ListOfTables[i]; for (int j = 0; j < numFrames; j++) { vector[i * numFrames + j] = table[j]; } } CodeCenterRec CodeCenter = mainWindow.Document.CodeCenter; EvalErrInfoRec ErrorInfo; EvalErrors EvaluationError = PcodeSystem.EvaluatePcodeThread.EvaluatePcode( ParamList, FuncCode, CodeCenter, out ErrorInfo, new PcodeExterns(mainWindow)); if (EvaluationError != EvalErrors.eEvalNoError) { PcodeEvaluationErrorInfo errorInfo = new PcodeEvaluationErrorInfo( EvaluationError, ErrorInfo, FuncCode, CodeCenter); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } Debug.Assert(ParamList.GetStackNumElements() == initialCapacity); // args - retaddr + return value #if DEBUG ParamList.Elements[2].AssertFloatArray(); #endif dataHandle = ParamList.Elements[2].reference.arrayHandleFloat; WaveTableStorageRec NewTable = new WaveTableStorageRec(numTables, numFrames, waveTableObject.WaveTableData.NumBits); float[] NewData = dataHandle.floats; if (NewData.Length != numTables * numFrames) { PcodeEvaluationErrorInfo errorInfo = new PcodeEvaluationErrorInfo( "<anonymous>", PcodeSystem.GetPcodeErrorMessage(EvalErrors.eEvalArrayWrongDimensions), 1); MessageBox.Show(errorInfo.CompositeErrorMessage, "Error", MessageBoxButtons.OK); return; } SampConv.QuantizeAndClampVector(NewData, NewTable.NumBits); for (int i = 0; i < numTables; i++) { WaveTableStorageRec.Table table = NewTable.ListOfTables[i]; for (int j = 0; j < numFrames; j++) { table[j] = NewData[i * numFrames + j]; } } undo.Push(waveTableObject.WaveTableData); redo.Clear(); waveTableObject.WaveTableData = NewTable; } }
/* 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); }
/* apply user effect processing to some stuff */ public SynthErrorCodes Apply( float[] workspace, int lOffset, int rOffset, int nActualFrames, SynthParamRec SynthParams) { Debug.Assert(nActualFrames % SynthParams.iOversampling == 0); // reinit each cycle because user code can reallocate or remove them leftWorkspaceHandle.floats = leftWorkspace; rightWorkspaceHandle.floats = rightWorkspace; int c = nActualFrames; double sr = SynthParams.dSamplingRate; if ((SynthParams.iOversampling == 1) || !disableOversampling) { FloatVectorCopyUnaligned( workspace, lOffset, leftWorkspaceHandle.floats, // not vector-aligned 0, nActualFrames); FloatVectorCopyUnaligned( workspace, rOffset, rightWorkspaceHandle.floats, // not vector-aligned 0, nActualFrames); } else { // downsample c /= SynthParams.iOversampling; sr /= SynthParams.iOversampling; for (int i = 0, j = 0; i < nActualFrames; i += SynthParams.iOversampling, j++) { leftWorkspaceHandle.floats[j] = workspace[i + lOffset]; rightWorkspaceHandle.floats[j] = workspace[i + rOffset]; } } int argCount = 1 /*retval*/ + 1 /*t*/ + 1 /*bpm*/ + 1 /*samplingRate*/ + 1 /*leftdata*/ + 1 /*rightdata*/ + 1 /*count*/ + userState.Length /*user state*/ + paramCount /*user params*/ + 1 /*retaddr*/; SynthParams.FormulaEvalContext.EmptyParamStackEnsureCapacity(argCount); int StackNumElements; StackElement[] StackBase; 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++].reference.arrayHandleFloat = leftWorkspaceHandle; // leftdata StackBase[StackNumElements++].reference.arrayHandleFloat = rightWorkspaceHandle; // rightdata StackBase[StackNumElements++].Data.Integer = c; for (int i = 0; i < userState.Length; i++) { StackBase[StackNumElements++].reference.arrayHandleGeneric = userState[i]; // user state } for (int i = 0; i < paramCount; i += 1) { if (smoothingBuffers[i].arrayHandle == null) { StackBase[StackNumElements++].Data.Double = paramResults[i]; // user params } else { // re-initialize handle in case user code cleared it last time smoothingBuffers[i].arrayHandle.floats = smoothingBuffers[i].vector; // compute smoothed data #if DEBUG Debug.Assert(!SynthParams.ScratchWorkspace1InUse); #endif if (smoothingBuffers[i].degraded) { FloatVectorSet( SynthParams.workspace, SynthParams.ScratchWorkspace1LOffset, nActualFrames, (float)paramResults[i]); } else { if ((params_Osc == null) || !EnvelopeCurrentSegmentExponential(params_Osc[i].Envelope)) { // linear FloatVectorAdditiveRecurrence( SynthParams.workspace, SynthParams.ScratchWorkspace1LOffset, (float)paramResultsPrevious[i], (float)paramResults[i], nActualFrames); } else { // geometric FloatVectorMultiplicativeRecurrence( SynthParams.workspace, SynthParams.ScratchWorkspace1LOffset, (float)paramResultsPrevious[i], (float)paramResults[i], nActualFrames); } } FloatVectorCopyUnaligned( SynthParams.workspace, SynthParams.ScratchWorkspace1LOffset, smoothingBuffers[i].vector, // target not aligned 0, nActualFrames); StackBase[StackNumElements++].reference.arrayHandleFloat = smoothingBuffers[i].arrayHandle; // user params } } StackNumElements++; /* return address placeholder */ SynthParams.FormulaEvalContext.UpdateRawStack(StackBase, StackNumElements); EvalErrInfoRec ErrorInfo; EvalErrors Error = PcodeSystem.EvaluatePcode( SynthParams.FormulaEvalContext, this.DataFunc, 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(); if ((leftWorkspaceHandle.floats != null) && (leftWorkspaceHandle.floats.Length >= c) && (rightWorkspaceHandle.floats != null) && (rightWorkspaceHandle.floats.Length >= c)) { if ((SynthParams.iOversampling == 1) || !disableOversampling) { // remove NaN/Infinity - prevent user effect misbehavior from taking rest of system down FloatVectorCopyReplaceNaNInf( leftWorkspaceHandle.floats, // unaligned permitted 0, workspace, lOffset, nActualFrames); FloatVectorCopyReplaceNaNInf( rightWorkspaceHandle.floats, // unaligned permitted 0, workspace, rOffset, nActualFrames); } else { // upsample Upsample( leftWorkspaceHandle.floats, 0, workspace, lOffset, c, SynthParams.iOversampling, ref lastLeft); Upsample( rightWorkspaceHandle.floats, 0, workspace, rOffset, c, SynthParams.iOversampling, ref lastRight); // remove NaN/Infinity - prevent user effect misbehavior from taking rest of system down FloatVectorCopyReplaceNaNInf( workspace, lOffset, workspace, lOffset, nActualFrames); FloatVectorCopyReplaceNaNInf( workspace, rOffset, workspace, rOffset, nActualFrames); } } return(SynthErrorCodes.eSynthDone); }
public override bool EnsureBuilt( bool force, PcodeSystem.IEvaluationContext pcodeEnvironment, BuildFailedCallback failedCallback) { if (!force && (WaveTableData != null)) { return(true); } WaveTableData = null; PcodeRec FuncCode; if (!BuildCode(failedCallback, out FuncCode)) { return(false); } using (ParamStackRec ParamList = new ParamStackRec()) { ArrayHandleFloat dataHandle = new ArrayHandleFloat(new float[NumFrames * NumTables]); int initialCapacity = 1 /*frames*/ + 1 /*tables*/ + 1 /*data*/ + 1 /*retaddr*/; ParamList.EmptyParamStackEnsureCapacity(initialCapacity); ParamList.AddIntegerToStack(NumFrames); ParamList.AddIntegerToStack(NumTables); ParamList.AddArrayToStack(dataHandle); ParamList.AddIntegerToStack(0); /* return address placeholder */ CodeCenterRec CodeCenter = ((Document)Parent).CodeCenter; EvalErrInfoRec ErrorInfo; EvalErrors EvaluationError = PcodeSystem.EvaluatePcodeThread.EvaluatePcode( ParamList, FuncCode, CodeCenter, out ErrorInfo, pcodeEnvironment); if (EvaluationError != EvalErrors.eEvalNoError) { failedCallback( this, new PcodeEvaluationErrorInfo( EvaluationError, ErrorInfo, FuncCode, CodeCenter)); return(false); } Debug.Assert(ParamList.GetStackNumElements() == initialCapacity); // args - retaddr + return value #if DEBUG ParamList.Elements[2].AssertFloatArray(); #endif dataHandle = ParamList.Elements[2].reference.arrayHandleFloat; WaveTableData = new WaveTableStorageRec(NumTables, NumFrames, NumBitsType.eSample24bit); float[] NewData = dataHandle.floats; if (NewData.Length != NumTables * NumFrames) { failedCallback( this, new PcodeEvaluationErrorInfo( "<anonymous>", PcodeSystem.GetPcodeErrorMessage(EvalErrors.eEvalArrayWrongDimensions), 1)); return(false); } for (int i = 0; i < NumTables; i++) { WaveTableStorageRec.Table table = WaveTableData.ListOfTables[i]; for (int j = 0; j < NumFrames; j++) { table[j] = NewData[i * NumFrames + j]; } } } return(true); }