Problem
The oscillator phase wrap (source/dsp/Oscillator.cpp:43-45) uses:
if (phase >= 1.0) phase -= 1.0;
This only subtracts 1.0 once. If phaseIncrement >= 1.0 (frequency >= sampleRate), phase could exceed 2.0 and the single subtraction wouldn't bring it back into [0, 1). Additionally, there's no handling for negative phase (which could occur if freq is negative due to a bug).
With current parameter ranges, max increment would be ~0.907 (5000Hz * 8x / 44100), which is safe. But at lower sample rates (some hosts use 22050Hz) or if parameter ranges are extended, this would overflow, causing waveform distortion.
Corroborated by: 3/8 audit agents (dsp-algorithm, stability-edge, perf-optimizer)
Suggested Fix
Use std::fmod or a while loop:
phase += phaseIncrement;
phase = std::fmod(phase, 1.0);
Or: while (phase >= 1.0) phase -= 1.0;
Also consider clamping oscillator frequency to Nyquist in setFrequency().
Impact
- Stability: Waveform distortion/garbage output at edge-case frequencies
- Severity: Low-Medium -- unlikely with current parameters but latent bug
Problem
The oscillator phase wrap (
source/dsp/Oscillator.cpp:43-45) uses:This only subtracts 1.0 once. If
phaseIncrement >= 1.0(frequency >= sampleRate), phase could exceed 2.0 and the single subtraction wouldn't bring it back into [0, 1). Additionally, there's no handling for negative phase (which could occur if freq is negative due to a bug).With current parameter ranges, max increment would be ~0.907 (5000Hz * 8x / 44100), which is safe. But at lower sample rates (some hosts use 22050Hz) or if parameter ranges are extended, this would overflow, causing waveform distortion.
Corroborated by: 3/8 audit agents (dsp-algorithm, stability-edge, perf-optimizer)
Suggested Fix
Use
std::fmodor a while loop:phase += phaseIncrement; phase = std::fmod(phase, 1.0);Or:
while (phase >= 1.0) phase -= 1.0;Also consider clamping oscillator frequency to Nyquist in
setFrequency().Impact