mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-09-11 02:34:10 +00:00
fix(audio): sanitize input/chain/output/backing gains at the engine setters
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>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bbb3b58db8
commit
3c8dd62ecb
@@ -0,0 +1,36 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user