Skip to content

Division by zero possible in Oscillator and YinPitchDetector #16

@user1303836

Description

@user1303836

Problem

Two division-by-zero paths exist that can produce Inf/NaN and propagate through the entire signal chain:

1. Oscillator: sr = 0

Oscillator::updateIncrement() (source/dsp/Oscillator.cpp:52) computes phaseIncrement = freq / sr. If a host passes sampleRate = 0 to prepareToPlay, sr becomes 0.0 and division produces Inf, which propagates to the audio output.

2. YinPitchDetector: betterTau = 0

YinPitchDetector::analyse() (source/dsp/YinPitchDetector.cpp:109) computes float freq = static_cast<float>(analysisSR) / betterTau. After parabolic interpolation (lines 97-107), betterTau could theoretically reach 0 or near-zero, producing Inf.

3. PitchSmoother: sr = 0

PitchSmoother::recomputeAlpha() (source/dsp/PitchSmoother.h:48) computes alpha = 1.0f - std::exp(-1.0f / (sr * tau)). If sr = 0, division by zero inside exp argument yields NaN for alpha, and every subsequent process() call produces NaN.

Corroborated by: 2/8 audit agents (stability-edge, pitch-detection)

Suggested Fixes

  1. Oscillator: Guard prepare(): sr = std::max(1.0, sampleRate);
  2. YinPitchDetector: Guard after parabolic interpolation: if (betterTau < 1.0f) { lastResult = {0.0f, 0.0f}; return; }
  3. PitchSmoother: Guard prepare(): sr = std::max(1.0f, static_cast<float>(sampleRate));

Impact

  • Stability: Can produce Inf/NaN in audio output, causing silence, loud noise, or downstream plugin crashes
  • Severity: High -- defensive guards are trivial to add

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions