# Twin FUN_180535880 transcription (Phase 2) ## PHASE-3 CALLER + GRID (2026-08-18) - Caller FUN_180536300 (decomp 6218 / sp_180536300.txt) decoded at buffer level: - params: param_1=top DSP, param_2=out, param_3=?, param_4=band obj, param_5=cell count, param_7=scratch (>=52*N bytes complex). - scratch: +0..8N A-accum, +8N..16N B-accum, +16N..24N z-powers, +24N..32N rotor-in (fill 1.0), +32N..36N phase ramp lVar1, +36N..44N rotor-out z1 (r14), +44N..52N lVar3(1.0)/lVar4(0.0) for interleave+negate+exp build. - 0x18052da00(lVar1, scale=2pi/(iVar7*sr), N) = ramp fill (float, via 0x180001a00); - twin always = FUN_180535880 (type-info compare of same addr -> equal); sibling FUN_180536f90 is dead. - 0x18052dbc0(param_2, lVar4, N) = cplx interleave -> out=(cos,sin)=e^{+i theta}. - GRID LAW (verified from trace.txt case8 + constructor): - os = *(int*)(param_1+0x240080) = 4 (written 0x18052ce3e `mov ...,0x4`) - sr = *(float*)(param_1+0x24) = 44100.0 - fs_total (generator) = os*sr = 176400 => resonance shape f/fc invariant to fs. - per-cell phase step = 2*pi/(os*sr); cell k <-> freq = k/os Hz (0.25 Hz steps). - Phase-1 model FS=44100 was a valid normalization (res(f) depends only on f/fc). - case8 generator call (trace 33361..33490, switchD_1805318ab): - +0x814 numBands = 1, +0x103 mode flag = 1 - param_5 (float, xmm4) = 10^(sens_dB/20) (pow10 10.0^([band+0x101]/20.0)) - gain = sqrtf(param_5) = 10^(sens_dB/40); model fit gain=4.132 => sens_dB@0x101 ~= 24.65 - freq = [band+0x804], Q = [band+0x80c], fs_total = os*sr (w0 = max(fc,2)*2pi/fs_total) ## PHASE-2 GATE: PASSED (2026-08-18) - `dsp/twin.hpp` + `dsp/twin.cpp` written: build_twin_coeff (FUN_180533ec0 double pipeline -> cvtpd2ps), cplx_div_exact (0x181a77520: mulps |A|^2, rcpps + Newton, NaN guard), cplx_mul_exact (0x18000ad60 scalar body @0x18000ae00: vfmaddsub213ps form), twin_apply (seed A0/B0 + 2 vfmadd213ss Horner stages + 2*div). - twin_check gate: fc-scan grid (7 fc, Q=0.9999978, gain=4.132, tone 1000 Hz) max |rel err| = 1.27e-5 vs double reference res_at (float rcpps parity). DUAL sweep (Q=0.1..10 x tones 500/2000, fc=500) max = 1.23e-5. Both PASS. - Constants locked: A1 = B1 = cos(w0)*-2.0, z1 = conj(exp(+i*theta)), z2 = cplx_mul(z1,z1), out = 2*B/A. ## Confirmed scalar math (from generator + cplx-div kernels) - Generator FUN_180533ec0 (per band, case8): `fVar1 = sqrtf(param_5)` (param_5 = pow(10, sens/20) via cd6 IAT stub) `w0 = max(2.0, freq)*2*pi / fs_total` (fs_total = 2*FS frame?) `p = sin(w0)*0.5 / Q` `dVar5 = p*fVar1` (A tap), `param_4 = p/fVar1` (B tap) A = [1+dVar5, dVar2, 1-dVar5], B = [1+param_4, dVar2, 1-param_4] where dVar2 = cos(w0) * DAT_1824c46b0 (=-2.0? VERIFY) - Twin FUN_180535880: for each FFT bin z (rotor): `res(z) = 2 * B(z) / A(z)`, B(z)=B0+B1*z+B2*z^2, A(z)=A0+A1*z+A2*z^2 implemented as complex FMA accumulation over 3 taps: r15 (A-accum) and r12 (B-accum) via 0x180001fd0 vfmadd213ss (coeff [rsp+k*4+0x28]=A_k, [+0x38]=B_k) rbp buffer = z powers via rotor ops (0x1800019a0 fill / 0x1800021e0 / 0x1800018b0 / 0x180001af0 / 0x180001dc0) final 0x180001e20 -> 0x181a775a0 cplx-div: out = 2*B/A (xmm7=0x40000000=2.0, xmm6=NaN guard) - cplx-div kernel 0x181a77520: |A|^2 via shufps 0x88/0xdd, rcpps + 1 Newton step (xmm7=2.0), NaN guard via cmpeqps. Matches rotor_kernel.hpp cplx-div exactly. ## Dispatch (all stubs share global 0x1826159a0 = 4 = AVX2) 0x180001d00 -> 0x180009860 -> 0x180040d40 (cplx fill const, NT stores) 0x1800019a0 -> 0x180004200 (float fill -> 0x181a63fe0) 0x1800021e0 -> 0x1800130e0 (large AVX, 0x450 stack, rotor/exp?) 0x1800018b0 -> 0x180003040 (-> 0x181a557c0) 0x180001af0 -> 0x180005a20 (loop -> 0x18001a5a0) 0x180001dc0 -> 0x18000ad60 (cplx op r14*rbp) 0x180001e20 -> 0x18000b820 (-> 0x181a775a0 cplx-div 2B/A) 0x180001fd0 -> 0x18000f620 (vfmadd213ss: out = src*coeff + dst) ## Coefficient layout in twin (param_3 = {double A[3], double B[3]}) stack: +0x28=A0 +0x2c=A1 +0x30=A2 | +0x38=B0 +0x3c=B1 +0x40=B2 loop k=0..2 uses A_k via [rsp+k*4+0x28], B_k via [rsp+k*4+0x38] r15 = out A-accum, r12 = out B-accum, rbp = z^1..z^2 buffer, r14 = rotor(z) input ## PHASE-1 LOCK (empirical, 36 points, LUT chain B.11) Effective sqrtf(param_5) needed ~= 4.13 (NOT 1.995). => param_5 ~= 17.07 = 10^(1.2325) => internal sens_stored ~= 24.65 dB (not XML 12.0) OR equivalent. RULED OUT: sqrt(10^(12/20))=1.995 (rmse 1.38/5.68); 10^(12/20)=3.981 direct (t1kq 0.056 but t1k 0.934); |2B/A|^2 (1.5/6.6). Sens setters (0x18053795d, 0x18056f002) both store RAW value; +0x808 scaling is HOST-side (plugin controller, outside dump) => must be resolved via bit-exact render or host trace. NOTE: single-gain compromise 4.132; t1kq wants 4.055, t1k wants 4.137 (tilt residual).