Skip to content

Land ITU Stage 2 on main (post-filter, comfort noise, AEC chain)#8

Merged
tap merged 2 commits into
mainfrom
claude/itu-stage2-to-main
Jul 16, 2026
Merged

Land ITU Stage 2 on main (post-filter, comfort noise, AEC chain)#8
tap merged 2 commits into
mainfrom
claude/itu-stage2-to-main

Conversation

@tap

@tap tap commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Corrective PR: #7 (Stage 2) was merged while its base still pointed at the Stage 1 branch — GitHub does not retarget stacked PRs when their base merges — so its two commits landed on claude/itu-stage1-signals and never reached main. This PR is those exact two commits cherry-picked onto current main; the diff is identical to what was reviewed and merged in #7.

See #7 for the full description: the residual-echo suppressor + comfort noise (mutap/postfilter.h), mutap::aec_chain on the raw FD-Kalman core, 12 measured-first tests, the A-weighting Nyquist fix, and the measured-vs-target table (all matrix margin targets pass).

🤖 Generated with Claude Code

https://claude.ai/code/session_01TLE2rvptWxV8catE8vTvgx


Generated by Claude Code

claude added 2 commits July 16, 2026 14:41
… chain

mutap/postfilter.h delivers the Stage 2 items of docs/itu-compliance.md:

- residual_suppressor: per-bin Wiener gain on E whose DEPTH comes from a
  leakage estimate (residual power per unit echo-estimate power) gated by
  mic-vs-echo-estimate coherence. The discriminator correlates the MIC
  (D = E + Yhat), never E, against Yhat: a converged adaptive filter
  keeps E orthogonal to its reference, so coh(E, Yhat) saturates at 0.34
  while adapting where coh(D, Yhat) measures 0.99. Gains are constrained
  to a causal 2B-tap filter (rectangular cut — a Hann taper measured
  WORSE double-talk transparency), attack-smoothed against estimator
  chatter, and suppressed bins are refilled with comfort noise shaped to
  a two-window minimum-statistics noise floor (one-pole trackers
  measured either -8 dB undershoot or tens-of-seconds acquisition).

- aec_chain: canceller + suppressor as the unit the compliance matrix
  measures. Defaults to the RAW partitioned FD-Kalman core, not pem_afc:
  open-loop AEC has an exogenous far end — no closed-loop bias to remove
  — and PEM's predictor refit floors misalignment near -20 dB where the
  raw core measures -75.6 dBm0(A) bare with double-talk immunity from
  its own noise-PSD tracking. pem_afc (grown an echo_estimate_block()
  accessor) still composes via the 3-argument branch.

Measured on the golden model (test_postfilter.cpp, all margin targets):
ST residual -80.5/-89.7 dBm0(A) cabin/studio (target < -64; NLMS core
-66.2, 16 kHz -70.7), DT send atten 1.14/1.03 dB (<= 1.5), DT echo loss
worst band 37.9/34.2 dB (>= 33), ERL 43.2 dB by 600 ms / 46.9 by 1200
(>= 40/46), comfort noise -1.50 dB level / <= 1.69 dB per band /
pumping 2.9 dB / build-up 11.6 ms. Full tables and the four design
decisions the measurements forced are in the matrix's "Stage 2
delivered" section.

Instrument fix: A-weighting poles above Nyquist (12.2 kHz pair at
fs = 16 kHz) are prewarp-clamped to 0.45 fs — tan() past pi/2 flipped
sign and the 16 kHz chain measurements went NaN.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TLE2rvptWxV8catE8vTvgx
…honest number

ASan (and MSVC, via the garbage it read) caught NearEndBuildUpTime
reading 250 ms past the end of its level trace: the near-end onset sat
at 5/6 of the run but the settled-level window needed 2 s of tail.
Onset moved to 2/3 (3.5 s of tail) with an explicit size guard.

Measured honestly, build-up at gain_release 0.9 is 26.0 ms — over the
switching rows' 25 ms margin target (the old 11.6 ms figure was
computed against the corrupted median). Release 0.85 measures 20.9 ms
and is the new default; 0.8 was measured too fast for the rest of the
board (studio worst DT echo-loss band fell to 32.8 dB, under the 33 dB
target). Full re-measurement at 0.85, all margin targets still met:
ST -79.9/-88.9 dBm0(A), DT atten 1.05/0.93 dB, DT echo loss worst band
38.0/34.1 dB, comfort noise -1.20 dB, pumping 3.3 dB. Test comments,
matrix table and README refreshed; ItuChain suite re-run green under
ASan+UBSan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TLE2rvptWxV8catE8vTvgx
@tap tap merged commit d60af7f into main Jul 16, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants