public BfxrGenerator(BfxrParameters p) { this.rand = new Random(); this.state.period = 100.0 / (p.StartFrequency * p.StartFrequency + 0.001); this.state.maxPeriod = 100.0 / (p.MinFrequency * p.MinFrequency + 0.001); this.state.slide = 1.0 - 0.01 * p.Slide * p.Slide * p.Slide; this.state.deltaSlide = -0.000001 * p.DeltaSlide * p.DeltaSlide * p.DeltaSlide; this.state.squareDuty = 0; this.state.dutySweep = 0; if (p.Wave == BfxrWave.Square) { this.state.squareDuty = 0.5 - 0.5 * p.SquareDuty; this.state.dutySweep = -0.00005 * p.DutySweep; } this.state.changePeriod = (int)((1.1 - p.ChangeRepeat) * (20000 / 1.1) + 32); this.state.changePeriodTime = 0; this.state.changeAmount = p.ChangeAmount > 0 ? 1.0 - 0.9 * p.ChangeAmount * p.ChangeAmount : 1.0 + 10.0 * p.ChangeAmount * p.ChangeAmount; this.state.changeAmount2 = p.ChangeAmount2 > 0 ? 1.0 - 0.9 * p.ChangeAmount2 * p.ChangeAmount2 : 1.0 + 10.0 * p.ChangeAmount2 * p.ChangeAmount2; this.state.changeTime = 0; this.state.changeTime2 = 0; this.state.changeLimit = p.ChangeSpeed == 1.0 ? 0 : (int)(((1.0 - p.ChangeSpeed) * (1.0 - p.ChangeSpeed) * 20000 + 32) * (1.0 - p.ChangeRepeat + 0.1) / 1.1); this.state.changeLimit2 = p.ChangeSpeed2 == 1.0 ? 0 : (int)(((1.0 - p.ChangeSpeed2) * (1.0 - p.ChangeSpeed2) * 20000 + 32) * (1.0 - p.ChangeRepeat + 0.1) / 1.1); this.initState = this.state; this.pinkGenerator = new PinkGenerator(this.rand); this.masterVolume = p.MasterVolume * p.MasterVolume; this.wave = p.Wave; double attackTime = Math.Max(0, p.AttackTime); double sustainTime = Math.Max(0.01, p.SustainTime); double decayTime = Math.Max(0, p.DecayTime); double totalTime = attackTime + sustainTime + decayTime; if (totalTime < MinLength) { double fac = MinLength / totalTime; attackTime *= fac; sustainTime *= fac; decayTime *= fac; } this.sustainPunch = p.SustainPunch; this.phase = 0; this.minFrequency = p.MinFrequency; this.muted = false; this.overtones = (int)(p.Overtones * 10); this.overtoneFalloff = p.OvertoneFalloff; this.bitcrushFreq = 1 - Math.Pow(p.BitCrush, 1.0 / 3.0); this.bitcrushFreqSweep = -0.000015 * p.BitCrushSweep; this.bitcrushPhase = 0; this.bitcrushLast = 0; this.compressionFactor = 1 / (1 + 4 * p.CompressionAmount); this.filters = p.LPFilterCutoff != 1.0 || p.HPFilterCutoff != 0.0; this.lpFilterOn = p.LPFilterCutoff != 1.0; this.lpFilterPos = 0.0; this.lpFilterDeltaPos = 0.0; this.lpFilterCutoff = 0.1 * p.LPFilterCutoff * p.LPFilterCutoff * p.LPFilterCutoff; this.lpFilterDeltaCutoff = 1.0 + 0.0001 * p.LPFilterCutoffSweep; this.lpFilterDamping = 1.0 - 5.0 / (1.0 + 20 * p.LPFilterResonance * p.LPFilterResonance) * (0.01 + this.lpFilterCutoff); this.hpFilterPos = 0.0; this.hpFilterCutoff = 0.1 * p.HPFilterCutoff * p.HPFilterCutoff; this.hpFilterDeltaCutoff = 1.0 + 0.0003 * p.HPFilterCutoffSweep; this.vibratoPhase = 0; this.vibratoSpeed = 0.01 * p.VibratoSpeed * p.VibratoSpeed; this.vibratoAmplitude = 0.5 * p.VibratoDepth; this.envelopeVolume = 0; this.envelopeStage = 0; this.envelopeTime = 0; this.envelopeLength0 = (int)(100000 * attackTime * attackTime); this.envelopeLength1 = (int)(100000 * sustainTime * sustainTime); this.envelopeLength2 = (int)(100000 * decayTime * decayTime + 10); this.envelopeLength = this.envelopeLength0; this.envelopeFullLength = this.envelopeLength0 + this.envelopeLength1 + this.envelopeLength2; this.envelopeInvLength0 = 1.0 / this.envelopeLength0; this.envelopeInvLength1 = 1.0 / this.envelopeLength1; this.envelopeInvLength2 = 1.0 / this.envelopeLength2; this.flanger = p.FlangerOffset != 0.0 || p.FlangerSweep != 0.0; this.flangerOffset = 1020.0 * p.FlangerOffset * p.FlangerOffset * (p.FlangerOffset > 0 ? 1 : -1); this.flangerDeltaOffset = 0.2 * p.FlangerSweep * p.FlangerSweep * p.FlangerSweep; this.flangerPos = 0; this.flangerBuffer = new float[1024]; this.noiseBuffer = new float[32]; this.pinkNoiseBuffer = new float[32]; this.loResNoiseBuffer = new float[32]; for (int i = 0; i < this.noiseBuffer.Length; i++) { this.noiseBuffer[i] = 2.0f * (float)this.rand.NextDouble() - 1.0f; } for (int i = 0; i < this.pinkNoiseBuffer.Length; i++) { this.pinkNoiseBuffer[i] = this.pinkGenerator.Next(); } float val = 0.0f; for (int i = 0; i < this.loResNoiseBuffer.Length; i++) { if ((i % LoResNoisePeriod) == 0) { val = 2.0f * (float)this.rand.NextDouble() - 1.0f; } this.loResNoiseBuffer[i] = val; } this.repeatTime = 0; this.repeatLimit = p.RepeatSpeed == 0.0 ? 0 : (int)((1.0 - p.RepeatSpeed) * (1.0 - p.RepeatSpeed) * 20000) + 32; }