Repository navigation
spectral_reverb returns under the ABI rules, measured against the plates (phase 2 item 7, part 2) - #86
Merged
Conversation
…tes: it loses (phase 2 item 7, part 2) tap::mu::spectral_reverb (include/mutap/spectral_reverb.h), the per-bin WOLA reverb from the karaoke branch (8abe958), made legal and measured on part 1's harness beside the as-shipped Dattorro plate: - inside tap::mu::inline TAP_DSP_FFT_ABI, its 2 x block FFT size through fft_detail::checked_fft_size, pinned as the sixth embedder in test_fft_engine_contract.cpp (tag by name and typeid, the size gate swept in both profiles); an afc_stage (process_block(in, out, n) noexcept, allocation only at construction, latency() one block), a flat mode (spectral_shaping::flat) and an explicit shape_max, shaped from F_hat or the coherent bus sum |sum F_hat_m|; - float plumbing test_spectral_reverb.cpp in both emulated selections (bare_metal_main.cpp and TEST_FILTER; on-target count 118); - decorrelated_loop's forward stage takes a stage's latency() out of the forward delay (0 for the plates: their rows repeat); - tests/support/spectral_rig.h, the gated host rows test_spectral_reverb_host.cpp, the MUTAP_SLOW sweep test_spectral_reverb_sweep.cpp (ProbeConvergence, Grid), karaoke_ramp_dump --reverb spectral, reverb_audible.py --plate spectral; - docs/reverb-afc.md "Spectral reverb", HANDOFF items 11 (resolved) and 13. Measured (macOS 15.7 x86_64, AppleClang 17, Release, five seed sets): behind PEM + FD-Kalman, six rooms, held note, S1 and S3, wet 0.15 / 0.30, flat and shape_max 1 / 2 / 4 (40 s probes, not converged): cost +2.83 to +30.57 dB (median of room medians) against the plate's -1.37 to +0.88. Without a canceller the flat reverb sits 17 to 32 dB below the dry room. Shaping helps only at shape_max 1; the long decays sit where |F - F_hat| is small (rho -0.336 to -0.688), not where it is worst. Every spectral row is audible earlier than the plate at the same wet. Verdict: it loses; kept only as a measured negative result (header says so). Fingerprints and icount unaffected: the class is not in the fingerprint harness or any icount workload, and fft.h changed in comments only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDhgJqxUsdmWPKh6pKrV5A
…ies by default The converged 80 s rows cost 697 s (CostsMoreThanThePlateBehindTheCanceller) and 189 s (UnsafeWithoutTheCanceller) on 3 threads, more than the sanitizer legs can afford; both now skip unless MUTAP_SLOW=1. The default run carries a short proxy of each, 20 s probes, two seed sets, the same directions: - UnsafeWithoutTheCancellerShortProbe (cabin and mt5, open loop): flat -29.80 / -22.42, shape_max 1 -19.79 / -13.98 dB (means; the 80 s medians -30.51 / -22.77 and -19.61 / -14.69); gates < -15 and < -8, as the slow row's. 27.03 s. - CostsMoreThanThePlateShortProbe (cabin, behind the canceller): the plate's limit minus the spectral reverb's, +14.66 (flat) and +9.78 (shape_max 1) dB (means of +15.75 / +13.56 and +11.62 / +7.94); gates > +6 and > +3. 77.25 s. Short probes understate both the spectral cost and the open loop's danger (ProbeConvergence: those medians fall with probe length), so a pass is conservative. The default spectral host rows take 104.5 s on 3 threads of the Intel Mac. docs/reverb-afc.md says where the plate rows are described that a stage's latency is budgeted inside the loop delay, lists the S3 chain-output flags as an open item beside the plates' S3 lines (the ‡), and gives the new rows and timings; HANDOFF item 11 likewise. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDhgJqxUsdmWPKh6pKrV5A
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.
Phase 2 item 7, part 2 (HANDOFF item 11).
tap::mu::spectral_reverb, the per-bin reverb from the karaoke branch (8abe958), comes back under the ABI rules and is measured on part 1's harness beside the as-shipped Dattorro plate.Verdict: it loses to the plate everywhere measured. It stays in the repo only as a measured negative result, and its header says so. Removing it again is the alternative; I recommend against it, because the gated rows that hold the verdict need the class.
What changed
include/mutap/spectral_reverb.h:tap::mu::inline TAP_DSP_FFT_ABI;fft_detail::checked_fft_sizebefore any buffer is sized (working note 6 (b): on the M55 an unchecked size is a release-mode HardFault);afc_stage(process_block(in, out, n)noexcept, n a multiple of the block), allocating only at construction,latency()one block;spectral_shaping::flat/from_pathwith an explicitshape_max;reshape_from_impulse_response) or from the coherent bus sum |Σ F̂_m| (reshape_from_impulse_responses).tests/test_fft_engine_contract.cpppins it as the sixth embedder: the tag by qualified name and typeid, and a size-gate sweep in both profiles plus the explicit CMSIS rows.mutap/fft.hcomments go from "five" to "six".tests/test_spectral_reverb.cppcovers the float/double plumbing and runs in both emulated selections (bare_metal_main.cppandTEST_FILTER, kept in sync; the on-target count comment is now 118).decorrelated_loop's forward stage now takes a stage'slatency()out of the forward delay. The plates report 0, so their rows repeat: the S1 cost medians match part 1's grid to the printed digit.tests/support/spectral_rig.h: the measurement and the per-bin hypothesis statistics;tests/test_spectral_reverb_host.cpp;MUTAP_SLOWsweeptests/test_spectral_reverb_sweep.cpp(ProbeConvergence, Grid);karaoke_ramp_dump --reverb spectralandreverb_audible.py --plate spectral.docs/reverb-afc.mdgets a "Spectral reverb" section, and the headline, intro, not-run list and provenance are updated. docs: the S3 wet-0.30 audible rows examined — bounded lines at the plate's own modes, loop-dependent #84's S3 paragraphs are kept. HANDOFF item 11 is rewritten as resolved; items 13 and working note 6 are updated.MUTAP_SLOW, and 20 s proxies run by default;Numbers
All from macOS 15.7 x86_64, AppleClang 17, Release, five seed sets.
Probe convergence (S1, wet 0.30, rt60 1 s; median ASG re the dry open loop). Unlike the plates (10 s), only the cabin's flat, shape_max 1 and 2 held rows converged, at 80 s. shape_max 4 and every mt5 chain row had not converged by 160 s.
The doc has the full table, mt5 and the speech envelope included.
Behind the canceller. Six rooms, held note, 40 s probes, so not converged; the doc explains why this mostly understates the cost. Values are the median of room medians.
Open loop (no canceller, 160 s): flat sits 17.15 to 31.80 dB below the dry room (room medians), confirming HANDOFF 11's −18 to −25. Shaped rows sit 12.56 to 29.84 dB below.
Shaped vs flat:
Hypothesis (Spearman over the 65 bins, at the moment of shaping, 30 runs per row):
Audible (cabin, ramp + criterion, PROTOCOL §7.3, rt60 1.1846 s; chain output, with c in brackets):
Every spectral row is audible earlier than the plate at the same wet. The doc has all 16 rows.
Gated rows. Converged probes run behind
MUTAP_SLOW. The default run carries 20 s, two-seed-set proxies with the same directions. Short probes understate both the spectral cost and the open loop's danger, so a pass is conservative.DecayAndLevelBesideThePlateUnsafeWithoutTheCancellerShortProbeCostsMoreThanThePlateShortProbeUnsafeWithoutTheCancellerMUTAP_SLOWCostsMoreThanThePlateBehindTheCancellerMUTAP_SLOWThe 20 s values are recorded beside the 80 s ones in the test comments, for this host only so far; CI's legs run the default rows.
Verification
cmake -DCMAKE_BUILD_TYPE=Release -DMUTAP_WERROR=ON -DMUTAP_BUILD_KARAOKE_DUMP=ON: built clean.MUTAP_SLOW_THREADS=3. At aadf7db, with the 80 s rows still in the default run, it was 418/418 in 4479.84 s.mutap_fingerprintpassed.pre-commitvia xargs: passed.scripts/tidy.shon the 8 changed host TUs: clean. A directclang-tidy-18 -p build-tidycount: 0 project warnings.fft.hchanged in comments only.Sweep wall times, on 3 threads of the shared Intel Mac:
Not run (the budget)
🤖 Generated with Claude Code
https://claude.ai/code/session_01DDhgJqxUsdmWPKh6pKrV5A