public override void Process(float[] buffer) { StepEnvelope(); prevPan = curPan; if (State == ADSRState.Dead) { return; } ChannelVolume vol = GetVolume(); float leftVolStep = (vol.ToLeftVol - vol.FromLeftVol) * SoundMixer.Instance.SamplesReciprocal; float rightVolStep = (vol.ToRightVol - vol.FromRightVol) * SoundMixer.Instance.SamplesReciprocal; float leftVol = vol.FromLeftVol; float rightVol = vol.FromRightVol; float interStep = frequency * SoundMixer.Instance.SampleRateReciprocal; int bufPos = 0; int samplesPerBuffer = SoundMixer.Instance.SamplesPerBuffer; do { float samp = pat[pos & (pat.Length - 1)] ? 0.5f : -0.5f; buffer[bufPos++] += samp * leftVol; buffer[bufPos++] += samp * rightVol; leftVol += leftVolStep; rightVol += rightVolStep; interPos += interStep; int posDelta = (int)interPos; interPos -= posDelta; pos = (pos + posDelta) & (pat.Length - 1); } while (--samplesPerBuffer > 0); }
public override void Process(float[] buffer) { StepEnvelope(); prevLeftVol = curLeftVol; prevRightVol = curRightVol; if (State == ADSRState.Dead) { return; } ChannelVolume vol = GetVolume(); vol.FromLeftVol *= SoundMixer.Instance.DSMasterVolume; vol.FromRightVol *= SoundMixer.Instance.DSMasterVolume; vol.ToLeftVol *= SoundMixer.Instance.DSMasterVolume; vol.ToRightVol *= SoundMixer.Instance.DSMasterVolume; ProcArgs pargs; pargs.LeftVolStep = (vol.ToLeftVol - vol.FromLeftVol) * SoundMixer.Instance.SamplesReciprocal; pargs.RightVolStep = (vol.ToRightVol - vol.FromRightVol) * SoundMixer.Instance.SamplesReciprocal; pargs.LeftVol = vol.FromLeftVol; pargs.RightVol = vol.FromRightVol; if (bFixed && !bGoldenSun) { pargs.InterStep = (ROM.Instance.Game.Engine.Type == EngineType.M4A ? ROM.Instance.Game.Engine.Frequency : sample.Frequency) * SoundMixer.Instance.SampleRateReciprocal; } else { pargs.InterStep = frequency * SoundMixer.Instance.SampleRateReciprocal; } if (bGoldenSun) // Most Golden Sun processing is thanks to ipatix { pargs.InterStep /= 0x40; switch (gsPSG.Type) { case GSPSGType.Square: ProcessSquare(buffer, SoundMixer.Instance.SamplesPerBuffer, pargs); break; case GSPSGType.Saw: ProcessSaw(buffer, SoundMixer.Instance.SamplesPerBuffer, pargs); break; case GSPSGType.Triangle: ProcessTri(buffer, SoundMixer.Instance.SamplesPerBuffer, pargs); break; } } else { ProcessNormal(buffer, SoundMixer.Instance.SamplesPerBuffer, pargs); } }