BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit 405193687ea68bc76ab6d8d32aa93ec713dc6e75
parent 5e0d39c205a97068fb668330091d2a71f7be547a
Author: Matt Demanett <matt@demanett.net>
Date:   Mon, 10 Jan 2022 22:59:30 -0500

Fix pops/glitches in oscillator pulse outputs when using audio rate PWM. #193

Diffstat:
Msrc/dsp/oscillator.cpp | 23++++++++++++++++++-----
Msrc/dsp/oscillator.hpp | 10++++++----
2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -171,10 +171,15 @@ void SquareOscillator::setPulseWidth(float pw) { else if (pw <= minPulseWidth) { pw = minPulseWidth; } - _pulseWidth = cyclePhase * pw; + _nextPulseWidth = cyclePhase * pw; } float SquareOscillator::nextForPhase(phase_t phase) { + phase_t cycle = phase / cyclePhase; + if (_lastCycle != cycle) { + _lastCycle = cycle; + _pulseWidth = _nextPulseWidth; + } phase %= cyclePhase; if (positive) { @@ -205,19 +210,27 @@ void BandLimitedSquareOscillator::setPulseWidth(float pw, bool dcCorrection) { else if (pw <= minPulseWidth) { pw = minPulseWidth; } - _pulseWidth = cyclePhase * pw; + _nextPulseWidth = cyclePhase * pw; if (pw > 0.5) { - _offset = 2.0f * pw - 1.0f; + _nextOffset = 2.0f * pw - 1.0f; } else { - _offset = -(1.0f - 2.0f * pw); + _nextOffset = -(1.0f - 2.0f * pw); } - _dcOffset = _dcCorrection ? 1.0f - 2.0f * pw : 0.0f; + _nextDcOffset = _dcCorrection ? 1.0f - 2.0f * pw : 0.0f; } float BandLimitedSquareOscillator::nextForPhase(phase_t phase) { + phase_t cycle = phase / cyclePhase; + if (_lastCycle != cycle) { + _lastCycle = cycle; + _pulseWidth = _nextPulseWidth; + _offset = _nextOffset; + _dcOffset = _nextDcOffset; + } + float sample = -BandLimitedSawOscillator::nextForPhase(phase); sample += BandLimitedSawOscillator::nextForPhase(phase - _pulseWidth); return sample + _offset + _dcOffset; diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -219,7 +219,8 @@ struct SquareOscillator : Phasor { static constexpr float maxPulseWidth = 1.0f - minPulseWidth; static constexpr float defaultPulseWidth = 0.5f; float _pulseWidthInput; - phase_t _pulseWidth = cyclePhase * defaultPulseWidth; + phase_t _lastCycle = -1; + phase_t _pulseWidth = cyclePhase * defaultPulseWidth, _nextPulseWidth = cyclePhase * defaultPulseWidth; bool positive = true; SquareOscillator( @@ -239,9 +240,10 @@ struct BandLimitedSquareOscillator : BandLimitedSawOscillator { const float maxPulseWidth = 1.0f - minPulseWidth; float _pulseWidthInput= -1.0f; bool _dcCorrection = false; - phase_delta_t _pulseWidth; - float _offset; - float _dcOffset; + phase_t _lastCycle = -1; + phase_delta_t _pulseWidth = 0, _nextPulseWidth = 0; + float _offset = 0.0f, _nextOffset = 0.0f; + float _dcOffset = 0.0f, _nextDcOffset = 0.0f; BandLimitedSquareOscillator( float sampleRate = 1000.0f,