Repository navigation
Sync post-M145 upstream fixes (full parity with C++ reference) - #36
Open
dignifiedquire wants to merge 22 commits into
Open
dignifiedquire wants to merge 22 commits into
dignifiedquire wants to merge 22 commits into
Conversation
Upstream a6d83994aa removes EchoCanceller::mobile_mode from AudioProcessing::Config and drops "(has no effect for the mobile mode)" from the enforce_high_pass_filtering comment. The port never had AECm or mobile_mode. This commit removes the one stale reference, the "Has no effect in mobile mode." sentence on EchoCanceller::enforce_high_pass_filtering in config.rs. No other file in crates/, fuzz/, README.md, or CHANGELOG.md mentions mobile mode or AECm. The generated C header (crates/sonora-ffi/include/wap_audio_processing.h) has no doc text for this field, and cbindgen does not parse the sonora crate (parse_deps = false), so the header does not change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream: https://webrtc.googlesource.com/src/+/7f5a8b656cf69708359a8179d226dda8d2206205 Remove the write-only DelayEstimate::blocks_since_last_change and blocks_since_last_update fields and RenderDelayController's delay_change_counter. RenderDelayController now stores each new estimate as-is and takes last_delay_estimate_quality from the computed buffer delay. AecState::FilterDelay stores every reported external delay, not only changed ones. Bit-exact: the dropped state was never read, and FilterDelay only checks whether an external delay exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream: https://webrtc.googlesource.com/src/+/d460e60e1955be72f3479a944fabde401fe848a2 RenderBuffer::headroom now returns 0 when the write and read indices meet on an underrun, instead of the full buffer size, and its debug_assert becomes headroom < size. The existing unit test asserted the buggy value; it now expects 0, and a new test checks every write == read position. The only consumer is EchoAudibility's stationarity lookahead, which runs only with use_stationarity_properties, so default-config output is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream d9b92fe1bc sets the input volume controller (IVC) production
target_range_max_dbfs to -12 dBFS (it was -30 at M145) and removes the
WebRTC-Agc2MaxSpeechLevelExperimental switch and its
target_range_experimental_max_dbfs field. The port never had that
field or switch.
The Rust InputVolumeControllerConfig::default() did not match M145's
production InputVolumeController::Config{} either. It held test-like
values. The APM pipeline builds the IVC from this default
(audio_processing_impl.rs initialize_gain_controller2), in the same way
that C++ APM builds it from Config{}. The default now equals upstream's
production Config{} after d9b92fe1bc:
field old M145 new (= d9b92fe1bc)
min_input_volume 20 20 20
clipped_level_min 70 70 70
clipped_level_step 15 15 15
clipped_ratio_threshold 0.1 0.1 0.1
clipped_wait_frames 300 300 300
enable_clipping_predictor false true true
target_range_max_dbfs -18 -30 -12
target_range_min_dbfs -30 -50 -50
update_input_volume_wait_frames 0 100 100
speech_probability_threshold 0.5 0.7 0.7
speech_ratio_threshold 0.8 0.6 0.6
User-visible change: audio samples are unchanged. When
GainController2::input_volume_controller is enabled,
recommended_stream_analog_level() now follows upstream. The target
range is [-50, -12] dBFS. Speech-level updates happen at most once
every 100 frames (1 s), and only when at least 60% of those frames have
a speech probability of 0.7 or higher. Before, they could happen on
every 10 ms frame. Clipping prediction is on, so the volume can also be
lowered on predicted clipping, not only on detected clipping.
The repository has no maintained changelog (CHANGELOG.md was not
updated for the 0.1.0 or 0.2.0 releases), so this commit message
records the change.
Tests:
- Add default_config_matches_upstream_production_config, which pins
every field to the upstream header at d9b92fe1bc.
- Port upstream CheckIsAlive, which runs the production config over
1/2/3/6 channels at 8/16/32/48 kHz. Both tests fail against the old
default.
- clipping_parameters_verified and the two clipping-predictor
enable/disable tests now start from get_test_config() instead of the
production default. Upstream uses its CreateInputVolumeController()
test factory for these tests. Their assertions are unchanged.
- The gain_controller2 tests keep
InputVolumeControllerConfig::default(), because upstream uses
InputVolumeControllerConfig{} at the same sites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…es for the suppressor gain computation Upstream: https://webrtc.googlesource.com/src/+/e10cd19640a9bf6f53cd071d1dd58051e1c0b0fc Port the parts that apply without the NeuralResidualEchoEstimator: - MovingAverage divides by the number of inputs seen so far (1/(n+1), saturating at mem_len) instead of always by mem_len, and gains update_memory_length. - The nearend detectors gain set_config; DominantNearendDetector now stores its config struct. - SuppressionGain::get_gain takes the active Suppressor config and a config_changed flag, which triggers update_state_depending_on_config (smoother window, detector config, GainParameters::set_config). SuppressionGain no longer keeps the whole EchoCanceller3Config; the write-only state_change_duration_blocks and initial_state_change_counter, and use_unbounded_echo_spectrum, are gone. - EchoRemover passes config.suppressor and config_changed = false. Skipped (ML-REE only, not ported): NeuralResidualEchoEstimator:: AdjustConfig, EchoRemover's ML-REE suppressor config selection and the coarse-filter-output gate on IsMlReeActive, ResidualEchoEstimator:: IsMlReeActive and its branch restructure (equivalent without ML-REE), the neural estimator impl and audioproc_f changes. Tests: MovingAverage average expectations follow upstream (/1, /2, /3), plus upstream's UpdateMemoryLength and UpdateStateDependingOnConfig tests; new tests check that a window change drops old history and that set_config and the smoother resize take effect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…llResetKillSwitch Upstream: https://webrtc.googlesource.com/src/+/fe9c0a1de4135aba3d28a9aaad5e920502f7d562 Drop AecState::full_reset_at_echo_path_change, which the port pinned to true (the field trial's default). AecState now always does the full reset on a delay change. No behavior change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…erResetHangoverKillSwitch Upstream: https://webrtc.googlesource.com/src/+/4252c6051dd87f7a02f8f27263683fbe00d6752e Drop Subtractor::use_coarse_filter_reset_hangover, which the port pinned to true (the field trial's default). The coarse filter reset hangover now always disallows the diverged-leakage adaptation. No behavior change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…InitialStateResetKillSwitch Upstream: https://webrtc.googlesource.com/src/+/8dd6b47c8302d32657c988d09ecc7fde38ae9479 Drop AecState::deactivate_initial_state_reset_at_echo_path_change, which the port pinned to false (the field trial's default). The initial state is now always reset on a delay change. No behavior change. subtractor_analyzer_reset_at_echo_path_change stays, because upstream main still gates it by a field trial. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream: https://webrtc.googlesource.com/src/+/86ef7fa42dc3429bb4813aa98699c70ad570cac9 EchoRemoverMetrics::reset_metrics now starts the ERLE floor at 1000 and its ceiling at 0, like the ERL metric, so each tracks the real extreme. Before, the floor started at 0 and the ceiling at 1000, so neither could move. A new test checks that ERL and ERLE floors and ceilings follow the updated values. Audio output is unchanged; the port does not report these metrics. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Move the cpp submodule from b5059ca to feb3c50 on the fork branch sync/post-m145-fixes. The branch cherry-picks these upstream WebRTC commits onto the M145 base (branch-heads/7632), oldest first: - a6d83994aa Remove aec_mobile (AECm) config from audio_processing.h - 297352a2fd Update comfort noise to be applied identically on all channels - 573e746914 Correct the switching between the coarse and refined filters - 7c388cbabb Changing default values of multi channel processing to be true - 7f5a8b656c Propagate delay estimator fields to AecState - d460e60e19 AEC3: Fix render buffer headroom calculation on underruns - d9b92fe1bc Make max target input level for input controller -12dB - e10cd19640 Enable dynamic on-the-fly AEC3 configuration updates for the suppressor gain computation - fe9c0a1de4 Remove field-trial WebRTC-Aec3AecStateFullResetKillSwitch - 32feae39d0 Remove field-trial WebRTC-Aec3TransparentModeKillSwitch - 4252c6051d Remove field-trial WebRTC-Aec3CoarseFilterResetHangoverKillSwitch - 8dd6b47c83 Remove field-trial WebRTC-Aec3DeactivateInitialStateResetKillSwitch - 86ef7fa42d aec: fix wrong sentinel usage in echo metrics - 05d6bc269c Remove field-trial WebRTC-Aec3HighPassFilterEchoReference - 401392b7e6 Remove field-trial WebRTC-Aec3EchoSaturationDetectionKillSwitch Prerequisites also cherry-picked: 8cd8620980 (Remove the possibility to run AECm), needed by a6d83994aa, and 1d1ee4503c (Refactor AudioProcessingTest), needed by the tests of 7c388cbabb. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…against C++ The existing full-pipeline comparison never processes a render signal and feeds the same signal to both channels, so it never reaches the multi-channel AEC3 paths. The new stereo_echo_pipeline_matches_cpp test runs EC + NS + AGC2 at 48 kHz stereo for 500 frames with independent noise on the two render channels and a different echo mix plus near-end noise on each capture channel. This exercises the multi-channel upstream changes 7c388cbabb (multi-channel defaults), 297352a2fd (shared comfort noise) and 573e746914 (one coarse/refined decision for all channels). It uses the existing PIPELINE_TOL and also asserts that both outputs differ between channels, which fails if either side downmixes capture to mono. Against the pre-sync C++ fork (b5059ca, multi-channel defaults false) the test fails on that check. sonora-sys gains process_reverse_stream_f32_2ch, mirroring process_stream_f32_2ch, because the shim only had a mono reverse path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
The port and the C++ reference are now based on M145 (branch-heads/7632) plus 15 later upstream WebRTC fixes, the newest from M156. The C++ fork's NEWS file lists them. The History entry about the M145 upgrade is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream 297352a2fd generates the random sin-table indices once per block and applies them to every capture channel. The existing correct_level test checks only per-channel power, which is the same when each channel draws its own phases, so no test failed if the port regressed to per-channel indices. identical_noise_on_all_channels feeds the same noise estimate to three channels over several blocks and asserts that the lower- and upper-band noise is bit-identical across channels. Verified: it fails when the indices are regenerated per channel (the pre-297352a2fd behaviour). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…onfig_changed No test called SuppressionGain::get_gain, so the config_changed branch added for upstream e10cd19640 was unguarded: dropping it, or updating the state on every call, still passed. - basic_gain_computation ports upstream's BasicGainComputation with the e10cd19640 signature (suppressor config and config_changed=false): strong noise or nearend gives unity gain, and strong echo on one of two capture channels drives the shared gain to zero. - get_gain_applies_config_only_when_changed passes a different suppressor config with config_changed=false (state unchanged) and then true (new tunings and a one-block nearend window take effect). Verified: removing the config_changed block, or making it unconditional, fails the second test; limiting lower_band_gain to channel 0 fails the first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Upstream input_volume_controller_unittest.cc (at d9b92fe1bc) constructs
15 tests from InputVolumeController::Config{} with designated overrides,
for example {.min_input_volume = GetParam()}, so they run on the
production defaults. The Rust ports used ..get_test_config() instead
(target range [-30, -18] dBFS, clipping predictor off, clipped level
min 165, no update wait), so none of them exercised the production
controller that the pipeline now uses.
These tests now use ..InputVolumeControllerConfig::default(); tests
that upstream builds from GetInputVolumeControllerTestConfig() or
CreateInputVolumeController() keep get_test_config(). All 39 IVC tests
pass. Verified: changing the default clipped_wait_frames now also fails
waiting_period_between_clipping_checks, which previously ignored the
default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
The shim compiles webrtc::AudioProcessing::Config and other C++ types,
so their layout and default member initializers (for example the
multi_channel_* defaults changed by upstream 7c388cbabb, or the
EchoCanceller layout changed by a6d83994aa) are fixed when the shim is
built. build.rs only reran when shim.h, shim.cc or bridge.rs changed,
so after a submodule bump a warm target dir kept a shim built against
the old headers and compared Rust against a stale C++ config.
build.rs now also reruns when anything under {cpp_root}/webrtc, the
pkg-config include dirs or the pkg-config library dirs changes, and
when WEBRTC_CPP_ROOT changes. The shim includes headers from both the
source tree (webrtc/api/audio/audio_processing.h) and the install
prefix (api/array_view.h and others), so both are watched.
Verified with cargo build -v: touching cpp/webrtc/api/audio/
audio_processing.h left sonora-sys Fresh before this change; after it,
touching that header, the installed header or the installed dylib each
marks sonora-sys Dirty and rebuilds it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
7bf030d rewrote the "0.1.0 (unreleased)" entry to claim M145 plus 15 later upstream fixes, but v0.1.0 and the 0.2.0 crates have shipped without most of them. The 0.1.0 line is restored and a new Unreleased section lists what this branch changes for users: the IVC production defaults and the AEC3 ports. It notes that the multi-channel defaults, shared comfort noise and joint filter choice already shipped in 0.2.0 (9e4b402 is an ancestor of sonora-v0.2.0). README.md said the C++ suite runs with the Rust backend "linked via the sonora-sys FFI bridge". The -Drust-backend meson option links libsonora_ffi.a (cpp/meson.build:201-246); sonora-sys is the opposite bridge, used by sonora-bench to call C++ from Rust. The "up to M156" wording is kept: chromiumdash maps M155 to branch 8059 and M156 to 8078, and upstream branch-heads/8078 contains 86ef7fa42d, 05d6bc269c and 401392b7e6 while branch-heads/8059 does not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
…ender stereo_echo_pipeline_matches_cpp used PIPELINE_TOL (0.2). Its channel check catches capture downmixed to mono, but with Rust's multi_channel_render set to false (the default before upstream 7c388cbabb) the Rust/C++ max diff only grows from 0.0050/0.0056 (L/R) to 0.055/0.046, so the test still passed. The doc comment and 1a31f72 also claimed it exercises 297352a2fd and 573e746914, but reverting either one in Rust changes the max diff by less than 1e-5. The test now uses its own STEREO_ECHO_TOL = 0.02, and the doc comment states what it guards and what it cannot detect. Measured on macOS arm64 and on x86_64 Ubuntu 24.04 (GCC 13, -march=native, Docker linux/amd64 emulation on Apple silicon, not a native x86 host): the baseline diffs agree to within 1e-5 and the mono-render diffs to within 2e-6 across the two, so the margin is about 3.6x above the baseline and 2.3x below the regression. Verified: the test now fails with multi_channel_render = false (tolerance) and with multi_channel_capture = false (channel check). The unit tests added in d3904ab cover 297352a2fd. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
Moves the fork from feb3c50 to 3b33b6e on sync/post-m145-fixes: - 8fa9626 regenerates output_data_float_avx2.pb for the multi-channel defaults (x86_64, GCC 13, -march=native; not yet confirmed on native x86 hardware) - 3b33b6e lists the multi-channel AEC3 output changes, the headroom change, the removed field trials and the test changes in NEWS No library source changes, so cpp/install and the Rust/C++ comparison are unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #36 +/- ##
==========================================
+ Coverage 93.64% 93.69% +0.04%
==========================================
Files 146 146
Lines 31130 31484 +354
Branches 31130 31484 +354
==========================================
+ Hits 29153 29499 +346
- Misses 1753 1762 +9
+ Partials 224 223 -1
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Upstream AEC3 can use an optional, experimental neural residual echo estimator (ML-REE). The port skips it: upstream ships it disabled, it needs TensorFlow Lite (C++) and a trained model that is not public, and the C++ reference sonora validates against does not build it. Record that in the sonora-aec3 docs (rendered on docs.rs) and point to it from the main README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
|
Hey @dignifiedquire , cool to see your work on this project! I was curious, do you imagine you will support the neural aec backend within sonora? Or is it a bit too complicated outside the scope here? |
The changelog said the new input volume controller defaults leave the processed samples unchanged. That is false when capture_level_adjustment.analog_mic_gain_emulation is enabled: the recommended level is stored as the emulated analog gain (audio_processing_impl.rs:769-770) and applied as pre-gain to the next capture frame (:486-490), so the output level changes. The AEC3 entry listed the suppressor config update port (e10cd19640) as if it were a new capability. Nothing in the port can trigger it, so describe it as internal with no behaviour change. The sonora-aec3 README said the suppressor config switch is ported for parity. Only the receiving side is: echo_remover passes the fixed config.suppressor and false. Say so. Upstream removed the "experimental API" note from the ML-REE creator header in 25cc1a2275; it is still present at M145 (branch-heads/7632). Say it was marked experimental at M145. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
7a129c1 changed the input volume controller bullet to "Processed samples are unchanged unless capture_level_adjustment.analog_mic_gain_emulation is enabled". That is still false for the documented use of recommended_stream_analog_level(): a caller that passes the recommendation back with set_stream_analog_level() changes the applied volume, which sets applied_input_volume_changed (audio_processing_impl.rs:298-304). AGC2 then resets its speech level estimator and saturation protector (gain_controller2.rs:241-248, via audio_processing_impl.rs:706), and with the echo canceller enabled AEC3 receives an echo path gain change (audio_processing_impl.rs:508). The new defaults change when the volume changes, so the output changes even for identical input. Measured with AGC2 (input volume controller and adaptive digital gain), emulation off, on near48_stereo.pcm (channel 0, 1,344,000 samples) before and after d09e7ff: with a fixed level of 128, 0 samples differ; with the recommendation fed back each frame, 1,191,182, 1,144,735 and 1,203,175 samples differ at input scales 0.05, 0.3 and 1.0. The bullet now says that the controller does not modify samples itself, names both ways its recommendation reaches the output, and says that the output changes for callers that apply it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR syncs sonora with the post-M145 upstream WebRTC fixes, for full parity between the Rust port and its C++ reference. The Rust port gets the upstream changes it was missing. The
cppsubmodule moves to a fork branch with the same commits cherry-picked, so the Rust-vs-C++ comparisons stay in lockstep.Important
Depends on dignifiedquire/webrtc-audio-processing#1. The submodule points at fork commit
3b33b6e. Merge the fork PR with a merge commit first; squash or rebase would orphan3b33b6e.User-visible change: IVC defaults
InputVolumeControllerConfig::default()held test-style values that matched neither M145 nor upstream. It is now upstream's productionConfig{}afterd9b92fe1bc:enable_clipping_predictorupdate_input_volume_wait_framesWith
input_volume_controllerenabled, this changesrecommended_stream_analog_level(). Whether the processed samples change depends on what happens to that recommendation:set_stream_analog_level(), orcapture_level_adjustment.analog_mic_gain_emulationis enabled (the emulated analog gain follows the recommendation): the output level changes. A probe found 1.1–1.2 million of 1.44 million samples changed.There's a CHANGELOG entry under "Unreleased".
Upstream commits
a6d83994aa: stale AECm documentation only; the port never had AECm.7f5a8b656cd460e60e19: headroom fix. The test that asserted the buggy value now asserts 0.d9b92fe1bce10cd19640: the non-neural-estimator parts, including theMovingAveragestart-up normalization and theconfig_changedflow.fe9c0a1de4,4252c6051d,8dd6b47c8386ef7fa42d297352a2fd,573e746914and7c388cbabb, via9e4b402. That commit's message swaps the first two hashes.32feae39d0,05d6bc269cand401392b7e6: the port never had these field trials.Commits
bf41756port: Remove aec_mobile (AECm) config from audio_processing.h3ea7be9port(aec3): Propagate delay estimator fields to AecState.9e455f7port(aec3): AEC3: Fix render buffer headroom calculation on underrunsd09e7ffport(agc2): Make max target input level for input controller -12dBdce1a5cport(aec3): Audio: Enable dynamic on-the-fly AEC3 configuration updates for the suppressor gain computationb4fe2fcport(aec3): Remove the usage of the field-trial WebRTC-Aec3AecStateFullResetKillSwitchcb89e6dport(aec3): Remove the usage of the field-trial WebRTC-Aec3CoarseFilterResetHangoverKillSwitch946592eport(aec3): Remove the usage of the field-trial WebRTC-Aec3DeactivateInitialStateResetKillSwitch492e58dport(aec3): aec: fix wrong sentinel usage in echo metrics8149e8cchore(cpp): update submodule with post-M145 upstream cherry-picks1629a49test: compare 48 kHz stereo echo pipeline with decorrelated channels against C++1147f9cdocs: note post-M145 upstream cherry-picksf556978test(aec3): check that comfort noise is identical on all channels4a021c1test(aec3): port SuppressionGainTest.BasicGainComputation and cover config_changedc1375c1test(agc2): build IVC tests on the production config where upstream does45cad1afix(sonora-sys): rebuild the shim when the C++ headers or library change5dc45e4docs: keep the 0.1.0 changelog entry and name sonora-ffi as the backend024f9cetest: give the stereo echo comparison a tolerance that catches mono render8a829c4chore(cpp): update submodule with the AVX2 reference and NEWS fixes828cc67docs: note that the neural residual echo estimator is not ported7a129c1docs: correct the IVC and AEC3 changelog claims and the ML-REE notes72366c3docs: say how the IVC recommendation reaches the outputTests added or strengthened
stereo_echo_pipeline_matches_cpp(sonora-bench): 48 kHz stereo with different signals on each channel, against C++, with tolerance 0.02. It fails if render or capture falls back to mono. It cannot detect a regression of the comfort-noise or filter-switching changes, which move the output by less than 1e-5; its doc comment says so.SuppressionGainTest.BasicGainComputation: ported, plus aconfig_changedtest. Deliberately breaking the code in three ways each made a test fail.Config{}now use the production default.sonora-sysbuild:build.rsnow reruns when the C++ headers, the installed library, orWEBRTC_CPP_ROOTchange. Before, the shim could silently link against stale headers.Verification (local, macOS arm64)
cargo fmt --all --check, and both CIclippy -D warningscommandscargo test --workspace: 772 passed, 0 failed, 0 ignoredRUSTDOCFLAGS=-D warnings cargo doc --workspace --no-deps, andcargo +1.91.1 check --workspace --all-targetsKnown and deferred
AudioProcessingTest.Formats(53 format-conversion cases) into an error-code-only test. That removes the only Rust-vs-C++ output check across rate and channel conversion; sonora-bench covers only matched formats. Follow-up: add sonora-bench comparisons for conversions (for example 48k stereo to 16k mono, 44.1 kHz, mono to stereo).sonora-aec3README and the top-level README say why.EchoRemover::process, as it is upstream.48k_*/ec_onlydiffers from C++ by 0.156 against a tolerance of 0.2. The number is identical before this branch, and it hasn't been investigated.🤖 Generated with Claude Code
https://claude.ai/code/session_01H29DamSLugosGXJSz1e5Yx