From 1f38f1a7fbfd8cd3e2f899c7e2dd85003c40f07b Mon Sep 17 00:00:00 2001 From: monkey-w1n5t0n Date: Tue, 21 Jul 2026 17:04:35 +0200 Subject: [PATCH] fix(engines): restore MEMLCelium's feedback tap (L7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feedback_/fbzm1_/fb_smooth_alpha_ were read every process() call but nothing ever wrote feedback_, so the path was silently inert. Git history shows this was a *muted* feature, not dead code: `feedback = v0 * feedbackGain` with feedbackGain 0.1f (MEMLCeliumAudioApp.hpp @ d095688), then "0; //0.1f" — zeroed with the value kept in the comment — then the write was dropped entirely when the engine was ported to nisps/engines/ at the 2026-04-29 rewrite (8d0d47b). Operator decision: port it back, live at 0.1f. The tap is voice 0's own enveloped output, post-envelope and pre voice-1/mix/ shape — NOT the final output. This differs from PAFSynth's feedback shape; where the sibling and the reference disagreed, the reference won. Not schema-exposed: the reference hardcoded it, and MEMLCelium has no voice spaces to vary it by. If feedback depth becomes a research axis it wants to be a runtime parameter — noted, not built. Verification, and a gap worth recording: parity-check.sh PASSES (max delta 2.38e-7) but that is NOT evidence for this change — its harness only exercises PAFSynth and ChannelStrip, and the impulse baseline runs all-params-0.5, under which voice 0's sequencer never triggers, so v0_env stays 0 and the new write is 0 either way. That baseline is blind to this path, not a check on it. So it was cross-checked directly instead: sequencer params forced to trigger early, 4800 samples native vs WASM through the nisps_engine_* C ABI — native vs WASM max abs diff 1.19e-7 (tolerance 1e-5) all 4800 samples nonzero, finite, max amplitude ~0.99 (tanh-bounded) same run with gain forced to 0 diverges by up to 1.49 — not a no-op No fixture regenerated. nisps.wasm ships here because it is a tracked artifact under the Phase 0 freshness gate. Follow-up: the parity harness covers 2 of 8 engines. "Firmware and WASM share the same engines" is asserted repo-wide but tested narrowly. --- manifold/public/nisps.wasm | Bin 130040 -> 130068 bytes nisps/engines/memlcelium.hpp | 14 ++++++++++++++ 2 files changed, 14 insertions(+) diff --git a/manifold/public/nisps.wasm b/manifold/public/nisps.wasm index 7dab364393dbe0d04884655de4cda71619404a67..9eb04a87f08e9e7d4a4978b86579f109f31a5c3d 100755 GIT binary patch delta 795 zcmY+CO=uHA6vubo>~=TFt_9J02-2BdLFqv#l)4JiMw>KglAaXAV4Aa_z4TBD)nL6U zxNi{!^(5lKL$E?F0X=x|5TRfM1%(`nryP1HG>05~v)hvNGH>Sn-^Xv>O#i?P`)1=0 zu%Fw1VKc+tVP!#{gX@}B{~QPq(QdAmb}b)vIJq@Vf?!in$GzNXJ>FLb7o>@u+zhiYv3Sw9YK|tj5AmMA0CbuQ*ypi`=-n_+&g8QC8jY46Mz<0O#}aLXVX^_` zE=OH-j+E7tTUSDnz#DmwIk=ubYnicR2a}D9AzgL6>34mu5@+$ z0;BBF)QFwbQT90V>o5~%N+PLlHU&FC;MLNjGsbWP0|jmP^bdrA2c=4ihs5o2dUTF= z%HD)Yqk6&a#-HG=9v({1%ibx2q}Gx2K9=x%`MftqzdbkO|qbQ{~l}DY_~bN!Pa@|TD@NH|9H9m@9L%In@x86!GH8osw)5h delta 767 zcmY*XO=uHQ5YC%@n@x5%si;IDgub^CgdP+@YP5&CG-;BiX-`5R(B`V(&%uL;)!2&1 z9(J~*dXx_kHutw=?VajNTuk zwF7MP#aCEz*(%oa@~}1)i8Nn(LKDGlvXOR-9Bga&FrQ%tZst2IhUafm+GRM@S}P0S7QQWij*dZ-W`z%C zZmmA-+!?t)2> zJEDTrhwcWI@BUR{ZC03iu*PkWQCyx~KD6f}gDsFumt-(qty|y=vPBu?x2xF{{TS|j zc7bxTu)+NhdR5IHBvE&37kV~;@K^QdaV~7yrAT@r=J`SwQMFWBGbudc4j}zBrm#H1 wg3HRpTzg`U&5W|u_T7uDWwTEE)OB`EGu>vh*`rnL@OzK1u "0; + // //0.1f" (explicitly muted, value preserved in comment) -> the write + // was dropped entirely when the engine was ported to nisps/engines/ at + // the 2026-04-29 rewrite (8d0d47b) — feedback_/fbzm1_/fb_smooth_alpha_ + // kept being read in process() but nothing wrote feedback_, so the path + // was silently inert. Operator decision: port it back live at 0.1f, not + // muted. Not schema-exposed — a single fixed value (MEMLCelium has no + // voice spaces to vary it by, unlike PAFSynth's feedback_gain_). + float feedback_gain_ = 0.1f; }; static_assert(AudioEngine, "MEMLCeliumEngine must satisfy AudioEngine");