/* 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); }
/* 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); }
/* 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); } }
/* 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); }
/* 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; } }
/* 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; }
public static void FreeEnvelopeStateRecord( ref EvalEnvelopeRec State, SynthParamRec SynthParams) { Free(ref SynthParams.freelists.envelopeOnePhaseFreeList, ref State.PhaseVector); Free(ref SynthParams.freelists.envelopeStateFreeList, ref State); }
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); } } }
/* 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); }
/* 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); }
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); } }
/* 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); } }
/* 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); }
/* 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); }
/* 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); }
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); }
/* 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); }
/* 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); }
/* 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); }
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); } }
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); }
/* 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); }
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); } }
/* 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); }