public override void Process(float[] buffer) { StepEnvelope(); if (State == EnvelopeState.Dead) { return; } ChannelVolume vol = GetVolume(); float interStep = _frequency * _mixer.SampleRateReciprocal; int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { float samp = _pat[_pos & (_pat.Length - 1)] ? 0.5f : -0.5f; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; _interPos += interStep; int posDelta = (int)_interPos; _interPos -= posDelta; _pos = (_pos + posDelta) & (_pat.Length - 1); } while (--samplesPerBuffer > 0); }
public override void Process(float[] buffer) { StepEnvelope(); if (State == EnvelopeState.Dead) { return; } ChannelVolume vol = GetVolume(); float interStep = frequency * mixer.SampleRateReciprocal; int bufPos = 0; int samplesPerBuffer = mixer.SamplesPerBuffer; do { float samp = sample[pos]; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; interPos += interStep; int posDelta = (int)interPos; interPos -= posDelta; pos = (pos + posDelta) & 0x1F; } while (--samplesPerBuffer > 0); }
public override void Process(float[] buffer) { StepEnvelope(); if (State == EnvelopeState.Dead) { return; } ChannelVolume vol = GetVolume(); float interStep = _bFixed && !_bGoldenSun ? _mixer.SampleRate * _mixer.SampleRateReciprocal : _frequency * _mixer.SampleRateReciprocal; if (_bGoldenSun) // Most Golden Sun processing is thanks to ipatix { interStep /= 0x40; switch (_gsPSG.Type) { case GoldenSunPSGType.Square: { _pos += _gsPSG.CycleSpeed << 24; int iThreshold = (_gsPSG.MinimumCycle << 24) + _pos; iThreshold = (iThreshold < 0 ? ~iThreshold : iThreshold) >> 8; iThreshold = (iThreshold * _gsPSG.CycleAmplitude) + (_gsPSG.InitialCycle << 24); float threshold = iThreshold / (float)0x100000000; int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { float samp = _interPos < threshold ? 0.5f : -0.5f; samp += 0.5f - threshold; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; _interPos += interStep; if (_interPos >= 1) { _interPos--; } } while (--samplesPerBuffer > 0); break; } case GoldenSunPSGType.Saw: { const int fix = 0x70; int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { _interPos += interStep; if (_interPos >= 1) { _interPos--; } int var1 = (int)(_interPos * 0x100) - fix; int var2 = (int)(_interPos * 0x10000) << 17; int var3 = var1 - (var2 >> 27); _pos = var3 + (_pos >> 1); float samp = _pos / (float)0x100; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; } while (--samplesPerBuffer > 0); break; } case GoldenSunPSGType.Triangle: { int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { _interPos += interStep; if (_interPos >= 1) { _interPos--; } float samp = _interPos < 0.5f ? (_interPos * 4) - 1 : 3 - (_interPos * 4); buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; } while (--samplesPerBuffer > 0); break; } } } else if (_bCompressed) { int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { float samp = _decompressedSample[_pos] / (float)0x80; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; _interPos += interStep; int posDelta = (int)_interPos; _interPos -= posDelta; _pos += posDelta; if (_pos >= _decompressedSample.Length) { Stop(); break; } } while (--samplesPerBuffer > 0); } else { int bufPos = 0; int samplesPerBuffer = _mixer.SamplesPerBuffer; do { float samp = (sbyte)_mixer.Config.ROM[_pos + _sampleOffset] / (float)0x80; buffer[bufPos++] += samp * vol.LeftVol; buffer[bufPos++] += samp * vol.RightVol; _interPos += interStep; int posDelta = (int)_interPos; _interPos -= posDelta; _pos += posDelta; if (_pos >= _sampleHeader.Length) { if (_sampleHeader.DoesLoop == 0x40000000) { _pos = _sampleHeader.LoopOffset; } else { Stop(); break; } } } while (--samplesPerBuffer > 0); } }