mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-09-10 23:54:10 +00:00
NaN/Inf from any JS caller (audio:setGain does no validation) previously reached the gain atomics raw; a NaN master gain multiplies the whole device output to NaN and poisons the peak meters (TLC deep-read §2). Clamp at the four setters — the single choke point covering the legacy facade, the source-indexed API, and the audio-effects executor. Bounds 0..32 match the executor's clampGain (Phase 0.b compat pin); stream/ renderer-bus keep their historical 0..8 via the same JUCE-free helper, now testable in the new tests/engine_units target (Phase 0.c harness). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
37 lines
1.4 KiB
C++
37 lines
1.4 KiB
C++
#pragma once
|
|
|
|
// Gain-argument containment (audio-engine TLC, deep-read §2).
|
|
//
|
|
// N-API's Number coercion lets NaN/Infinity from JS reach the engine's gain
|
|
// atomics raw — a NaN master gain multiplies the whole device output to NaN
|
|
// (buffer.applyGain) and poisons the peak meters, and nothing downstream
|
|
// scrubs it (the per-source NaN scrub runs before the master gain). Clamping
|
|
// at the engine setters is the single choke point that fixes every caller:
|
|
// audio:setGain, the source-indexed API, and the audio-effects executor.
|
|
//
|
|
// Bounds: 0..32 for input/chain/output/backing — matching the executor's
|
|
// JS-side clampGain so a legit high rig gain is never under-shot (compat pin,
|
|
// docs/audio-engine-tlc.md Phase 0.b). The stream/renderer-bus gains keep
|
|
// their tighter historical 0..8 (previously sanitizeStreamGain).
|
|
//
|
|
// JUCE-free on purpose, like AudioSanitize.h, so tests/engine_units can test
|
|
// it without a device.
|
|
|
|
#include <cmath>
|
|
|
|
namespace slopsmith {
|
|
|
|
// Non-finite → 0 (silence beats a poisoned mix); otherwise clamp to [0, max].
|
|
inline float sanitizeGain(float g, float maxGain) noexcept
|
|
{
|
|
if (!std::isfinite(g)) return 0.0f;
|
|
if (g < 0.0f) return 0.0f;
|
|
if (g > maxGain) return maxGain;
|
|
return g;
|
|
}
|
|
|
|
inline float sanitizeMasterGain(float g) noexcept { return sanitizeGain(g, 32.0f); }
|
|
inline float sanitizeStreamGain(float g) noexcept { return sanitizeGain(g, 8.0f); }
|
|
|
|
} // namespace slopsmith
|