Audio Numerics Review
Floating-point is not real math. IEEE 754 edge cases — denormals, NaN propagation,
catastrophic cancellation, precision loss — silently produce wrong audio output without
crashing. You won't find them with a debugger; you find them by knowing where to look.
Step 1 — Find numeric-critical paths
Locate every function doing floating-point or integer DSP: filter state loops, feedback
delay lines, envelope followers, RMS/energy accumulators, pitch detectors, fixed-point
paths (CMSIS-DSP, SIMD int16/int32), any division whose denominator may be zero.
Step 2 — Scan for violations
| Violation |
Where to look |
Symptom |
| Denormal floats |
IIR state vars, reverb tanks, delay feedback |
Sudden 100× CPU spike when signal decays |
| NaN / Inf |
Divisions, sqrt, acos/asin, peak normalizers |
Silence or noise that can't be traced |
| Catastrophic cancellation |
DC-blocking filters, near-Nyquist biquads, first-order diff |
Noise floor jumps, loss of precision |
| Fixed-point overflow |
Q15/Q31 multiply, CMSIS paths, SIMD int16 |
Audible distortion / wrapping |
| Precision loss |
RMS/energy sums, mixing buses, long loops |
Accumulated DC offset, incorrect levels |
| FTZ/DAZ absent |
prepareToPlay/stream-open — no mode setup |
Denormals hit on some hosts but not others |
For code examples and platform-specific notes see references/numerics-pitfalls.md.
Step 3 — Write the review
## Audio Numerics Review: `[file / function]`
### Verdict
[Safe | Has critical violations | Warnings only] — one sentence summary
### Critical Violations
**[Category]: [description]**
`file:line` — `offending code`
Why: one sentence on the numeric risk
Fix: concrete suggestion
### Warnings
[same format]
### What's Done Well
[guarded divisions, double accumulators, FTZ setup, etc.]
### Recommended Fixes (priority order)
1. ...
Quick fix table
| Violation |
Safe alternative |
| Denormal in feedback |
ScopedNoDenormals; FTZ+DAZ in prepareToPlay; DC-offset clamp |
| Division by zero |
(denom > 1e-6f) ? num/denom : fallback |
sqrt/acos/asin unclamped |
std::sqrt(std::max(0.f, x)), std::clamp inputs |
| NaN propagating silently |
assert(!std::isnan(y)) in debug; validate at entry points |
| Cancellation in coefficients |
Compute coefficients in double; use numerically stable forms |
| Fixed-point overflow |
Promote to wider type before multiply; __SSAT, CMSIS saturating ops |
| Precision loss in long sum |
double accumulator or Kahan compensated summation |
| FTZ/DAZ absent |
Set explicitly in prepareToPlay; use ScopedNoDenormals per-block |
1---2name: audio-numerics-review3description: Reviews audio DSP code for numerical correctness. Use when the user asks to review, audit, or check DSP code for correctness issues — filters, feedback loops, fixed-point arithmetic, accumulation loops, or any numeric computation in audio code. Trigger on "check this filter for NaN", "why does my reverb blow up?", "is this numerically stable?", "why do I hear DC in my output?". Pairs with audio-dsp-review (realtime safety); this skill covers numeric correctness. Flag issues proactively.4---56# Audio Numerics Review78Floating-point is not real math. IEEE 754 edge cases — denormals, NaN propagation,9catastrophic cancellation, precision loss — silently produce wrong audio output without10crashing. You won't find them with a debugger; you find them by knowing where to look.1112## Step 1 — Find numeric-critical paths1314Locate every function doing floating-point or integer DSP: filter state loops, feedback15delay lines, envelope followers, RMS/energy accumulators, pitch detectors, fixed-point16paths (CMSIS-DSP, SIMD int16/int32), any division whose denominator may be zero.1718## Step 2 — Scan for violations1920| Violation | Where to look | Symptom |21|-----------|--------------|---------|22| **Denormal floats** | IIR state vars, reverb tanks, delay feedback | Sudden 100× CPU spike when signal decays |23| **NaN / Inf** | Divisions, `sqrt`, `acos`/`asin`, peak normalizers | Silence or noise that can't be traced |24| **Catastrophic cancellation** | DC-blocking filters, near-Nyquist biquads, first-order diff | Noise floor jumps, loss of precision |25| **Fixed-point overflow** | Q15/Q31 multiply, CMSIS paths, SIMD int16 | Audible distortion / wrapping |26| **Precision loss** | RMS/energy sums, mixing buses, long loops | Accumulated DC offset, incorrect levels |27| **FTZ/DAZ absent** | `prepareToPlay`/stream-open — no mode setup | Denormals hit on some hosts but not others |2829For code examples and platform-specific notes see `references/numerics-pitfalls.md`.3031## Step 3 — Write the review3233```34## Audio Numerics Review: `[file / function]`3536### Verdict37[Safe | Has critical violations | Warnings only] — one sentence summary3839### Critical Violations40**[Category]: [description]**41`file:line` — `offending code`42Why: one sentence on the numeric risk43Fix: concrete suggestion4445### Warnings46[same format]4748### What's Done Well49[guarded divisions, double accumulators, FTZ setup, etc.]5051### Recommended Fixes (priority order)521. ...53```5455## Quick fix table5657| Violation | Safe alternative |58|-----------|-----------------|59| Denormal in feedback | `ScopedNoDenormals`; FTZ+DAZ in `prepareToPlay`; DC-offset clamp |60| Division by zero | `(denom > 1e-6f) ? num/denom : fallback` |61| `sqrt`/`acos`/`asin` unclamped | `std::sqrt(std::max(0.f, x))`, `std::clamp` inputs |62| NaN propagating silently | `assert(!std::isnan(y))` in debug; validate at entry points |63| Cancellation in coefficients | Compute coefficients in `double`; use numerically stable forms |64| Fixed-point overflow | Promote to wider type before multiply; `__SSAT`, CMSIS saturating ops |65| Precision loss in long sum | `double` accumulator or Kahan compensated summation |66| FTZ/DAZ absent | Set explicitly in `prepareToPlay`; use `ScopedNoDenormals` per-block |