fa3d785997a1d387442b0c5a728753acb9d776b7
Pull the audio mixer's inline math out of the async mixer-task closure into three pure, testable functions — mix_frames (sample-by-sample sum with i16 saturation), apply_volume (per-peer scale + clamp, unity-skip fast path), and frame_level (normalized RMS for the UI meter). Behavior-preserving: the loop now calls them and the full suite still passes. Adds 12 #[cfg(test)] unit tests, notably the saturation guards: a loud mix or a volume boost clamps to i16::MAX/MIN rather than wrapping (a plain cast would wrap a 2x-full-scale sum to a large negative value). Also covers sum, ragged peer-frame lengths, no-peers silence, volume unity/zero/half, and RMS bounds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>