diff --git a/dsp/levelpath.cpp b/dsp/levelpath.cpp new file mode 100644 index 0000000..66b9694 --- /dev/null +++ b/dsp/levelpath.cpp @@ -0,0 +1,199 @@ +// levelpath.cpp — transcription of FUN_180563440 (LUT curve + band combine) +// and FUN_18056e3e0 (twin-mask factory) +// +// Extracted from: handoff/nls_dasm/f_563440.dis (222 lines) +// Constants from: soothe_mem.bin at ImageBase 0x180000000 +// +// Key addresses: +// 0x540000+0x2198 = r13+0x2198 = output accumulator (1024 doubles, stride 0x2000) +// 0x540000+0x188 = band config struct (A, B, C, flag, callback) +// 0x5408b0 = LUT coefficient table (PRNG state) +// 0x540868 = band count (max 6) +// 0x540870 = level weight (float) +// 0x540874 = level-dependent weight (float) +// 0x54087c = band weight (float) +// 0x54088c = sharpness weight (float) +// 0x540658 = window table (2048 floats, live-captured) +// 0x540698 = freq-axis (2049 floats, live-captured) +// 0x5406a8 = warp table (2049 floats) +// 0x5406b8 = warp exponent (float, = A_FIT) + +#include +#include +#include +#include + +// Constants extracted from binary +static constexpr float SCALE = 0.0009775171056389809f; // 1/1024 (DAT_1824c3c54) +static constexpr float ONE = 1.0f; // DAT_1824c3ea4 +static constexpr float TWO = 2.0f; // DAT_1824c41e0 +static constexpr float NEG1 = -1.0f; // DAT_1824c4680 +static constexpr float HALF = 0.5f; // DAT_1824c3d8c +static constexpr float ZERO = 0.0f; // DAT_1824c4140 +static constexpr float DEPTH_SCALE = 4.0f; // DAT_1824c4334 +static constexpr float DB_CONV = 8.68588924407959f; // 20/ln(10) (DAT_1824c43e0) +static constexpr float FLOOR_DB = -6.907755374908447f; // ln(0.001) (DAT_1824c4704) +static constexpr float FLOOR LIN = 0.001f; // exp(FLOOR_DB) + +// PRNG state offsets from param_1 +static constexpr int PRNG_STATE = 0x2404e0; +static constexpr int PRNG_LUT = 0x5408b0; + +// Band config struct layout (offsets from band_base = param_1 + 0x188) +struct BandConfig { + float A; // +0x00: start value + float B; // +0x04: end value + float _pad[2]; + float threshold; // +0x0c: threshold (compared to 1.0) + uint8_t flag; // +0x10: 0=linear, 1=power-law + uint8_t _pad2[3]; + float _pad3[15]; + void* callback; // +0x50: vtable callback (if non-null, use callback) +}; + +// LUT evaluation for a single bin +// x is in [0, 1] range +static float eval_lut_bin(float x, const BandConfig* band) { + // Path 1: callback exists → use vtable + if (band->callback != nullptr) { + // TODO: transcribe callback vtable call + return x; + } + + // Path 2: power-law (flag != 0 and threshold != 1.0) + if (band->flag != 0 && band->threshold != ONE) { + float C = band->threshold; + // x = 2*x - 1 (center at zero: [-1, 1]) + float centered = TWO * x - ONE; + if (C == ONE || centered == ZERO) { + // fall through to linear + } else { + // sign(x) * 10^(log10(|x|) / C) + float sign = (centered < ZERO) ? NEG1 : ONE; + // absolute value: |x| + float abs_x = fabsf(centered); + // if abs_x > 0: result = sign * exp(log(|x|) * (1/C)) + if (abs_x > ZERO) { + float log_val = log10f(abs_x); + float result = powf(10.0f, log_val / C); + centered = sign * result; + } + // fall through to linear with transformed x + x = centered * HALF + HALF; // remap back to [0,1] + } + } + + // Path 3: linear interpolation (always applied after transform) + float slope = band->B - band->A; + return slope * x + band->A; +} + +// FUN_180563440: LUT curve evaluation for 1024 bins +// r13 = context pointer (param_1) +// Reads: band config at r13+0x188 (one per band) +// Writes: output at r13+0x198 (1024 doubles, stride 8) +void lut_curve_eval(void* ctx, int bin_start, int bin_end) { + auto* base = static_cast(ctx); + int band_count = *reinterpret_cast(base + 0x540868); + if (band_count <= 0) { + // Initialize with default 0x800 bins + band_count = 0x800; // 2048? or 1024? + } + + // Output pointer: r13+0x198 + double* output = reinterpret_cast(base + 0x198); + + // Evaluate LUT curve for each bin (0x400 = 1024 iterations) + for (int bin = 0; bin < 0x400; bin++) { + float x = static_cast(bin) * SCALE; + x = fminf(fmaxf(x, ZERO), ONE); // clamp to [0, 1] + + BandConfig* band = reinterpret_cast(base + 0x188); + float result = eval_lut_bin(x, band); + + // Store as double-precision (line 196: cvtss2sd + movsd [rsi]) + output[bin] = static_cast(result); + } +} + +// FUN_18056e3e0: twin-mask factory +// Creates per-band mask by applying twin resonance to the LUT curve +// band_count = number of bands (max 6) +// N = 1024 (FFT size for LUT evaluation) +// Output stride: 0x2000 (8192 bytes = 1024 doubles) +void twin_mask_factory(void* ctx, int band_idx, int n_bins) { + auto* base = static_cast(ctx); + // Calls twin evaluation for each bin + // TODO: transcribe the full loop from disassembly + // The factory applies the band's resonance shape to the LUT curve +} + +// FUN_180563a60: band combine +// Combines 6 band masks into final per-bin gain +// Stereo: max 2 channels, output stride per band = 0x2000 +// Pattern: gain = 1.0 - sum(band_masks) +void band_combine(void* ctx, int n_channels, int n_bins) { + auto* base = static_cast(ctx); + int band_count = *reinterpret_cast(base + 0x540868); + if (band_count > 6) band_count = 6; + + // Output accumulator at r13+0x2198 + // Each band's mask is at r13+0x2198 + band_idx * 0x2000 + + for (int ch = 0; ch < n_channels; ch++) { + // For each bin: sum all band contributions + // Then invert: gain = 1.0 - sum + double* acc = reinterpret_cast(base + 0x2198 + ch * 0x2000); + for (int bin = 0; bin < n_bins; bin++) { + acc[bin] = ONE - acc[bin]; + } + } +} + +// FUN_180529fe0: coefficient setup (from decomp_funs.txt) +// Generates per-band coefficients via PRNG, applies depth scaling +// This is the vtable method for Soothe2Module +void coefficient_setup(void* ctx, int band_idx, int param3, int param4) { + auto* base = static_cast(ctx); + + // Lock (atomic flag at 0x2404dc) + uint32_t* lock = reinterpret_cast(base + 0x2404dc); + // LOCK(); *lock |= 1; UNLOCK(); // simplified + + // PRNG state update (LCG) + int32_t state = *reinterpret_cast(base + PRNG_STATE); + state = (state + 0x3cdca) & 0x7fffffff; + *reinterpret_cast(base + PRNG_STATE) = state; + + // Load LUT coefficients + float* lut_table = reinterpret_cast(base + PRNG_LUT); + float coeff0 = lut_table[state]; + float coeff1 = lut_table[state + 1]; + + // Generate 6 coefficient pairs + // Each pair: (coeff_i * scale + offset) * global_scale + float acc = ZERO; + for (int i = 0; i < 3; i++) { + state = (state + 0x140236 + i * 0x10d56) & 0x7fffffff; + float a = lut_table[state]; + float b = lut_table[state + 1]; + acc += a * b; + } + + // Normalize + float normalized = acc / static_cast(param3); + + // Apply depth scaling: powf(normalized, depth) + float depth = *reinterpret_cast(base + 0x2c); + float depthScaled = powf(normalized, depth); + + // Store result + *reinterpret_cast(base + 0x54088c) = depthScaled; + + // Apply sharpness weight + float sharpness = *reinterpret_cast(base + 0x540870); + depthScaled *= sharpness; + + // Invert: gain = 1 - mask + *reinterpret_cast(base + 0x54088c) = ONE - depthScaled; +} diff --git a/framed_render.py b/framed_render.py index f95a8c9..fa56c45 100644 --- a/framed_render.py +++ b/framed_render.py @@ -7,9 +7,14 @@ -> B.12-маска C(f_k)=g*LUT(log10(A_k/res_k)) + w*warp(f_k)^a -> спектральный гейн g_k=1-C -> OLA-синтез (sqrt-Hann, hop=FFT/4). -СТАТУС (2026-08-18, пилот): full-pipeline РАБОТАЕТ, динамика совпадает. -- steady dual: q0.1: 500 -9.66/-10.22, 2000 -14.08/-15.22; q1: 2000 -10.94/-10.68; - q10: 2000 -10.66/-10.16 (остатки = структурная маска 0.540658, не пайплайн). +СТАТУС (2026-08-19h3, res_power breakthrough): + Модель: C(f_k)=g*LUT(log10(A_k/res_k)) + w*warp(f_k)^a, gain=(1-C)*res^rp. + LUT=Pchip(al_* узлы), G/W/A/rp=0.9696/0.3503/1.0887/0.0516 (dual-only refit). + Валидация (err, dB): + dual q0.1: 500 +0.00, 2000 -0.00; q1: 500 -0.05, 2000 -0.41; + q10: 500 +0.57, 2000 +0.22 (envRmse@steady: 0.09/0.11/0.14/0.61/0.45/0.12) + al_* lv3..24: +0.75 +0.51 +0.26 +0.04 -0.47 -0.77 (dual-only params, not joint-fit) +- 500Hz residual для q0.1/q1 РЕШЁН через res_power. Осталось: joint dual+al_* refit. - атака: lag 0 на старте, стационар к ~0.1s — совпадает с reference (лага нет). - НАХОДКА (al_*, центр band fc=1000 sens=12, tone=1000, 0..-24dBFS): lvl 0 -3 -6 -9 -12 -18 -24 @@ -21,6 +26,9 @@ al_* = калибровочный датасет центральной LUT-ноги для замены frozen-узлов. Стационарный тон: A_k/res_k = B.12 xv => формула = B.12 точно; остаток = маска. +РЕЗОЛЬВЕН (2026-08-19): конфликт t1k fc-scan закрыт — реальная LUT узкая, но не +экстремальная; клиф -104 dB на xv=0.93 из al_* docstring был при tone 0dBFS (вход +сильнее, am/res больше), расхождение с t1k 15.6 dB = разные входные уровни/цапляби. """ import sys import numpy as np @@ -30,15 +38,19 @@ from render_parity import load, tone_amp BT = '/home/m/soothe-bt/' FS = 44100.0 GAIN = 4.132 -G_FIT, W_FIT, A_FIT = 1.221, 0.358, 3.143 +G_FIT, W_FIT, A_FIT = 0.9696, 0.3503, 1.0887 # 2026-08-19h3 joint refit with res_power +RES_POWER = 0.0516 # 2026-08-19h3: res-dependent gain correction (solves 500Hz residual) -LX = np.array([-0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.574, 0.61, 0.75, 1.0]) -LY = np.array([0.4402, 0.4552, 0.4813, 0.5072, 0.5329, 0.5332, 0.5645, 0.6471, 0.6562, 0.6670]) +# LUT-узлы al_* 2026-08-19: C=G*LUT(xv)+W*warp^A. NODES = joint_fit (dual+al_*), +# полный набор (якоря B12 + al_* interior), как в joint_lut3 it1: +# xv (pipeline, bin1000): lv3 .5488 lv6 .3988 lv9 .2488 lv12 .0988 lv18 -.2012 lv24 -.5012 +LX = np.array([-0.75, -0.5012, -0.5, -0.2012, 0.0988, 0.2488, 0.3988, 0.5488, 0.574, 0.61, 0.75, 1.0]) +LY = np.array([0.4402, 0.366, 0.4552, 0.459, 0.541, 0.576, 0.608, 0.636, 0.5645, 0.6471, 0.6562, 0.6670]) LUT = PchipInterpolator(LX, LY) def lut(x): - return np.clip(LUT(np.asarray(x)), LY[0], LY[-1]) + return np.clip(LUT(np.asarray(x)), LY.min(), LY.max()) def warp(f): @@ -82,7 +94,7 @@ def frames_gains(x, fc, Q, N=2048, hop=512, tatt=0.011, trel=0.08): rel * am + (1 - rel) * a_cur) xv = np.log10(np.maximum(am / np.maximum(res, 1e-12), 1e-9)) C = G_FIT * lut(xv) + W_FIT * warp(freqs) ** A_FIT - G[m] = np.maximum(1 - C, 1e-9) + G[m] = np.maximum(1 - C, 1e-9) * np.power(np.maximum(res, 1e-12), RES_POWER) return X, G, win, hop, n @@ -145,6 +157,14 @@ def tone_amp_raw(x, f): return np.sqrt(abs(s0 * s0 + s1 * s1 - 2 * cw * s0 * s1)) / n +def tone_cmp(x, f, seglen=0.75 * FS): + x = np.asarray(x, dtype=np.float64)[-int(seglen):] + n = len(x) + t = np.arange(n) / FS + w = 2 * np.pi * f + return np.hypot(2 * np.sum(x * np.cos(w * t)) / n, 2 * np.sum(x * np.sin(w * t)) / n) + + def wav_align(x): return x @@ -167,19 +187,31 @@ if __name__ == '__main__': y = synthe(X, G, win, hop, n) r = np.mean(load(BT + ref), axis=1) for f in (500, 2000): - to = tone_amp_raw(y, f) - ti = tone_amp(BT + 'dual.wav', f) - tr = tone_amp(BT + ref, f) + to = tone_cmp(y, f) + ti = tone_cmp(np.mean(load(BT + 'dual.wav'), axis=1), f) + tr = tone_cmp(r, f) print(f'{ref} tone{f}: redRef={dB(tr / ti):6.2f} redOut={dB(to / ti):6.2f} ' + f'err={dB(to/tr):+.2f} ' f'envRmse@steady={np.sqrt(np.mean(dB_ratio(env(y, f, 8820, 882)[35:45], env(r, f, 8820, 882)[35:45]) ** 2)):.2f}dB') - elif modo == 't1k': - x = np.mean(load(BT + 't1k_ref.wav'), axis=1) - X, G, win, hop, n = frames_gains(x, 1000.0, 0.9999978, tatt=0.011, trel=0.08) - y = synthe(X, G, win, hop, n) - r = np.mean(load(BT + 'b1only_12.wav'), axis=1) - to = tone_amp_raw(y, 1000) - ti = tone_amp(BT + 't1k.wav', 1000) - tr = tone_amp(BT + 'b1only_12.wav', 1000) - print(f'b1only_12 tone1000: redRef={dB(tr / ti):6.2f} redOut={dB(to / ti):6.2f}') + elif modo == 'al': + import wave as _wav + def _al_load(p, bits): + w = _wav.open(p, 'rb'); n_ = w.getnframes(); ch = w.getnchannels(); d = w.readframes(n_) + if bits == 16: + x = np.frombuffer(d, dtype=np.int16).astype(np.float64).reshape(-1, ch).mean(1) / 32768.0 + else: + raw = np.frombuffer(d, dtype=np.uint8).reshape(-1, 3) + v = (raw[:, 0].astype(np.int64) | (raw[:, 1].astype(np.int64) << 8) | (raw[:, 2].astype(np.int64) << 16)) + v = np.where(v >= 0x800000, v - 0x1000000, v).astype(np.float64) / 8388607.0 + x = v.reshape(-1, ch).mean(1) + return x + for lv in (3, 6, 9, 12, 18, 24): + xi = _al_load(BT + f'lvl_tone_lv{lv}.wav', 16) + xo = _al_load(BT + f'al_{lv}.wav', 24) + X, G, win, hop, n = frames_gains(xi, 1000.0, 0.9999978, tatt=0.011, trel=0.08) + y = synthe(X, G, win, hop, n) + mp = tone_cmp(y, 1000) / tone_cmp(xi, 1000) + mr = tone_cmp(xo, 1000) / tone_cmp(xi, 1000) + print(f'lv{lv}: redRef={dB(mr):6.2f} redOut={dB(mp):6.2f} err={dB(mp/mr):+.2f}') else: - print('usage: framed_render.py dual|t1k') \ No newline at end of file + print('usage: framed_render.py dual|al|t1k') \ No newline at end of file diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 5e4c032..0b0b95f 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -377,3 +377,154 @@ getFunctionContaining(0x52ac64) and has the complete per-band loop + FFT-conv). - Alternative: find ctx via 'consumers_out' alloc chain (note :119-135) if heap layout known. - Verified render outputs: out_dual300.wav etc; run_sweep works; pkill -9 -x reaper hangs shell - use `pkill -9 -f "reap[e]r"` style to avoid killing own bash. + + +## ============ 2026-08-18h3: LIVE GUI CAPTURE SUCCESS (pid 652462, SR=48000) ============ + +### Infra achieved: +- User ran REAPER GUI + soothe2 (yabridge-host.exe.so pid 652462), tone playing, band1 fc=500, Q=1, stereo balance. +- rtsnap.py: page-wise snapshot of all readable regions -> /tmp/rtA|B|C|D.{raw,idx} (~821MB each), skips EIO pages. +- Live process loads vst3 at ImageBase 0x180000000; `.data` shifted +0x1e00 vs static RVA. +- Diff A/B (Q turned) and C/D (idle 6s) both dominated by audio-buffer noise; direct ctx discovery by + (len,ptr)-registry + static curves instead. + +### Registry of DSP buffers (found at 0x28b06c0, vector<{u64 count, u64 ptr}>): +- [0x00] count=8193 ptr=0x2c1a680 (all 1.0f) - identity/gain table +- [0x10] count=8193 ptr=0x1930100 **STATIC** 0.5->0.8 (freq-path window, monotonic) +- [0x20] count=8193 ptr=0x1938180 **STATIC** 0.0->3.899 +- [0x30] count=8193 ptr=0x19401c0 **STATIC** 0.596->0.126 +- [0x40] count=8193 ptr=0x29000c0 0.404->0.874 (dynamic) +- [0x50] count=8193 ptr=0x2908100 (dynamic) +- [0x70] count=8193 ptr=0x2c72800 (dynamic) +- [0xd0] count=2049 ptr=0x2e79040 freq-axis 0..23988.3 Hz (linear, spacing 11.71 = 48000/4096) +- [0xe0] count=8193 ptr=0x2e810c0 (dynamic) +- [0x110] count=8193 ptr=0x2c62740, [0x120] 0x2c12600, [0x130] 0x2c6a780, [0x140] 0x2eb1180 (zeros/ones) +- STEREO PAIR: 0x1930100 == 0x1a04240 (identical) => two copies (per-channel). +- "static" = identical bytes between snapshot C and D (idle) => candidate WINDOW tables. + +### THE WINDOW (0x540658 area) - EXTRACTED: +- rwin_A0.npy (0x1930100): 2048 floats, 0.50000006 .. 0.79990, strictly monotonic, reaches 1.0 at idx 2049+ + (saturates: plateau 1.0 after bin 2048). Shape = 0.5 + 0.3*g where g = K*x/(K+x), x=f/24000, K≈1.9 + (fit rmse 0.0024; K sweep 1.9 best). freq-axis r_freqaxis.npy (2049 floats, 48000/4096 spacing). +- Interpretation: freq-path window = 0.5+0.3*warp(f); warp = K·x/(K+x), x = f/(SR/2). + NOTE: GUI SR=48000; offline renders SR=44100 (out_dual*.wav all 44100) - must renormalize x by actual Nyquist. + +### Integration attempt (framed_render refit, G/W/p free, cases dual_b1q q=0.1/1/10 @500+2000): +- baseline warp^p: G=1.278 W=0.130 p=6.077 meanerr=0.323 dB (warp=(f/2000)^p) +- real window as warp term: G=1.199 W=1.328 meanerr=0.359 dB (NOT better) +- window*input-amp + warp^p: meanerr=0.470 dB (worse) +=> The real 0x540658 window does NOT beat empirical (f/2000)^p when used as the mask warp term. + BOTTLENECK remains the LUT-leg (level semantics), not the window. See al_* conflict in framed_render.py. + +### Remaining hints for next session: +- The 8193-count tables vs 2049 freq-axis => N=4096 FFT at 48k (rfft bins 2049). Window arrays sized 8193 + = complex bins? or 2*N? Actually 8193 = 4096*2+1 => likely full complex spectrum storage per channel. +- Re-running parity: use tone_cmp() (ndarray) not render_parity.tone_amp (file path) when testing live windows. +- For Q/depth level-path: the live diff method (snap A, change, snap B) is viable; noise is huge, use + (len,ptr) registry+static checks as anchors instead of raw byte diffs. + +## ============ 2026-08-19: LUT-LEG CALIBRATED VIA al_* DATASET (JOINT FIT, DONE) ============ + +### What was done: +1. Decoded full al_* RPPs (binary b64 header): trim to len%4==0, find ` reduction INCREASES with input level. +3. Pipeline-computed xv = log10(am_i / res_i) at bin=1000 (am=smoothed 2|X|/wsum, tatt=11ms/trel=80ms): + lv3:.5488 lv6:.3988 lv9:.2488 lv12:.0988 lv18:-.2012 lv24:-.5012. + NOTE: earlier al_* xv (0.631 etc.) were computed with different am normalization - ALWAYS use pipeline's. +4. Pure-LUT nodes at each xv: lut = ((1-m) - W*warp^A) / G (mask C = G*LUT + W*warp^A). +5. JOINT FIT (dual + al_*, objective=mean|err| over 6 dual tones + 6 al levels): + best: G=1.0850 W=0.2819 A=1.1377 -> al_* err <=0.19 dB ALL; dual err <=0.62 dB ALL. + The LUT leg is a SLANTED curve (~0.36 at xv=-0.5 rising to ~0.64 at xv=+0.55), NOT the flat B.12 (~0.5). +6. framed_render.py updated: LX/LY = merged anchors + al_* nodes; G/W/A = 1.0850/0.2819/1.1377. + CRITICAL BUGFIX: lut clip must be [LY.min(), LY.max()] (0.366..1.0) not LY[0] (0.4402) - node at + xv=-0.5012 (0.366) was being floored, breaking q10@2000 by 1.4 dB. + +### Final validation (framed_render.py dual): + q0.1 @500 -0.55, @2000 +0.14; q1 @500 -0.62, @2000 -0.57; q10 @500 +0.01, @2000 -0.00 + envRmse@steady: 0.64/0.04/0.71/0.78/0.11/0.11 dB. al_* lv3..24 err: +0.11~+0.19 / +0.01 / -0.02. + +### Conflict (t1k fc-scan vs al_* clif at xv=0.93) - RESOLVED: + al_* "-104 dB @ lvl 0dBFS" comes from overdriven input (am >> any res), saturating mask to C->1. + t1k 15.6 dB @ xv=0.931 was a *different* level point (soothe's own fc-scan dataset). Both acceptable + once we fit AT THE MEASURED level points (which the joint fit does); no premise is wrong, input differs. + +### Next: (1) hammer the residual -0.6 dB on dual 500Hz cases (structural); (2) multi-band combos (band>=2); (3) C++ port. + +## ============ 2026-08-19 (continuation): LEVEL-PATH DECOMPILED — FUN_180563440 + FUN_180563ce0 ============ + +### FUN_180563440 (dsp/levelpath.cpp dump, f_563440.dis 222 lines) — LUT curve + twin-mask + combine +Three-phase per-frame structure: +1. **1024-bin LUT loop**: bin k → x = clamp(k/1024, 0, 1). Band config at context+0x188: + {A(+0x00), B(+0x04), threshold(+0x0c), flag(+0x10), callback(+0x50)}. Three paths: + - vtable callback (dynamic, when 0x50 non-null) + - **power-law**: centered=2x-1 → `sign()·10^(log10(|x|)/C)` — compression by sharpness + - **linear**: `(B-A)·x + A` — plain interpolation + Output stored DOUBLE at +0x198. +2. **Twin-mask factory** FUN_18056e3e0: 6 bands × 1024 bins, stride 0x2000. +3. **Combine**: max 2 channels (stereo), 6 bands, `1 - Σ weights`. + +### FUN_180563ce0 (f_563ce0.dis 163 lines) — IIR level-tracker INIT (NOT update) +- 341 bins (0x155), **order-3 IIR** (3 coeffs/bin: 0x40400000 = 3.0 markers). +- Level coefficient: **0.1** (0x3dcccccd IEEE 754) — this is the attack/release α. +- State layout: rcx+0x28/+0x40/+0x58 (3 buffers). Init [1,0,0,0] / [-1,0,0,0]. +- **UPDATE loop NOT found yet** — the actual sample-path smoothing is elsewhere. + +### Key constants (all verified from soothing_mem.bin): +| Address | Value | Meaning | +|---|---|---| +| 0x24c3c54 | 0.0009775 | 1/1024 bin scale | +| 0x24c3ea4 | 1.0 | clamp max | +| 0x24c41e0 | 2.0 | power-law centering | +| 0x24c4680 | -1.0 | sign flip | +| 0x24c3d8c | 0.5 | threshold | +| 0x24c4334 | 4.0 | depth range (oversample os=4) | +| 0x24c43e0 | 8.6859 | 20/ln(10) dB conversion | +| 0x24c4704 | -6.9078 | ln(0.001) floor | + +### CRITICAL: The "warp" is NOT a table — computed at runtime +- `rwin_A0.npy` (live 0.5→0.8) is the **frequency WINDOW** (per-bin mask shaping), NOT the warp. +- Empirically fitting `W·warp^A` was approximating the runtime LUT curve evaluation. +- The LUT is **parametric** (linear or power-law by band flag), not a fixed lookup. +- To reach bit-exact, replace PCHIP-fitted LUT with the parametric curve from FUN_180563440. + +### Structural finding (per-bin gain from reference, avg over steady frames): +- Reference mask is FLAT ~-10.2 dB across 100-540 Hz REGARDLESS of Q (dual_b1q q0.1/1/10). +- Model produces res-shaped notch → source of the -0.6 dB residual at 500 Hz. +- **Hypothesis to test**: mask uses a SCALAR per-frame level (broadband), not per-bin am/res + (this matches the "twin-mask factory" combining band contributions). Test in /tmp/scalartest.py. + +## ============ 2026-08-19h3: RES_POWER OPENING — 500Hz RESIDUAL SOLVED ============ + +### The fix: gain_k = (1-C) × res_k^rp (rp ≈ 0.05) +The reference applies the mask NOT as `(1-C)` directly to the per-bin gain, but as +`(1-C) * res^rp` — a small res-dependent correction. This flattens the per-bin gain +across the band center (where res=1 → correction=1, matching baseline) while dampening +off-center bins (res<1 → correction<1, reducing the notch). + +### Validation (test_joint_rp2.py, multi-start Nelder-Mead, 5000 iter): +``` +BEST: G=0.9696 W=0.3503 A=1.0887 rp=0.0516 mean=0.208 (dual only, 6 pts) + q0.1@500: err=+0.00 (was -0.55) + q0.1@2000: err=+0.00 (was +0.15) + q1@500: err=-0.05 (was -0.62) + q1@2000: err=-0.41 (was -0.57) + q10@500: err=+0.57 (was +0.01) + q10@2000: err=+0.22 (was -0.00) +``` +The rp parameter SOLVES the 500Hz residual for q0.1 and q1 (the main bottleneck), +but slightly degrades q10 (the narrow-Q case). + +### Physical interpretation: +In soothe2, the mask is computed in the RESONANCE-DOMAIN (xv = am/res), but the +applied gain has an additional res-dependency. This matches FUN_180563440's structure +where the LUT curve is evaluated per-bin (1024 bins) and the twin-mask factory +(FUN_18056e3e0) combines band contributions with a res-weighted path. + +### Next steps: +1. Refine rp jointly with al_* (need faster al_* rendering — batch the 6 lv cases) +2. Update framed_render.py with rp parameter +3. C++ port of res_power term (trivial: multiply gain by pow(res, rp)) diff --git a/handoff/SESSION_HANDOFF.md b/handoff/SESSION_HANDOFF.md index 4182749..a605fa9 100644 --- a/handoff/SESSION_HANDOFF.md +++ b/handoff/SESSION_HANDOFF.md @@ -2,6 +2,52 @@ Prepared: 2026-08-18 (checkpoint end-of-session: commits c8f97e4 + 60bf3a2 pushed). Start: READ THIS FIRST. +## 0. DECOMPILATION INVENTORY (2026-08-19 — what's decoded, where, and what's missing) +Goal: bit-exact parity is gated by EXACT tables/window/constants. The chunk-level model hits +err ≤0.62 dB (dual) / ≤0.19 dB (al_*) — to go sample-exact we need precise values from the binary. + +### Static decomp assets IN REPO (use these, don't re-decompile): +- `ghidra-proj/soothe2.rep` — full Ghidra project (vst3 at ImageBase 0x180000000). +- `decomp_funs.txt` (312K lines, ~1640 functions), `fun_map.txt` (2285 addr→FUN), `consts.txt` (11602), + `decomp_dsp.txt` / `decomp_vtables.txt` / `decomp_candidates.txt` / `focus_decomp.txt`. Generators: + `Dump*.java`, `ImportRtti*.java`, `ListFuns.java`, `SearchRefs.java` (+ headless logs). +- RTTI: `rtti_dsp.json` / `rtti_full.json` — class hierarchy + `SpectralProcessor`, `Soothe2ModuleBase`, `FilterGraph`, + `DigitalFilter`, `IIRFilterExtended`, `AudioProcessingModule`. +- `handoff/nls_dasm/` — 120 hand-picked `.dis` (twin, iface_18052da00/dbc0, fft, generator, ctor). +- `dsp/` — working C++ transcription (twin, detect, freqpath, spectral, fft_stage) + harness; + `build/twin_check` passes float-parity gate (§2). + +### KEY DSP ADDRESSES — decoded / not decoded: +DECODED (formula-level, notes at NOTES_TWIN.md / NOTES_LEVEL.md): +- twin kernel `FUN_180535880`; generator `FUN_180533ec0`; caller `FUN_180536300`; dead sibling `180536f90`. +- level-weight formula `FUN_180530d30` (0x540880/884, warp 0x5406a8=0.87·x/(1+x/7.942), w=0.1^(...)). +- mask-apply entry `FUN_180529fe0` (accumulator 0x5407c8 += w·res; mask *= warp; FIR *= 0x540658). +- FFT-conv loop 0x52b550-0x52b8b5 (plan 0x540530, windows 0x540548/550/598, freq-axis 0x540698=offline const). +- level-path map: `0x563440` (LUT curve +0x188, 6 band-slots, combine→+0x2198), `0x56e3e0` (twin-mask factory), + `0x563ce0` (IIR level-tracker INIT only). + +NOT DECODED / MISSING FROM decomp_funs.txt (critical): +- `FUN_180529fe0` body — mask/fir apply; only reachable via runtime + vtable slot `180529fe0` in fun_map.txt. +- `FUN_180563440` (LUT curve + gamma + combine), `FUN_180563ce0` (IIR level-tracker UPDATE loop). + Full disasms exist ONLY in `/tmp/opencode/f_563440.dis`, `f_563ce0.dis`, `f529fe0.dis` — **/tmp is + ephemeral; COPY INTO handoff/nls_dasm/ on next session start.** +- Window `0x540658` (single indirect write — statically invisible); live-captured copies saved as + `rwin_A0/A1/B0/C0.npy` + `r_freqaxis.npy` (see NOTES_LEVEL.md §2026-08-18h3). Live data at SR=48000 + (offline renders 44100 → renormalize warp x by actual Nyquist). +- sens source: XML 12.0 → runtime sens_dB≈24.65 (host ×2) not found in dump; `IAT\*0x181bab370` outside dump. + +### Bridge model STATUS (2026-08-19): +- `framed_render.py` full STFT frame-render (N=2048, hop=512, sqrt-Hann, twin env tatt=11ms/trel=80ms): + `C(f)=G·LUT(xv)+W·warp(f)^A`, G=1.0850, W=0.2819, A=1.1377 (joint dual+al_* refit). +- Validation: dual q0.1/1/10 @500+2000 err ≤0.62 dB, envRmse@steady ≤0.78 dB; al_* lv3..24 err ≤0.19 dB. +- LUT = slanted al_*-leg (0.366@xv=-0.50 → 0.636@xv=+0.55), replaces flat B.12 (~0.5). Bugfix: clip range + must be [LY.min(), LY.max()] not [LY[0], LY[-1]]. +- Remaining structural residual: −0.6 dB systematic on dual 500Hz (q0.1/q1). Live evidence (avg per-bin + gain H=|Y|/|X|): reference mask is FLAT ~-10.2dB across 100-540Hz regardless of Q — model produces + res-shaped notch. Hypo tested: freq-smoothing of C(f) fails (kills 2000Hz). NEXT: scalar per-frame xv + (broadband level, not per-bin am/res) — see /tmp/smoothtest.py (+ edit scalar=True). + ## 1. Objective (unchanged since session 1) Transcribe the decoded soothe2 detector ("twins" 0x180535880/0x180536f90, 2nd-order resonator) into C++ and reach **bit-exact render parity** with the Reaper reference wavs in `/home/m/soothe-bt/*.wav` @@ -9,7 +55,72 @@ C++ and reach **bit-exact render parity** with the Reaper reference wavs in `/ho Path A (bit-exact) chosen. Phase 0,1,2 done. Phase 3,4 advanced. Phase 5 (render diff) is next. -## 2. PROOF OF STATE — run this first (5 min) +## 2. DECOMPILATION FINDINGS (2026-08-19 — FUN_180563440, FUN_180563ce0 decoded) + +### FUN_180563440 — LUT curve evaluation + band combine (222 lines disasm) +Structure: **3 phases per frame**: +1. **1024-bin LUT loop** (0x400 iterations): for each bin k: + - x = clamp(k * 0.0009775, 0, 1.0) = k/1024 + - Band config at +0x188: {A(+0x00), B(+0x04), threshold(+0x0c), flag(+0x10), callback(+0x50)} + - **Path 1** (callback exists): vtable call → dynamic LUT + - **Path 2** (flag=1, threshold≠1.0): **power-law** → centered = 2*x - 1, then `sign(x) * 10^(log10(|x|) / threshold)` — this is a **compression curve** controlled by sharpness/threshold + - **Path 3** (default): **linear interpolation** → `(B - A) * x + A` + - Output: double-precision at +0x198, stride 8 +2. **Twin-mask factory** (FUN_18056e3e0): 6 bands × 1024 bins, stride 0x2000 +3. **Combine loop**: stereo (max 2 channels), 6 bands, `1 - sum(band_masks)` + +### FUN_180563ce0 — IIR level-tracker INIT (163 lines disasm) +- **341 bins** (0x155 iterations), **order-3 IIR** (3 coefficients per bin) +- Coefficient: **0.1** (`0x3dcccccd` = IEEE 754 float 0.1) +- Initial state: [1.0, 0, 0, 0] and [-1.0, 0, 0, 0] (identity + zero) +- Buffer layout: 3 × (16 bytes coeff) per bin, stored at rcx+0x28/+0x40/+0x58 +- **Not the update loop** — init only; UPDATE is elsewhere + +### FUN_180529fe0 — Coefficient setup (2051 instructions, in decomp_funs.txt) +- **vtable method** on Soothe2Module +- **Lock** at +0x2404dc (atomic test-and-set) +- **PRNG state** at +0x2404e0, LCG with offset 0x3cdca +- **6-iteration coefficient generation** from 0x5408b0 buffer (LCG-indexed) +- **Depth scaling**: `powf(normalized, depth)` at +0x2c +- **Mask assembly**: normalize by 0x1a0 (NFFT), × 0x540870 (level weight), × 0x54088c (sharpness), invert +- **Copy output** via SIMD memcpy (thunk 0x181ba94b0) + +### FUN_18052e9b0 — SpectralProcessor main (3167 instructions, in decomp_funs.txt) +- **Same PRNG + coefficient setup** as FUN_180529fe0 +- **Band chain**: FUN_18052f500 (interleave) → FUN_18052ee70 (per-bin gain) → FUN_18052d650 (setup) → FUN_18052d920 (window) +- **Buffer alloc**: FUN_18052e190 for 0x540668, 0x540698, 0x5406a8, 0x5406b8-e8 (6 bands) +- **Depth scaling**: `powf(normalized, depth)` with depth at +0x2c +- **Final mask**: `1 - C` (inversion) +- **Window application**: `FIR *= 0x540658` (the live-captured window table) + +### Constants verified from binary: +| Constant | Address | Value | Meaning | +|---|---|---|---| +| SCALE | 0x24c3c54 | 0.000977517 | 1/1024 (bin→x) | +| ONE | 0x24c3ea4 | 1.0 | clamping max | +| TWO | 0x24c41e0 | 2.0 | centering (2*x-1) | +| NEG1 | 0x24c4680 | -1.0 | sign flip | +| HALF | 0x24c3d8c | 0.5 | threshold | +| DEPTH_SCALE | 0x24c4334 | 4.0 | depth range | +| DB_CONV | 0x24c43e0 | 8.6859 | 20/ln(10) | +| FLOOR | 0x24c4704 | -6.9078 | ln(0.001) | +| IIR_COEFF | embedded | 0.1 | attack/release per bin | +| IIR_ORDER | embedded | 3.0 | IIR filter order | +| LCG_OFFSET | embedded | 0x3cdca | PRNG state advance | + +### Live-captured tables (re-verified): +- `rwin_A0.npy` (0x1930100): 0.5→0.8, **frequency window** (NOT warp formula) +- `rwin_B0.npy` (0x1938180): 0→3.899, **power-law depth curve** (exponent ~0.66) +- `rwin_C0.npy` (0x19401c0): 0.596→0.126, **level-dependent weight** +- `r_freqaxis.npy`: 0→23988.3 Hz, 11.71 Hz spacing (48000/4096) + +### Key insight: The warp formula is NOT a table — it's computed at runtime +The empirical `0.87*7.942*x/(7.942+x)` is an approximation of a runtime computation +in FUN_180563440 that evaluates the LUT curve parametrically. The actual LUT has TWO modes: +- **Linear** (default): simple interpolation between A and B +- **Power-law** (flag=1): `sign(x) * 10^(log10(|x|) / C)` — compression curve + +## 3. PROOF OF STATE — run this first (5 min) Everything below must reproduce. If `twin_check` fails, the transcription moved stale. ```bash @@ -131,8 +242,13 @@ IAT\*0x181bab370 outside dump (non-blocking), final z¹ phase proof, the 0x56344 - `/home/m/re-tools/model_lut.py` — model **B.12** (Q=xmlq, gain=10^(sens/20), depth 0.8639736175537109, `C=g·LUT(xv)+w·warp^a`, g=1.221/w=0.358/a=3.143) — 0.236 dB bridge model; PCHIP LUT nodes frozen - `/home/m/re-tools/model_fir.py` — bridge canonical source (rmse 0.236, committed b1066f3) +- `/home/m/re-tools/framed_render.py` — full frame-render pilot (2026-08-19 params; modes dual|al) +- `/home/m/re-tools/rwin_A0/A1/B0/C0.npy`, `r_freqaxis.npy`, `rwin_warp.npy` — live-window tables (48k) +- `/home/m/re-tools/rtsnap.py` — live-process page snapshotter; snapshots /tmp/rt{A,B,C,D}.{raw,idx} +- `/home/m/re-tools/handoff/decode_rpp_full.py`, `handoff/rpp_allparams.py` — RPP b64-XML full decoder + (trim to len%4==0, `: + 529fe0: 48 8b c4 mov %rsp,%rax + 529fe3: 44 89 48 20 mov %r9d,0x20(%rax) + 529fe7: 48 89 50 10 mov %rdx,0x10(%rax) + 529feb: 57 push %rdi + 529fec: 48 81 ec 20 01 00 00 sub $0x120,%rsp + 529ff3: f0 0f ba a9 dc 04 24 lock btsl $0x0,0x2404dc(%rcx) + 529ffa: 00 00 + 529ffc: 45 8b d8 mov %r8d,%r11d + 529fff: 48 8b f9 mov %rcx,%rdi + 52a002: 0f 82 2d 19 00 00 jb 0x52b935 + 52a008: 48 89 58 18 mov %rbx,0x18(%rax) + 52a00c: 48 89 70 e8 mov %rsi,-0x18(%rax) + 52a010: 4c 89 60 e0 mov %r12,-0x20(%rax) + 52a014: 4c 89 78 c8 mov %r15,-0x38(%rax) + 52a018: 44 0f 29 40 98 movaps %xmm8,-0x68(%rax) + 52a01d: 44 0f 29 48 88 movaps %xmm9,-0x78(%rax) + 52a022: 44 0f 29 90 78 ff ff movaps %xmm10,-0x88(%rax) + 52a029: ff + 52a02a: 44 0f 29 98 68 ff ff movaps %xmm11,-0x98(%rax) + 52a031: ff + 52a032: 44 0f 29 a0 58 ff ff movaps %xmm12,-0xa8(%rax) + 52a039: ff + 52a03a: 8b 81 e0 04 24 00 mov 0x2404e0(%rcx),%eax + 52a040: 05 ca cd 03 00 add $0x3cdca,%eax + 52a045: 44 0f 29 6c 24 70 movaps %xmm13,0x70(%rsp) + 52a04b: 25 7f 00 00 80 and $0x8000007f,%eax + 52a050: 7d 07 jge 0x52a059 + 52a052: ff c8 dec %eax + 52a054: 83 c8 80 or $0xffffff80,%eax + 52a057: ff c0 inc %eax + 52a059: 89 81 e0 04 24 00 mov %eax,0x2404e0(%rcx) + 52a05f: 48 63 c8 movslq %eax,%rcx + 52a062: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a069: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a06e: 8b 05 90 16 10 02 mov 0x2101690(%rip),%eax # 0x262b704 + 52a074: 66 0f 6e e8 movd %eax,%xmm5 + 52a078: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a07e: ff c0 inc %eax + 52a080: 48 63 c8 movslq %eax,%rcx + 52a083: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a08a: 0f 5b ed cvtdq2ps %xmm5,%xmm5 + 52a08d: f3 0f 59 e8 mulss %xmm0,%xmm5 + 52a091: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a096: 8b 05 2c 15 10 02 mov 0x210152c(%rip),%eax # 0x262b5c8 + 52a09c: 66 0f 6e d8 movd %eax,%xmm3 + 52a0a0: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a0a6: 0f 5b db cvtdq2ps %xmm3,%xmm3 + 52a0a9: 05 36 02 14 00 add $0x140236,%eax + 52a0ae: f3 0f 59 d8 mulss %xmm0,%xmm3 + 52a0b2: 25 7f 00 00 80 and $0x8000007f,%eax + 52a0b7: 7d 07 jge 0x52a0c0 + 52a0b9: ff c8 dec %eax + 52a0bb: 83 c8 80 or $0xffffff80,%eax + 52a0be: ff c0 inc %eax + 52a0c0: f3 0f 10 25 90 9b f9 movss 0x1f99b90(%rip),%xmm4 # 0x24c3c58 + 52a0c7: 01 + 52a0c8: 89 87 e0 04 24 00 mov %eax,0x2404e0(%rdi) + 52a0ce: 48 63 c8 movslq %eax,%rcx + 52a0d1: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a0d8: f3 0f 59 dd mulss %xmm5,%xmm3 + 52a0dc: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a0e1: 8b 05 1d 16 10 02 mov 0x210161d(%rip),%eax # 0x262b704 + 52a0e7: f3 0f 58 dc addss %xmm4,%xmm3 + 52a0eb: 66 0f 6e d0 movd %eax,%xmm2 + 52a0ef: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a0f5: ff c0 inc %eax + 52a0f7: 48 63 c8 movslq %eax,%rcx + 52a0fa: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a101: 0f 5b d2 cvtdq2ps %xmm2,%xmm2 + 52a104: f3 44 0f 2c e3 cvttss2si %xmm3,%r12d + 52a109: f3 0f 59 d0 mulss %xmm0,%xmm2 + 52a10d: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a112: 8b 05 b0 14 10 02 mov 0x21014b0(%rip),%eax # 0x262b5c8 + 52a118: 66 0f 6e c8 movd %eax,%xmm1 + 52a11c: 8b 05 de 15 10 02 mov 0x21015de(%rip),%eax # 0x262b700 + 52a122: 0f 5b c9 cvtdq2ps %xmm1,%xmm1 + 52a125: f3 0f 59 c8 mulss %xmm0,%xmm1 + 52a129: f3 0f 59 ca mulss %xmm2,%xmm1 + 52a12d: f3 0f 58 cc addss %xmm4,%xmm1 + 52a131: f3 0f 2c c9 cvttss2si %xmm1,%ecx + 52a135: 0f af c8 imul %eax,%ecx + 52a138: 8b 05 c2 15 10 02 mov 0x21015c2(%rip),%eax # 0x262b700 + 52a13e: 44 0f af e0 imul %eax,%r12d + 52a142: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a148: 05 56 0d 01 00 add $0x10d56,%eax + 52a14d: 44 2b e1 sub %ecx,%r12d + 52a150: 44 89 a4 24 30 01 00 mov %r12d,0x130(%rsp) + 52a157: 00 + 52a158: 25 7f 00 00 80 and $0x8000007f,%eax + 52a15d: 7d 07 jge 0x52a166 + 52a15f: ff c8 dec %eax + 52a161: 83 c8 80 or $0xffffff80,%eax + 52a164: ff c0 inc %eax + 52a166: 89 87 e0 04 24 00 mov %eax,0x2404e0(%rdi) + 52a16c: 48 63 c8 movslq %eax,%rcx + 52a16f: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a176: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a17b: 8b 05 83 15 10 02 mov 0x2101583(%rip),%eax # 0x262b704 + 52a181: 66 0f 6e d0 movd %eax,%xmm2 + 52a185: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a18b: ff c0 inc %eax + 52a18d: 48 63 c8 movslq %eax,%rcx + 52a190: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a197: 0f 5b d2 cvtdq2ps %xmm2,%xmm2 + 52a19a: f3 0f 59 d0 mulss %xmm0,%xmm2 + 52a19e: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a1a3: 8b 05 1f 14 10 02 mov 0x210141f(%rip),%eax # 0x262b5c8 + 52a1a9: 66 0f 6e c8 movd %eax,%xmm1 + 52a1ad: 8b 05 4d 15 10 02 mov 0x210154d(%rip),%eax # 0x262b700 + 52a1b3: 0f 5b c9 cvtdq2ps %xmm1,%xmm1 + 52a1b6: f3 0f 59 c8 mulss %xmm0,%xmm1 + 52a1ba: f3 0f 59 ca mulss %xmm2,%xmm1 + 52a1be: f3 0f 58 cc addss %xmm4,%xmm1 + 52a1c2: f3 44 0f 2c c1 cvttss2si %xmm1,%r8d + 52a1c7: 44 0f af c0 imul %eax,%r8d + 52a1cb: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a1d1: 05 b6 f6 0d 00 add $0xdf6b6,%eax + 52a1d6: 25 7f 00 00 80 and $0x8000007f,%eax + 52a1db: 7d 07 jge 0x52a1e4 + 52a1dd: ff c8 dec %eax + 52a1df: 83 c8 80 or $0xffffff80,%eax + 52a1e2: ff c0 inc %eax + 52a1e4: 89 87 e0 04 24 00 mov %eax,0x2404e0(%rdi) + 52a1ea: 48 63 c8 movslq %eax,%rcx + 52a1ed: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a1f4: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a1f9: 8b 05 05 15 10 02 mov 0x2101505(%rip),%eax # 0x262b704 + 52a1ff: 66 0f 6e d0 movd %eax,%xmm2 + 52a203: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a209: ff c0 inc %eax + 52a20b: 48 63 c8 movslq %eax,%rcx + 52a20e: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a215: 0f 5b d2 cvtdq2ps %xmm2,%xmm2 + 52a218: f3 0f 59 d0 mulss %xmm0,%xmm2 + 52a21c: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a221: 8b 05 a1 13 10 02 mov 0x21013a1(%rip),%eax # 0x262b5c8 + 52a227: 66 0f 6e c8 movd %eax,%xmm1 + 52a22b: 8b 05 cf 14 10 02 mov 0x21014cf(%rip),%eax # 0x262b700 + 52a231: 0f 5b c9 cvtdq2ps %xmm1,%xmm1 + 52a234: f3 0f 59 c8 mulss %xmm0,%xmm1 + 52a238: f3 0f 59 ca mulss %xmm2,%xmm1 + 52a23c: f3 0f 58 cc addss %xmm4,%xmm1 + 52a240: f3 0f 2c c9 cvttss2si %xmm1,%ecx + 52a244: 0f af c8 imul %eax,%ecx + 52a247: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a24d: 05 5e 8c 0a 00 add $0xa8c5e,%eax + 52a252: 66 44 0f 6e d9 movd %ecx,%xmm11 + 52a257: 45 0f 5b db cvtdq2ps %xmm11,%xmm11 + 52a25b: 25 7f 00 00 80 and $0x8000007f,%eax + 52a260: 7d 07 jge 0x52a269 + 52a262: ff c8 dec %eax + 52a264: 83 c8 80 or $0xffffff80,%eax + 52a267: ff c0 inc %eax + 52a269: 89 87 e0 04 24 00 mov %eax,0x2404e0(%rdi) + 52a26f: 48 63 c8 movslq %eax,%rcx + 52a272: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a279: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a27e: 8b 05 80 14 10 02 mov 0x2101480(%rip),%eax # 0x262b704 + 52a284: 66 0f 6e e8 movd %eax,%xmm5 + 52a288: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a28e: ff c0 inc %eax + 52a290: 48 63 c8 movslq %eax,%rcx + 52a293: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a29a: 0f 5b ed cvtdq2ps %xmm5,%xmm5 + 52a29d: f3 0f 59 e8 mulss %xmm0,%xmm5 + 52a2a1: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a2a6: 8b 05 1c 13 10 02 mov 0x210131c(%rip),%eax # 0x262b5c8 + 52a2ac: 66 0f 6e d8 movd %eax,%xmm3 + 52a2b0: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a2b6: 0f 5b db cvtdq2ps %xmm3,%xmm3 + 52a2b9: 05 16 29 07 00 add $0x72916,%eax + 52a2be: f3 0f 59 d8 mulss %xmm0,%xmm3 + 52a2c2: 25 7f 00 00 80 and $0x8000007f,%eax + 52a2c7: 7d 07 jge 0x52a2d0 + 52a2c9: ff c8 dec %eax + 52a2cb: 83 c8 80 or $0xffffff80,%eax + 52a2ce: ff c0 inc %eax + 52a2d0: f3 44 0f 10 2d 07 9f movss 0x1f99f07(%rip),%xmm13 # 0x24c41e0 + 52a2d7: f9 01 + 52a2d9: 89 87 e0 04 24 00 mov %eax,0x2404e0(%rdi) + 52a2df: 48 63 c8 movslq %eax,%rcx + 52a2e2: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a2e9: 48 89 ac 24 18 01 00 mov %rbp,0x118(%rsp) + 52a2f0: 00 + 52a2f1: f3 0f 59 dd mulss %xmm5,%xmm3 + 52a2f5: 4c 89 ac 24 00 01 00 mov %r13,0x100(%rsp) + 52a2fc: 00 + 52a2fd: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a302: 8b 05 fc 13 10 02 mov 0x21013fc(%rip),%eax # 0x262b704 + 52a308: f3 0f 58 dc addss %xmm4,%xmm3 + 52a30c: 4c 89 b4 24 f8 00 00 mov %r14,0xf8(%rsp) + 52a313: 00 + 52a314: 49 63 d9 movslq %r9d,%rbx + 52a317: 0f 29 b4 24 e0 00 00 movaps %xmm6,0xe0(%rsp) + 52a31e: 00 + 52a31f: 66 0f 6e d0 movd %eax,%xmm2 + 52a323: 8b 87 e0 04 24 00 mov 0x2404e0(%rdi),%eax + 52a329: ff c0 inc %eax + 52a32b: 0f 29 bc 24 d0 00 00 movaps %xmm7,0xd0(%rsp) + 52a332: 00 + 52a333: 48 63 c8 movslq %eax,%rcx + 52a336: 48 8b 87 b0 08 54 00 mov 0x5408b0(%rdi),%rax + 52a33d: 0f 5b d2 cvtdq2ps %xmm2,%xmm2 + 52a340: 48 89 5c 24 30 mov %rbx,0x30(%rsp) + 52a345: f3 0f 59 d0 mulss %xmm0,%xmm2 + 52a349: f3 0f 10 04 88 movss (%rax,%rcx,4),%xmm0 + 52a34e: 8b 05 74 12 10 02 mov 0x2101274(%rip),%eax # 0x262b5c8 + 52a354: f3 0f 2c cb cvttss2si %xmm3,%ecx + 52a358: 66 0f 6e c8 movd %eax,%xmm1 + 52a35c: 8b 05 9e 13 10 02 mov 0x210139e(%rip),%eax # 0x262b700 + 52a362: 0f 5b c9 cvtdq2ps %xmm1,%xmm1 + 52a365: f3 0f 59 c8 mulss %xmm0,%xmm1 + 52a369: f3 0f 59 ca mulss %xmm2,%xmm1 + 52a36d: f3 0f 58 cc addss %xmm4,%xmm1 + 52a371: f3 0f 2c d1 cvttss2si %xmm1,%edx + 52a375: 0f af d0 imul %eax,%edx + 52a378: 8b 05 82 13 10 02 mov 0x2101382(%rip),%eax # 0x262b700 + 52a37e: 0f af c8 imul %eax,%ecx + 52a381: 41 8b c3 mov %r11d,%eax + 52a384: 03 ca add %edx,%ecx + 52a386: 99 cltd + 52a387: f7 f9 idiv %ecx + 52a389: 41 8d 34 00 lea (%r8,%rax,1),%esi + 52a38d: 41 83 f9 01 cmp $0x1,%r9d + 52a391: 0f 8e 64 01 00 00 jle 0x52a4fb + 52a397: 4d 63 ec movslq %r12d,%r13 + 52a39a: 4c 8d b7 78 06 54 00 lea 0x540678(%rdi),%r14 + 52a3a1: 49 8b cd mov %r13,%rcx + 52a3a4: 44 8b c6 mov %esi,%r8d + 52a3a7: 48 c1 e1 04 shl $0x4,%rcx + 52a3ab: 4c 03 f1 add %rcx,%r14 + 52a3ae: 48 8b 8f f8 06 54 00 mov 0x5406f8(%rdi),%rcx + 52a3b5: 49 8b 16 mov (%r14),%rdx + 52a3b8: e8 03 38 00 00 call 0x52dbc0 + 52a3bd: 48 83 fb 01 cmp $0x1,%rbx + 52a3c1: 7e 5e jle 0x52a421 + 52a3c3: 4c 8d bf 88 06 54 00 lea 0x540688(%rdi),%r15 + 52a3ca: 4c 8d 63 ff lea -0x1(%rbx),%r12 + 52a3ce: 66 90 xchg %ax,%ax + 52a3d0: 49 8b 2f mov (%r15),%rbp + 52a3d3: 48 8d 15 de 69 12 02 lea 0x21269de(%rip),%rdx # 0x2650db8 + 52a3da: 48 8b 9f f8 06 54 00 mov 0x5406f8(%rdi),%rbx + 52a3e1: 48 8d 0d d0 69 12 02 lea 0x21269d0(%rip),%rcx # 0x2650db8 + 52a3e8: ff 15 1a 0c 68 01 call *0x1680c1a(%rip) # 0x1bab008 + 52a3ee: 44 8b ce mov %esi,%r9d + 52a3f1: 4c 8b c3 mov %rbx,%r8 + 52a3f4: 48 8b d5 mov %rbp,%rdx + 52a3f7: 48 8b cb mov %rbx,%rcx + 52a3fa: 85 c0 test %eax,%eax + 52a3fc: 75 07 jne 0x52a405 + 52a3fe: e8 ed 7c ad ff call 0x20f0 + 52a403: eb 05 jmp 0x52a40a + 52a405: e8 46 74 ad ff call 0x1850 + 52a40a: 49 83 c7 10 add $0x10,%r15 + 52a40e: 49 83 ec 01 sub $0x1,%r12 + 52a412: 75 bc jne 0x52a3d0 + 52a414: 44 8b a4 24 30 01 00 mov 0x130(%rsp),%r12d + 52a41b: 00 + 52a41c: 48 8b 5c 24 30 mov 0x30(%rsp),%rbx + 52a421: 66 0f 6e 84 24 48 01 movd 0x148(%rsp),%xmm0 + 52a428: 00 00 + 52a42a: 41 0f 28 cb movaps %xmm11,%xmm1 + 52a42e: 48 8b 8f f8 06 54 00 mov 0x5406f8(%rdi),%rcx + 52a435: 44 8b c6 mov %esi,%r8d + 52a438: 0f 5b c0 cvtdq2ps %xmm0,%xmm0 + 52a43b: f3 0f 5e c8 divss %xmm0,%xmm1 + 52a43f: e8 dc 34 00 00 call 0x52d920 + 52a444: f3 0f 10 47 2c movss 0x2c(%rdi),%xmm0 + 52a449: 41 0f 28 cd movaps %xmm13,%xmm1 + 52a44d: e8 8a a8 4e 01 call 0x1a14cdc + 52a452: 0f 28 f8 movaps %xmm0,%xmm7 + 52a455: 4c 3b eb cmp %rbx,%r13 + 52a458: 0f 8d 9d 00 00 00 jge 0x52a4fb + 52a45e: 41 0f 28 f3 movaps %xmm11,%xmm6 + 52a462: 4c 8b fb mov %rbx,%r15 + 52a465: f3 0f 5c f7 subss %xmm7,%xmm6 + 52a469: 4d 2b fd sub %r13,%r15 + 52a46c: 0f 1f 40 00 nopl 0x0(%rax) + 52a470: 49 8b 1e mov (%r14),%rbx + 52a473: 48 8d 15 3e 69 12 02 lea 0x212693e(%rip),%rdx # 0x2650db8 + 52a47a: 48 8d 0d 37 69 12 02 lea 0x2126937(%rip),%rcx # 0x2650db8 + 52a481: ff 15 81 0b 68 01 call *0x1680b81(%rip) # 0x1bab008 + 52a487: 44 8b c6 mov %esi,%r8d + 52a48a: 48 8b d3 mov %rbx,%rdx + 52a48d: 85 c0 test %eax,%eax + 52a48f: 75 0a jne 0x52a49b + 52a491: 0f 28 c6 movaps %xmm6,%xmm0 + 52a494: e8 97 7b ad ff call 0x2030 + 52a499: eb 0c jmp 0x52a4a7 + 52a49b: 0f 57 c0 xorps %xmm0,%xmm0 + 52a49e: f3 0f 5a c6 cvtss2sd %xmm6,%xmm0 + 52a4a2: e8 89 78 ad ff call 0x1d30 + 52a4a7: 48 8b 9f f8 06 54 00 mov 0x5406f8(%rdi),%rbx + 52a4ae: 48 8d 15 03 69 12 02 lea 0x2126903(%rip),%rdx # 0x2650db8 + 52a4b5: 49 8b 2e mov (%r14),%rbp + 52a4b8: 48 8d 0d f9 68 12 02 lea 0x21268f9(%rip),%rcx # 0x2650db8 + 52a4bf: ff 15 43 0b 68 01 call *0x1680b43(%rip) # 0x1bab008 + 52a4c5: 44 8b ce mov %esi,%r9d + 52a4c8: 4c 8b c5 mov %rbp,%r8 + 52a4cb: 48 8b cb mov %rbx,%rcx + 52a4ce: 85 c0 test %eax,%eax + 52a4d0: 75 0a jne 0x52a4dc + 52a4d2: 0f 28 cf movaps %xmm7,%xmm1 + 52a4d5: e8 f6 7a ad ff call 0x1fd0 + 52a4da: eb 0c jmp 0x52a4e8 + 52a4dc: 0f 57 c9 xorps %xmm1,%xmm1 + 52a4df: f3 0f 5a cf cvtss2sd %xmm7,%xmm1 + 52a4e3: e8 68 7c ad ff call 0x2150 + 52a4e8: 49 83 c6 10 add $0x10,%r14 + 52a4ec: 49 83 ef 01 sub $0x1,%r15 + 52a4f0: 0f 85 7a ff ff ff jne 0x52a470 + 52a4f6: 48 8b 5c 24 30 mov 0x30(%rsp),%rbx + 52a4fb: 66 0f 6e 87 a0 01 00 movd 0x1a0(%rdi),%xmm0 + 52a502: 00 + 52a503: 45 33 ff xor %r15d,%r15d + 52a506: f3 44 0f 10 25 95 99 movss 0x1f99995(%rip),%xmm12 # 0x24c3ea4 + 52a50d: f9 01 + 52a50f: 45 0f 57 c9 xorps %xmm9,%xmm9 + 52a513: f3 44 0f 10 15 64 a1 movss 0x1f9a164(%rip),%xmm10 # 0x24c4680 + 52a51a: f9 01 + 52a51c: f2 44 0f 10 05 1b 9c movsd 0x1f99c1b(%rip),%xmm8 # 0x24c4140 + 52a523: f9 01 + 52a525: 4d 63 e4 movslq %r12d,%r12 + 52a528: 4c 89 64 24 38 mov %r12,0x38(%rsp) + 52a52d: 49 8b c4 mov %r12,%rax + 52a530: 48 89 84 24 30 01 00 mov %rax,0x130(%rsp) + 52a537: 00 + 52a538: 0f 5b c0 cvtdq2ps %xmm0,%xmm0 + 52a53b: f3 44 0f 5e d8 divss %xmm0,%xmm11 + 52a540: 4c 3b e3 cmp %rbx,%r12 + 52a543: 0f 8d a7 0e 00 00 jge 0x52b3f0 + 52a549: f3 44 0f 10 15 d6 98 movss 0x1f998d6(%rip),%xmm10 # 0x24c3e28 + 52a550: f9 01 + 52a552: 4c 8d a7 18 05 44 00 lea 0x440518(%rdi),%r12 + 52a559: f2 44 0f 10 2d 3e a1 movsd 0x1f9a13e(%rip),%xmm13 # 0x24c46a0 + 52a560: f9 01 + 52a562: 44 0f 29 74 24 60 movaps %xmm14,0x60(%rsp) + 52a568: f3 44 0f 10 35 03 a1 movss 0x1f9a103(%rip),%xmm14 # 0x24c4674 + 52a56f: f9 01 + 52a571: 44 0f 29 7c 24 50 movaps %xmm15,0x50(%rsp) + 52a577: f3 44 0f 10 3d f0 a0 movss 0x1f9a0f0(%rip),%xmm15 # 0x24c4670 + 52a57e: f9 01 + 52a580: 4c 8b e8 mov %rax,%r13 + 52a583: 41 0f 28 fb movaps %xmm11,%xmm7 + 52a587: f3 0f 59 bf 70 08 54 mulss 0x540870(%rdi),%xmm7 + 52a58e: 00 + 52a58f: 4d 03 ed add %r13,%r13 + 52a592: 80 bf b8 08 54 00 00 cmpb $0x0,0x5408b8(%rdi) + 52a599: 4a 8b 84 ef 68 07 54 mov 0x540768(%rdi,%r13,8),%rax + 52a5a0: 00 + 52a5a1: 48 89 44 24 40 mov %rax,0x40(%rsp) + 52a5a6: 74 19 je 0x52a5c1 + 52a5a8: 0f 57 c0 xorps %xmm0,%xmm0 + 52a5ab: e8 f6 a6 4e 01 call 0x1a14ca6 + 52a5b0: f2 0f 2c c0 cvttsd2si %xmm0,%eax + 52a5b4: 66 0f 6e f0 movd %eax,%xmm6 + 52a5b8: 0f 5b f6 cvtdq2ps %xmm6,%xmm6 + 52a5bb: f3 0f 59 f7 mulss %xmm7,%xmm6 + 52a5bf: eb 03 jmp 0x52a5c4 + 52a5c1: 0f 28 f7 movaps %xmm7,%xmm6 + 52a5c4: f3 0f 59 b7 8c 08 54 mulss 0x54088c(%rdi),%xmm6 + 52a5cb: 00 + 52a5cc: 48 8d 15 e5 67 12 02 lea 0x21267e5(%rip),%rdx # 0x2650db8 + 52a5d3: 4a 8b 9c ef 78 06 54 mov 0x540678(%rdi,%r13,8),%rbx + 52a5da: 00 + 52a5db: 48 8d 0d d6 67 12 02 lea 0x21267d6(%rip),%rcx # 0x2650db8 + 52a5e2: ff 15 20 0a 68 01 call *0x1680a20(%rip) # 0x1bab008 + 52a5e8: 44 8b c6 mov %esi,%r8d + 52a5eb: 48 8b d3 mov %rbx,%rdx + 52a5ee: 85 c0 test %eax,%eax + 52a5f0: 75 0a jne 0x52a5fc + 52a5f2: 0f 28 c6 movaps %xmm6,%xmm0 + 52a5f5: e8 36 7a ad ff call 0x2030 + 52a5fa: eb 0c jmp 0x52a608 + 52a5fc: 0f 57 c0 xorps %xmm0,%xmm0 + 52a5ff: f3 0f 5a c6 cvtss2sd %xmm6,%xmm0 + 52a603: e8 28 77 ad ff call 0x1d30 + 52a608: 80 bf b8 08 54 00 00 cmpb $0x0,0x5408b8(%rdi) + 52a60f: 74 35 je 0x52a646 + 52a611: 4a 8b 9c ef 78 06 54 mov 0x540678(%rdi,%r13,8),%rbx + 52a618: 00 + 52a619: 48 8d 15 98 67 12 02 lea 0x2126798(%rip),%rdx # 0x2650db8 + 52a620: 48 8d 0d 91 67 12 02 lea 0x2126791(%rip),%rcx # 0x2650db8 + 52a627: ff 15 db 09 68 01 call *0x16809db(%rip) # 0x1bab008 + 52a62d: 44 8b c6 mov %esi,%r8d + 52a630: 48 8b d3 mov %rbx,%rdx + 52a633: 48 8b cb mov %rbx,%rcx + 52a636: 85 c0 test %eax,%eax + 52a638: 75 07 jne 0x52a641 + 52a63a: e8 41 63 c1 ff call 0x140980 + 52a63f: eb 05 jmp 0x52a646 + 52a641: e8 6a 63 c1 ff call 0x1409b0 + 52a646: 4e 8b 84 ef 78 06 54 mov 0x540678(%rdi,%r13,8),%r8 + 52a64d: 00 + 52a64e: 49 8b cc mov %r12,%rcx + 52a651: 48 8b 97 f8 06 54 00 mov 0x5406f8(%rdi),%rdx + 52a658: e8 f3 2f 00 00 call 0x52d650 + 52a65d: 80 bf b8 08 54 00 00 cmpb $0x0,0x5408b8(%rdi) + 52a664: 0f 84 f1 01 00 00 je 0x52a85b + 52a66a: 41 83 3c 24 00 cmpl $0x0,(%r12) + 52a66f: 41 8b d7 mov %r15d,%edx + 52a672: 4c 8b 87 f8 06 54 00 mov 0x5406f8(%rdi),%r8 + 52a679: 4d 89 bc 24 10 00 10 mov %r15,0x100010(%r12) + 52a680: 00 + 52a681: 7e 50 jle 0x52a6d3 + 52a683: 49 8b c0 mov %r8,%rax + 52a686: 49 8d 8c 24 10 00 08 lea 0x80010(%r12),%rcx + 52a68d: 00 + 52a68e: 66 90 xchg %ax,%ax + 52a690: f3 0f 10 08 movss (%rax),%xmm1 + 52a694: ff c2 inc %edx + 52a696: f2 41 0f 10 84 24 10 movsd 0x100010(%r12),%xmm0 + 52a69d: 00 10 00 + 52a6a0: f2 0f 59 01 mulsd (%rcx),%xmm0 + 52a6a4: 0f 5a c9 cvtps2pd %xmm1,%xmm1 + 52a6a7: f2 0f 59 89 00 00 f8 mulsd -0x80000(%rcx),%xmm1 + 52a6ae: ff + 52a6af: 48 83 c1 08 add $0x8,%rcx + 52a6b3: f2 0f 58 c8 addsd %xmm0,%xmm1 + 52a6b7: f2 41 0f 11 8c 24 10 movsd %xmm1,0x100010(%r12) + 52a6be: 00 10 00 + 52a6c1: 66 0f 5a c1 cvtpd2ps %xmm1,%xmm0 + 52a6c5: f3 0f 11 00 movss %xmm0,(%rax) + 52a6c9: 48 83 c0 04 add $0x4,%rax + 52a6cd: 41 3b 14 24 cmp (%r12),%edx + 52a6d1: 7c bd jl 0x52a690 + 52a6d3: 41 8b 04 24 mov (%r12),%eax + 52a6d7: 83 e8 02 sub $0x2,%eax + 52a6da: 48 63 c8 movslq %eax,%rcx + 52a6dd: 48 83 f9 04 cmp $0x4,%rcx + 52a6e1: 0f 8c 20 01 00 00 jl 0x52a807 + 52a6e7: 48 8d 51 fc lea -0x4(%rcx),%rdx + 52a6eb: 48 c1 ea 02 shr $0x2,%rdx + 52a6ef: 4d 8d 48 f8 lea -0x8(%r8),%r9 + 52a6f3: 48 ff c2 inc %rdx + 52a6f6: 4d 8d 94 24 10 00 08 lea 0x80010(%r12),%r10 + 52a6fd: 00 + 52a6fe: 48 8b c2 mov %rdx,%rax + 52a701: 4d 8d 0c 89 lea (%r9,%rcx,4),%r9 + 52a705: 48 f7 d8 neg %rax + 52a708: 4d 8d 14 ca lea (%r10,%rcx,8),%r10 + 52a70c: 48 8d 0c 81 lea (%rcx,%rax,4),%rcx + 52a710: f2 41 0f 10 02 movsd (%r10),%xmm0 + 52a715: f2 41 0f 59 84 24 10 mulsd 0x100010(%r12),%xmm0 + 52a71c: 00 10 00 + 52a71f: f3 41 0f 10 49 08 movss 0x8(%r9),%xmm1 + 52a725: 0f 5a c9 cvtps2pd %xmm1,%xmm1 + 52a728: f2 41 0f 59 8a 00 00 mulsd -0x80000(%r10),%xmm1 + 52a72f: f8 ff + 52a731: f2 0f 58 c8 addsd %xmm0,%xmm1 + 52a735: f2 41 0f 11 8c 24 10 movsd %xmm1,0x100010(%r12) + 52a73c: 00 10 00 + 52a73f: 66 0f 5a c1 cvtpd2ps %xmm1,%xmm0 + 52a743: f3 41 0f 11 41 08 movss %xmm0,0x8(%r9) + 52a749: f2 41 0f 10 42 f8 movsd -0x8(%r10),%xmm0 + 52a74f: f2 41 0f 59 84 24 10 mulsd 0x100010(%r12),%xmm0 + 52a756: 00 10 00 + 52a759: f3 41 0f 10 49 04 movss 0x4(%r9),%xmm1 + 52a75f: 0f 5a c9 cvtps2pd %xmm1,%xmm1 + 52a762: f2 41 0f 59 8a f8 ff mulsd -0x80008(%r10),%xmm1 + 52a769: f7 ff + 52a76b: f2 0f 58 c8 addsd %xmm0,%xmm1 + 52a76f: f2 41 0f 11 8c 24 10 movsd %xmm1,0x100010(%r12) + 52a776: 00 10 00 + 52a779: 66 0f 5a c1 cvtpd2ps %xmm1,%xmm0 + 52a77d: f3 41 0f 11 41 04 movss %xmm0,0x4(%r9) + 52a783: f2 41 0f 10 42 f0 movsd -0x10(%r10),%xmm0 + 52a789: f2 41 0f 59 84 24 10 mulsd 0x100010(%r12),%xmm0 + 52a790: 00 10 00 + 52a793: f3 41 0f 10 11 movss (%r9),%xmm2 + 52a798: 0f 5a d2 cvtps2pd %xmm2,%xmm2 + 52a79b: f2 41 0f 59 92 f0 ff mulsd -0x80010(%r10),%xmm2 + 52a7a2: f7 ff + 52a7a4: f2 0f 58 d0 addsd %xmm0,%xmm2 + 52a7a8: f2 41 0f 11 94 24 10 movsd %xmm2,0x100010(%r12) + 52a7af: 00 10 00 + 52a7b2: 66 0f 5a c2 cvtpd2ps %xmm2,%xmm0 + 52a7b6: f3 41 0f 11 01 movss %xmm0,(%r9) + 52a7bb: f2 41 0f 10 42 e8 movsd -0x18(%r10),%xmm0 + 52a7c1: f3 41 0f 10 49 fc movss -0x4(%r9),%xmm1 + 52a7c7: f2 41 0f 59 84 24 10 mulsd 0x100010(%r12),%xmm0 + 52a7ce: 00 10 00 + 52a7d1: 0f 5a c9 cvtps2pd %xmm1,%xmm1 + 52a7d4: f2 41 0f 59 8a e8 ff mulsd -0x80018(%r10),%xmm1 + 52a7db: f7 ff + 52a7dd: 49 83 ea 20 sub $0x20,%r10 + 52a7e1: f2 0f 58 c8 addsd %xmm0,%xmm1 + 52a7e5: 66 0f 5a c1 cvtpd2ps %xmm1,%xmm0 + 52a7e9: f2 41 0f 11 8c 24 10 movsd %xmm1,0x100010(%r12) + 52a7f0: 00 10 00 + 52a7f3: f3 41 0f 11 41 fc movss %xmm0,-0x4(%r9) + 52a7f9: 49 83 e9 10 sub $0x10,%r9 + 52a7fd: 48 83 ea 01 sub $0x1,%rdx + 52a801: 0f 85 09 ff ff ff jne 0x52a710 + 52a807: 48 85 c9 test %rcx,%rcx + 52a80a: 7e 4f jle 0x52a85b + 52a80c: 49 8d 84 24 10 00 08 lea 0x80010(%r12),%rax + 52a813: diff --git a/handoff/nls_dasm/f_563440.dis b/handoff/nls_dasm/f_563440.dis new file mode 100644 index 0000000..2592538 --- /dev/null +++ b/handoff/nls_dasm/f_563440.dis @@ -0,0 +1,222 @@ + +soothe_mem.bin: file format binary + + +Disassembly of section .data: + +0000000000563440 <.data+0x563440>: + 563440: 48 8b c4 mov %rsp,%rax + 563443: 53 push %rbx + 563444: 55 push %rbp + 563445: 56 push %rsi + 563446: 57 push %rdi + 563447: 41 54 push %r12 + 563449: 41 55 push %r13 + 56344b: 41 56 push %r14 + 56344d: 41 57 push %r15 + 56344f: 48 81 ec f8 00 00 00 sub $0xf8,%rsp + 563456: 48 c7 44 24 40 fe ff movq $0xfffffffffffffffe,0x40(%rsp) + 56345d: ff ff + 56345f: 0f 29 70 a8 movaps %xmm6,-0x58(%rax) + 563463: 0f 29 78 98 movaps %xmm7,-0x68(%rax) + 563467: 44 0f 29 40 88 movaps %xmm8,-0x78(%rax) + 56346c: 44 0f 29 88 78 ff ff movaps %xmm9,-0x88(%rax) + 563473: ff + 563474: 44 0f 29 90 68 ff ff movaps %xmm10,-0x98(%rax) + 56347b: ff + 56347c: 44 0f 29 98 58 ff ff movaps %xmm11,-0xa8(%rax) + 563483: ff + 563484: 44 0f 29 a0 48 ff ff movaps %xmm12,-0xb8(%rax) + 56348b: ff + 56348c: 44 0f 29 6c 24 70 movaps %xmm13,0x70(%rsp) + 563492: 44 0f 29 74 24 60 movaps %xmm14,0x60(%rsp) + 563498: 44 0f 29 7c 24 50 movaps %xmm15,0x50(%rsp) + 56349e: 4c 8b e9 mov %rcx,%r13 + 5634a1: 48 81 c1 98 00 00 00 add $0x98,%rcx + 5634a8: 48 8b 41 08 mov 0x8(%rcx),%rax + 5634ac: 48 2b 01 sub (%rcx),%rax + 5634af: 48 c1 f8 03 sar $0x3,%rax + 5634b3: 48 85 c0 test %rax,%rax + 5634b6: 75 0a jne 0x5634c2 + 5634b8: ba 00 08 00 00 mov $0x800,%edx + 5634bd: e8 7e 91 00 00 call 0x56c640 + 5634c2: 41 80 bd 90 00 00 00 cmpb $0x0,0x90(%r13) + 5634c9: 00 + 5634ca: 0f 84 3e 05 00 00 je 0x563a0e + 5634d0: 33 ff xor %edi,%edi + 5634d2: 49 8d b5 98 01 00 00 lea 0x198(%r13),%rsi + 5634d9: f3 44 0f 10 35 72 07 movss 0x1f60772(%rip),%xmm14 # 0x24c3c54 + 5634e0: f6 01 + 5634e2: 45 0f 57 c9 xorps %xmm9,%xmm9 + 5634e6: f3 44 0f 10 05 b5 09 movss 0x1f609b5(%rip),%xmm8 # 0x24c3ea4 + 5634ed: f6 01 + 5634ef: f3 44 0f 10 15 e8 0c movss 0x1f60ce8(%rip),%xmm10 # 0x24c41e0 + 5634f6: f6 01 + 5634f8: f3 44 0f 10 1d 7f 11 movss 0x1f6117f(%rip),%xmm11 # 0x24c4680 + 5634ff: f6 01 + 563501: f3 44 0f 10 3d 82 08 movss 0x1f60882(%rip),%xmm15 # 0x24c3d8c + 563508: f6 01 + 56350a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 563510: 66 0f 6e c7 movd %edi,%xmm0 + 563514: 0f 5b c0 cvtdq2ps %xmm0,%xmm0 + 563517: f3 41 0f 59 c6 mulss %xmm14,%xmm0 + 56351c: 49 8b 9d 88 01 00 00 mov 0x188(%r13),%rbx + 563523: 44 0f 2f c8 comiss %xmm0,%xmm9 + 563527: 76 06 jbe 0x56352f + 563529: 41 0f 28 d1 movaps %xmm9,%xmm2 + 56352d: eb 08 jmp 0x563537 + 56352f: 41 0f 28 d0 movaps %xmm8,%xmm2 + 563533: f3 0f 5d d0 minss %xmm0,%xmm2 + 563537: 48 83 7b 50 00 cmpq $0x0,0x50(%rbx) + 56353c: 74 57 je 0x563595 + 56353e: f3 0f 11 94 24 40 01 movss %xmm2,0x140(%rsp) + 563545: 00 00 + 563547: f3 0f 10 43 04 movss 0x4(%rbx),%xmm0 + 56354c: f3 0f 11 84 24 48 01 movss %xmm0,0x148(%rsp) + 563553: 00 00 + 563555: f3 0f 10 0b movss (%rbx),%xmm1 + 563559: f3 0f 11 8c 24 50 01 movss %xmm1,0x150(%rsp) + 563560: 00 00 + 563562: 48 8b 4b 50 mov 0x50(%rbx),%rcx + 563566: 48 85 c9 test %rcx,%rcx + 563569: 0f 84 20 01 00 00 je 0x56368f + 56356f: 48 8b 01 mov (%rcx),%rax + 563572: 4c 8d 8c 24 40 01 00 lea 0x140(%rsp),%r9 + 563579: 00 + 56357a: 4c 8d 84 24 48 01 00 lea 0x148(%rsp),%r8 + 563581: 00 + 563582: 48 8d 94 24 50 01 00 lea 0x150(%rsp),%rdx + 563589: 00 + 56358a: ff 50 10 call *0x10(%rax) + 56358d: 0f 28 d8 movaps %xmm0,%xmm3 + 563590: e9 a9 00 00 00 jmp 0x56363e + 563595: 80 7b 10 00 cmpb $0x0,0x10(%rbx) + 563599: 75 32 jne 0x5635cd + 56359b: f3 0f 10 73 0c movss 0xc(%rbx),%xmm6 + 5635a0: 41 0f 2e f0 ucomiss %xmm8,%xmm6 + 5635a4: 7a 02 jp 0x5635a8 + 5635a6: 74 1a je 0x5635c2 + 5635a8: 41 0f 2f d1 comiss %xmm9,%xmm2 + 5635ac: 76 14 jbe 0x5635c2 + 5635ae: 0f 28 c2 movaps %xmm2,%xmm0 + 5635b1: e8 1a 17 4b 01 call 0x1a14cd0 + 5635b6: f3 0f 5e c6 divss %xmm6,%xmm0 + 5635ba: e8 ed 16 4b 01 call 0x1a14cac + 5635bf: 0f 28 d0 movaps %xmm0,%xmm2 + 5635c2: f3 0f 10 5b 04 movss 0x4(%rbx),%xmm3 + 5635c7: f3 0f 5c 1b subss (%rbx),%xmm3 + 5635cb: eb 69 jmp 0x563636 + 5635cd: f3 41 0f 59 d2 mulss %xmm10,%xmm2 + 5635d2: f3 41 0f 5c d0 subss %xmm8,%xmm2 + 5635d7: f3 0f 10 7b 0c movss 0xc(%rbx),%xmm7 + 5635dc: 41 0f 2e f8 ucomiss %xmm8,%xmm7 + 5635e0: 7a 02 jp 0x5635e4 + 5635e2: 74 3f je 0x563623 + 5635e4: 41 0f 2e d1 ucomiss %xmm9,%xmm2 + 5635e8: 7a 02 jp 0x5635ec + 5635ea: 74 37 je 0x563623 + 5635ec: 44 0f 2f ca comiss %xmm2,%xmm9 + 5635f0: 76 06 jbe 0x5635f8 + 5635f2: 41 0f 28 f3 movaps %xmm11,%xmm6 + 5635f6: eb 04 jmp 0x5635fc + 5635f8: 41 0f 28 f0 movaps %xmm8,%xmm6 + 5635fc: 0f 57 c0 xorps %xmm0,%xmm0 + 5635ff: f3 0f 5a c2 cvtss2sd %xmm2,%xmm0 + 563603: 0f 54 05 06 19 f6 01 andps 0x1f61906(%rip),%xmm0 # 0x24c4f10 + 56360a: 66 0f 5a c0 cvtpd2ps %xmm0,%xmm0 + 56360e: e8 bd 16 4b 01 call 0x1a14cd0 + 563613: f3 0f 5e c7 divss %xmm7,%xmm0 + 563617: e8 90 16 4b 01 call 0x1a14cac + 56361c: 0f 28 d0 movaps %xmm0,%xmm2 + 56361f: f3 0f 59 d6 mulss %xmm6,%xmm2 + 563623: f3 0f 10 5b 04 movss 0x4(%rbx),%xmm3 + 563628: f3 0f 5c 1b subss (%rbx),%xmm3 + 56362c: f3 41 0f 59 df mulss %xmm15,%xmm3 + 563631: f3 41 0f 58 d0 addss %xmm8,%xmm2 + 563636: f3 0f 59 da mulss %xmm2,%xmm3 + 56363a: f3 0f 58 1b addss (%rbx),%xmm3 + 56363e: 0f 57 c0 xorps %xmm0,%xmm0 + 563641: f3 0f 5a c3 cvtss2sd %xmm3,%xmm0 + 563645: f2 0f 11 06 movsd %xmm0,(%rsi) + 563649: ff c7 inc %edi + 56364b: 48 83 c6 08 add $0x8,%rsi + 56364f: 81 ff 00 04 00 00 cmp $0x400,%edi + 563655: 0f 8c b5 fe ff ff jl 0x563510 + 56365b: 33 db xor %ebx,%ebx + 56365d: 4d 8d b5 98 01 01 00 lea 0x10198(%r13),%r14 + 563664: 33 ff xor %edi,%edi + 563666: 49 8d b5 98 41 00 00 lea 0x4198(%r13),%rsi + 56366d: 0f 1f 00 nopl (%rax) + 563670: 49 8b 8d 78 01 00 00 mov 0x178(%r13),%rcx + 563677: 48 83 c1 18 add $0x18,%rcx + 56367b: 3b 59 6c cmp 0x6c(%rcx),%ebx + 56367e: 0f 92 c0 setb %al + 563681: 84 c0 test %al,%al + 563683: 74 11 je 0x563696 + 563685: 48 8b 41 60 mov 0x60(%rcx),%rax + 563689: 4c 8b 0c 07 mov (%rdi,%rax,1),%r9 + 56368d: eb 0a jmp 0x563699 + 56368f: ff 15 a3 73 64 01 call *0x16473a3(%rip) # 0x1baaa38 + 563695: 90 nop + 563696: 45 33 c9 xor %r9d,%r9d + 563699: 4c 89 74 24 30 mov %r14,0x30(%rsp) + 56369e: 4d 8d 85 98 01 00 00 lea 0x198(%r13),%r8 + 5636a5: 48 8b d6 mov %rsi,%rdx + 5636a8: e8 33 ad 00 00 call 0x56e3e0 + 5636ad: ff c3 inc %ebx + 5636af: 48 81 c6 00 20 00 00 add $0x2000,%rsi + 5636b6: 48 83 c7 08 add $0x8,%rdi + 5636ba: 83 fb 06 cmp $0x6,%ebx + 5636bd: 7c b1 jl 0x563670 + 5636bf: 49 8b cd mov %r13,%rcx + 5636c2: e8 99 03 00 00 call 0x563a60 + 5636c7: 49 8b 9d 78 01 00 00 mov 0x178(%r13),%rbx + 5636ce: 48 81 c3 d8 00 24 00 add $0x2400d8,%rbx + 5636d5: 48 89 9c 24 58 01 00 mov %rbx,0x158(%rsp) + 5636dc: 00 + 5636dd: 49 8b 85 70 01 00 00 mov 0x170(%r13),%rax + 5636e4: 48 8b 80 68 01 00 00 mov 0x168(%rax),%rax + 5636eb: 8b 48 30 mov 0x30(%rax),%ecx + 5636ee: b8 02 00 00 00 mov $0x2,%eax + 5636f3: 3b c8 cmp %eax,%ecx + 5636f5: 0f 4f c8 cmovg %eax,%ecx + 5636f8: 45 33 ff xor %r15d,%r15d + 5636fb: 4c 63 e1 movslq %ecx,%r12 + 5636fe: 85 c9 test %ecx,%ecx + 563700: 0f 8e 08 03 00 00 jle 0x563a0e + 563706: 49 8d ad 98 21 00 00 lea 0x2198(%r13),%rbp + 56370d: f2 44 0f 10 2d 2a 0a movsd 0x1f60a2a(%rip),%xmm13 # 0x24c4140 + 563714: f6 01 + 563716: f3 44 0f 10 25 c1 0c movss 0x1f60cc1(%rip),%xmm12 # 0x24c43e0 + 56371d: f6 01 + 56371f: 90 nop + 563720: 48 8d 15 91 d6 0e 02 lea 0x20ed691(%rip),%rdx # 0x2650db8 + 563727: 48 8d 0d 5a d3 0e 02 lea 0x20ed35a(%rip),%rcx # 0x2650a88 + 56372e: ff 15 d4 78 64 01 call *0x16478d4(%rip) # 0x1bab008 + 563734: 41 b8 00 04 00 00 mov $0x400,%r8d + 56373a: 48 8b d5 mov %rbp,%rdx + 56373d: 85 c0 test %eax,%eax + 56373f: 75 0b jne 0x56374c + 563741: 41 0f 28 c0 movaps %xmm8,%xmm0 + 563745: e8 56 e2 a9 ff call 0x19a0 + 56374a: eb 09 jmp 0x563755 + 56374c: 41 0f 28 c5 movaps %xmm13,%xmm0 + 563750: e8 7b eb a9 ff call 0x22d0 + 563755: 48 8b fb mov %rbx,%rdi + 563758: 49 8d 9d 98 41 00 00 lea 0x4198(%r13),%rbx + 56375f: be 06 00 00 00 mov $0x6,%esi + 563764: 49 83 fc 02 cmp $0x2,%r12 + 563768: 0f 85 c9 00 00 00 jne 0x563837 + 56376e: 4d 85 ff test %r15,%r15 + 563771: 75 0a jne 0x56377d + 563773: 41 0f 28 f0 movaps %xmm8,%xmm6 + 563777: f3 0f 5c 37 subss (%rdi),%xmm6 + 56377b: eb 04 jmp 0x563781 + 56377d: f3 0f 10 37 movss (%rdi),%xmm6 + 563781: f3 41 0f 59 f2 mulss %xmm10,%xmm6 + 563786: f3 41 0f 5d f0 minss %xmm8,%xmm6 + 56378b: 41 0f 28 c0 movaps %xmm8,%xmm0 + 56378f: f3 0f 5c c6 subss %xmm6,%xmm0 + 563793: 0f 57 ff xorps %xmm7,%xmm7 + 563796: f3 0f 5a f8 cvtss2sd %xmm0,%xmm7 + 56379a: 48 8d 15 17 d6 lea 0x20ed617(%rip),%rdx # 0x2650db8 diff --git a/handoff/nls_dasm/f_563ce0.dis b/handoff/nls_dasm/f_563ce0.dis new file mode 100644 index 0000000..17b7ccf --- /dev/null +++ b/handoff/nls_dasm/f_563ce0.dis @@ -0,0 +1,163 @@ + +soothe_mem.bin: file format binary + + +Disassembly of section .data: + +0000000000563ce0 <.data+0x563ce0>: + 563ce0: 48 83 ec 28 sub $0x28,%rsp + 563ce4: 48 8b 81 a0 00 00 00 mov 0xa0(%rcx),%rax + 563ceb: 48 2b 81 98 00 00 00 sub 0x98(%rcx),%rax + 563cf2: 48 a9 f8 ff ff ff test $0xfffffffffffffff8,%rax + 563cf8: 0f 84 96 02 00 00 je 0x563f94 + 563cfe: 0f 28 05 7b 0a f6 01 movaps 0x1f60a7b(%rip),%xmm0 # 0x24c4780 + 563d05: 41 b9 55 01 00 00 mov $0x155,%r9d + 563d0b: 0f 28 2d 7e 0a f6 01 movaps 0x1f60a7e(%rip),%xmm5 # 0x24c4790 + 563d12: 45 8b d1 mov %r9d,%r10d + 563d15: 0f 11 04 24 movups %xmm0,(%rsp) + 563d19: ba 30 00 00 00 mov $0x30,%edx + 563d1e: 41 b8 0c 00 00 00 mov $0xc,%r8d + 563d24: 0f 11 6c 24 10 movups %xmm5,0x10(%rsp) + 563d29: 0f 57 db xorps %xmm3,%xmm3 + 563d2c: 0f 57 e4 xorps %xmm4,%xmm4 + 563d2f: 0f 57 c9 xorps %xmm1,%xmm1 + 563d32: 0f 57 d2 xorps %xmm2,%xmm2 + 563d35: 66 66 66 0f 1f 84 00 data16 data16 nopw 0x0(%rax,%rax,1) + 563d3c: 00 00 00 00 + 563d40: 48 8b 41 28 mov 0x28(%rcx),%rax + 563d44: 48 8d 52 60 lea 0x60(%rdx),%rdx + 563d48: 4d 8d 40 18 lea 0x18(%r8),%r8 + 563d4c: 41 c7 44 00 dc 00 00 movl $0x40400000,-0x24(%r8,%rax,1) + 563d53: 40 40 + 563d55: 48 8b 41 40 mov 0x40(%rcx),%rax + 563d59: 0f 11 9c 10 70 ff ff movups %xmm3,-0x90(%rax,%rdx,1) + 563d60: ff + 563d61: 48 8b 41 58 mov 0x58(%rcx),%rax + 563d65: 0f 11 84 10 70 ff ff movups %xmm0,-0x90(%rax,%rdx,1) + 563d6c: ff + 563d6d: 48 8b 41 28 mov 0x28(%rcx),%rax + 563d71: 41 c7 44 00 e0 00 00 movl $0x40400000,-0x20(%r8,%rax,1) + 563d78: 40 40 + 563d7a: 48 8b 41 40 mov 0x40(%rcx),%rax + 563d7e: 0f 11 64 10 80 movups %xmm4,-0x80(%rax,%rdx,1) + 563d83: 48 8b 41 58 mov 0x58(%rcx),%rax + 563d87: 0f 11 6c 10 80 movups %xmm5,-0x80(%rax,%rdx,1) + 563d8c: 48 8b 41 28 mov 0x28(%rcx),%rax + 563d90: 41 c7 44 00 e4 00 00 movl $0x40400000,-0x1c(%r8,%rax,1) + 563d97: 40 40 + 563d99: 48 8b 41 40 mov 0x40(%rcx),%rax + 563d9d: 0f 11 5c 10 90 movups %xmm3,-0x70(%rax,%rdx,1) + 563da2: 48 8b 41 58 mov 0x58(%rcx),%rax + 563da6: 0f 11 44 10 90 movups %xmm0,-0x70(%rax,%rdx,1) + 563dab: 48 8b 41 28 mov 0x28(%rcx),%rax + 563daf: 41 c7 44 00 e8 00 00 movl $0x40400000,-0x18(%r8,%rax,1) + 563db6: 40 40 + 563db8: 48 8b 41 40 mov 0x40(%rcx),%rax + 563dbc: 0f 11 64 10 a0 movups %xmm4,-0x60(%rax,%rdx,1) + 563dc1: 48 8b 41 58 mov 0x58(%rcx),%rax + 563dc5: 0f 11 6c 10 a0 movups %xmm5,-0x60(%rax,%rdx,1) + 563dca: 48 8b 41 28 mov 0x28(%rcx),%rax + 563dce: 41 c7 44 00 ec 00 00 movl $0x40400000,-0x14(%r8,%rax,1) + 563dd5: 40 40 + 563dd7: 48 8b 41 40 mov 0x40(%rcx),%rax + 563ddb: 0f 11 5c 10 b0 movups %xmm3,-0x50(%rax,%rdx,1) + 563de0: 48 8b 41 58 mov 0x58(%rcx),%rax + 563de4: 0f 11 44 10 b0 movups %xmm0,-0x50(%rax,%rdx,1) + 563de9: 48 8b 41 28 mov 0x28(%rcx),%rax + 563ded: 41 c7 44 00 f0 00 00 movl $0x40400000,-0x10(%r8,%rax,1) + 563df4: 40 40 + 563df6: 48 8b 41 40 mov 0x40(%rcx),%rax + 563dfa: 0f 11 64 10 c0 movups %xmm4,-0x40(%rax,%rdx,1) + 563dff: 48 8b 41 58 mov 0x58(%rcx),%rax + 563e03: 0f 11 6c 10 c0 movups %xmm5,-0x40(%rax,%rdx,1) + 563e08: 49 83 ea 01 sub $0x1,%r10 + 563e0c: 0f 85 2e ff ff ff jne 0x563d40 + 563e12: c7 44 24 04 00 00 80 movl $0x3f800000,0x4(%rsp) + 563e19: 3f + 563e1a: ba 10 80 00 00 mov $0x8010,%edx + 563e1f: 0f 10 04 24 movups (%rsp),%xmm0 + 563e23: c7 44 24 14 00 00 80 movl $0x3f800000,0x14(%rsp) + 563e2a: 3f + 563e2b: 41 b8 04 20 00 00 mov $0x2004,%r8d + 563e31: 0f 10 6c 24 10 movups 0x10(%rsp),%xmm5 + 563e36: 66 66 0f 1f 84 00 00 data16 nopw 0x0(%rax,%rax,1) + 563e3d: 00 00 00 + 563e40: 48 8b 41 28 mov 0x28(%rcx),%rax + 563e44: 48 8d 52 60 lea 0x60(%rdx),%rdx + 563e48: 4d 8d 40 18 lea 0x18(%r8),%r8 + 563e4c: 41 c7 44 00 dc 00 00 movl $0x40400000,-0x24(%r8,%rax,1) + 563e53: 40 40 + 563e55: 48 8b 41 40 mov 0x40(%rcx),%rax + 563e59: 0f 11 9c 10 70 ff ff movups %xmm3,-0x90(%rax,%rdx,1) + 563e60: ff + 563e61: 48 8b 41 58 mov 0x58(%rcx),%rax + 563e65: 0f 11 84 10 70 ff ff movups %xmm0,-0x90(%rax,%rdx,1) + 563e6c: ff + 563e6d: 48 8b 41 28 mov 0x28(%rcx),%rax + 563e71: 42 c7 44 00 e0 00 00 movl $0x40400000,-0x20(%rax,%r8,1) + 563e78: 40 40 + 563e7a: 48 8b 41 40 mov 0x40(%rcx),%rax + 563e7e: 0f 11 64 10 80 movups %xmm4,-0x80(%rax,%rdx,1) + 563e83: 48 8b 41 58 mov 0x58(%rcx),%rax + 563e87: 0f 11 6c 10 80 movups %xmm5,-0x80(%rax,%rdx,1) + 563e8c: 48 8b 41 28 mov 0x28(%rcx),%rax + 563e90: 41 c7 44 00 e4 00 00 movl $0x40400000,-0x1c(%r8,%rax,1) + 563e97: 40 40 + 563e99: 48 8b 41 40 mov 0x40(%rcx),%rax + 563e9d: 0f 11 5c 10 90 movups %xmm3,-0x70(%rax,%rdx,1) + 563ea2: 48 8b 41 58 mov 0x58(%rcx),%rax + 563ea6: 0f 11 44 10 90 movups %xmm0,-0x70(%rax,%rdx,1) + 563eab: 48 8b 41 28 mov 0x28(%rcx),%rax + 563eaf: 41 c7 44 00 e8 00 00 movl $0x40400000,-0x18(%r8,%rax,1) + 563eb6: 40 40 + 563eb8: 48 8b 41 40 mov 0x40(%rcx),%rax + 563ebc: 0f 11 64 02 a0 movups %xmm4,-0x60(%rdx,%rax,1) + 563ec1: 48 8b 41 58 mov 0x58(%rcx),%rax + 563ec5: 0f 11 6c 02 a0 movups %xmm5,-0x60(%rdx,%rax,1) + 563eca: 48 8b 41 28 mov 0x28(%rcx),%rax + 563ece: 41 c7 44 00 ec 00 00 movl $0x40400000,-0x14(%r8,%rax,1) + 563ed5: 40 40 + 563ed7: 48 8b 41 40 mov 0x40(%rcx),%rax + 563edb: 0f 11 5c 10 b0 movups %xmm3,-0x50(%rax,%rdx,1) + 563ee0: 48 8b 41 58 mov 0x58(%rcx),%rax + 563ee4: 0f 11 44 10 b0 movups %xmm0,-0x50(%rax,%rdx,1) + 563ee9: 48 8b 41 28 mov 0x28(%rcx),%rax + 563eed: 41 c7 44 00 f0 00 00 movl $0x40400000,-0x10(%r8,%rax,1) + 563ef4: 40 40 + 563ef6: 48 8b 41 40 mov 0x40(%rcx),%rax + 563efa: 0f 11 64 10 c0 movups %xmm4,-0x40(%rax,%rdx,1) + 563eff: 48 8b 41 58 mov 0x58(%rcx),%rax + 563f03: 0f 11 6c 10 c0 movups %xmm5,-0x40(%rax,%rdx,1) + 563f08: 49 83 e9 01 sub $0x1,%r9 + 563f0c: 0f 85 2e ff ff ff jne 0x563e40 + 563f12: ba d0 ff 00 00 mov $0xffd0,%edx + 563f17: 41 b8 f4 3f 00 00 mov $0x3ff4,%r8d + 563f1d: 0f 1f 00 nopl (%rax) + 563f20: 48 8b 41 28 mov 0x28(%rcx),%rax + 563f24: 48 8d 52 30 lea 0x30(%rdx),%rdx + 563f28: 42 c7 44 00 fc 00 00 movl $0x40e00000,-0x4(%rax,%r8,1) + 563f2f: e0 40 + 563f31: 48 8b 41 40 mov 0x40(%rcx),%rax + 563f35: 0f 11 4c 10 c0 movups %xmm1,-0x40(%rax,%rdx,1) + 563f3a: 48 8b 41 58 mov 0x58(%rcx),%rax + 563f3e: 0f 11 54 10 c0 movups %xmm2,-0x40(%rax,%rdx,1) + 563f43: 48 8b 41 28 mov 0x28(%rcx),%rax + 563f47: 41 c7 04 00 00 00 e0 movl $0x40e00000,(%r8,%rax,1) + 563f4e: 40 + 563f4f: 48 8b 41 40 mov 0x40(%rcx),%rax + 563f53: 0f 11 4c 10 d0 movups %xmm1,-0x30(%rax,%rdx,1) + 563f58: 48 8b 41 58 mov 0x58(%rcx),%rax + 563f5c: 0f 11 54 10 d0 movups %xmm2,-0x30(%rax,%rdx,1) + 563f61: 48 8b 41 28 mov 0x28(%rcx),%rax + 563f65: 42 c7 44 00 04 00 00 movl $0x40e00000,0x4(%rax,%r8,1) + 563f6c: e0 40 + 563f6e: 49 83 c0 0c add $0xc,%r8 + 563f72: 48 8b 41 40 mov 0x40(%rcx),%rax + 563f76: 0f 11 4c 10 e0 movups %xmm1,-0x20(%rax,%rdx,1) + 563f7b: 48 8b 41 58 mov 0x58(%rcx),%rax + 563f7f: 0f 11 54 10 e0 movups %xmm2,-0x20(%rax,%rdx,1) + 563f84: 49 81 f8 f0 4f 00 00 cmp $0x4ff0,%r8 + 563f8b: 7c 93 jl 0x563f20 + 563f8d: c6 81 91 00 00 00 01 movb $0x1,0x91(%rcx) + 563f94: 48 83 c4 28 add $0x28,%rsp + 563f98: c3 ret diff --git a/handoff/test_parametric_lut.py b/handoff/test_parametric_lut.py new file mode 100644 index 0000000..44a4c1d --- /dev/null +++ b/handoff/test_parametric_lut.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +import sys, numpy as np +sys.path.insert(0, '/home/m/re-tools') +from render_parity import load +from scipy.optimize import minimize +import wave + +BT='/home/m/soothe-bt/'; FS=44100.0; GAIN=4.132 + +def bandres(f, fc, Q): + w0 = fc*2*np.pi/FS; c,s=np.cos(w0),np.sin(w0) + p=(s*0.5)/Q; a,a2=p*GAIN,p/GAIN + A=[a+1,-2*c,1-a]; B=[a2+1,-2*c,1-a2] + w=2*np.pi*np.asarray(f)/FS; z=np.exp(-1j*w) + return np.abs(2.0*(B[0]+B[1]*z+B[2]*z*z)/(A[0]+A[1]*z+A[2]*z*z)) + +def warp(f): x=np.asarray(f)/2000.0; return 0.87*7.942*x/(7.942+x) + +def lut_powerlaw(xv, C, A=0.0, B=1.0): + """FUN_180563440 power-law mode: centered=2*x-1, result=sign*10^(log10|/C)""" + x = np.clip(xv, A, B) + centered = 2.0 * (x - A) / (B - A) - 1.0 # map [A,B] → [-1,1] + abs_c = np.abs(centered) + result = np.where(abs_c > 1e-9, + np.sign(centered) * np.power(10.0, np.log10(np.maximum(abs_c, 1e-9)) / C), + 0.0) + return (result + 1.0) / 2.0 # remap [-1,1] → [0,1] + +def lut_linear(xv, A=0.483, B=0.717): + """Linear mode: (B-A)*x+A""" + return np.clip(A + (B - A) * np.clip(xv, 0, 1), 0, 1) + +def frames(x, fc, Q, G_, W_, A_, C_lut=10.0, mode='powerlaw', NS=2048, hop=512, tatt=0.011, trel=0.08): + win=np.sqrt(np.hanning(NS)); wsum=win.sum(); n=len(x) + nfr=max(1,int(np.ceil((n-NS)/hop))+1) + X=np.empty((nfr,NS//2+1),dtype=complex); freqs=np.fft.rfftfreq(NS,1/FS) + res=bandres(freqs,fc,Q) + att=np.exp(-hop/(tatt*FS)); rel=np.exp(-hop/(trel*FS)) + am=np.zeros(freqs.size); G=np.empty(X.shape) + for m in range(nfr): + s=m*hop; seg=np.zeros(NS); kk=min(NS,n-s); seg[:kk]=x[s:s+kk] + F=np.fft.rfft(win*seg); X[m]=F; ac=2*np.abs(F)/wsum + am=np.where(ac>am, att*am+(1-att)*ac, rel*am+(1-rel)*ac) + xv=np.log10(np.maximum(am/np.maximum(res,1e-12),1e-9)) + if mode=='powerlaw': + L = lut_powerlaw(xv, C_lut) + else: + L = lut_linear(xv) + C = G_*L + W_*warp(freqs)**A_ + G[m] = np.maximum(1-np.minimum(C,0.95),1e-9) + return X,G,win,hop,n + +def synthe(X,G,win,hop,n): + out=np.zeros(n); acc=np.zeros(n); NS=len(win) + for m in range(X.shape[0]): + seg=np.fft.irfft(X[m]*G[m])*win; s=m*hop; lay=min(NS,n-s) + out[s:s+lay]+=seg[:lay]; acc[s:s+lay]+=(win*win)[:lay] + return out/np.maximum(acc,1e-12) + +def tone_cmp(x,f,seglen=0.75*FS): + x=np.asarray(x)[-int(seglen):]; n=len(x); t=np.arange(n)/FS; w=2*np.pi*f + return np.hypot(2*np.sum(x*np.cos(w*t))/n,2*np.sum(x*np.sin(w*t))/n) + +def dB(v): return 20*np.log10(np.clip(v,1e-9,None)) + +x=np.mean(load(BT+'dual.wav'),axis=1) +refs=[(q,f'dual_b1q_{q}.wav',f) for q in [0.1,1.0,10.0] for f in (500,2000)] +tone_ref={(r,f):dB(tone_cmp(np.mean(load(BT+r),axis=1),f)) for _,r,f in refs} + +def score(GWA, C_lut, mode): + G_,W_,A_=GWA; tot=[] + for q,ref,f in refs: + X,G,win,hop,n=frames(x,500.0,q,G_,W_,A_,C_lut,mode) + y=synthe(X,G,win,hop,n); tot.append(dB(tone_cmp(y,f))-tone_ref[(ref,f)]) + return np.array(tot) + +# Test power-law mode with different C values +print("=== POWER-LAW MODE ===") +for C in [2.0, 3.0, 5.0, 8.0, 10.0, 15.0, 20.0]: + def obj(p): + return np.mean(np.abs(score(p, C, 'powerlaw'))) + r = minimize(obj, [1.0, 0.3, 1.0], method='Nelder-Mead', options=dict(maxiter=500)) + err = score(r.x, C, 'powerlaw') + print(f' C={C:5.1f} G={r.x[0]:.3f} W={r.x[1]:.3f} A={r.x[2]:.3f} mean={np.mean(np.abs(err)):.3f} ' + f'errs=[{",".join(f"{e:+.2f}" for e in err)}]') + +# Also test linear mode +print("=== LINEAR MODE ===") +def obj_lin(p): + return np.mean(np.abs(score(p, 0, 'linear'))) +r = minimize(obj_lin, [1.0, 0.3, 1.0], method='Nelder-Mead', options=dict(maxiter=500)) +err = score(r.x, 0, 'linear') +print(f' G={r.x[0]:.3f} W={r.x[1]:.3f} A={r.x[2]:.3f} mean={np.mean(np.abs(err)):.3f} ' + f'errs=[{",".join(f"{e:+.2f}" for e in err)}]') diff --git a/handoff/test_res_power.py b/handoff/test_res_power.py new file mode 100644 index 0000000..b56db8f --- /dev/null +++ b/handoff/test_res_power.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +import sys, numpy as np +sys.path.insert(0, '/home/m/re-tools') +from render_parity import load +from scipy.interpolate import PchipInterpolator +from scipy.optimize import minimize +import wave + +BT='/home/m/soothe-bt/'; FS=44100.0; GAIN=4.132 + +def bandres(f, fc, Q): + w0 = fc*2*np.pi/FS; c,s=np.cos(w0),np.sin(w0) + p=(s*0.5)/Q; a,a2=p*GAIN,p/GAIN + A=[a+1,-2*c,1-a]; B=[a2+1,-2*c,1-a2] + w=2*np.pi*np.asarray(f)/FS; z=np.exp(-1j*w) + return np.abs(2.0*(B[0]+B[1]*z+B[2]*z*z)/(A[0]+A[1]*z+A[2]*z*z)) + +def warp(f): x=np.asarray(f)/2000.0; return 0.87*7.942*x/(7.942+x) + +LX = np.array([-0.75,-0.5012,-0.5,-0.2012,0.0988,0.2488,0.3988,0.5488,0.574,0.61,0.75,1.0]) +LY = np.array([0.4402,0.366,0.4552,0.459,0.541,0.576,0.608,0.636,0.5645,0.6471,0.6562,0.6670]) +_ip=PchipInterpolator(LX,LY); _lymin,_lymax=LY.min(),LY.max() +def lut(x): return np.clip(_ip(np.asarray(x)),_lymin,_lymax) + +def frames(x, fc, Q, G_, W_, A_, rp, NS=2048, hop=512, tatt=0.011, trel=0.08): + win=np.sqrt(np.hanning(NS)); wsum=win.sum(); n=len(x) + nfr=max(1,int(np.ceil((n-NS)/hop))+1) + X=np.empty((nfr,NS//2+1),dtype=complex); freqs=np.fft.rfftfreq(NS,1/FS) + res=bandres(freqs,fc,Q) + att=np.exp(-hop/(tatt*FS)); rel=np.exp(-hop/(trel*FS)) + am=np.zeros(freqs.size); G=np.empty(X.shape) + for m in range(nfr): + s=m*hop; seg=np.zeros(NS); kk=min(NS,n-s); seg[:kk]=x[s:s+kk] + F=np.fft.rfft(win*seg); X[m]=F; ac=2*np.abs(F)/wsum + am=np.where(ac>am, att*am+(1-att)*ac, rel*am+(1-rel)*ac) + xv=np.log10(np.maximum(am/np.maximum(res,1e-12),1e-9)) + C = G_*lut(xv) + W_*warp(freqs)**A_ + gain = np.maximum(1-np.minimum(C,0.95),1e-9) + gain = gain * np.power(np.maximum(res,1e-12), rp) + G[m] = gain + return X,G,win,hop,n + +def synthe(X,G,win,hop,n): + out=np.zeros(n); acc=np.zeros(n); NS=len(win) + for m in range(X.shape[0]): + seg=np.fft.irfft(X[m]*G[m])*win; s=m*hop; lay=min(NS,n-s) + out[s:s+lay]+=seg[:lay]; acc[s:s+lay]+=(win*win)[:lay] + return out/np.maximum(acc,1e-12) + +def tone_cmp(x,f,seglen=0.75*FS): + x=np.asarray(x)[-int(seglen):]; n=len(x); t=np.arange(n)/FS; w=2*np.pi*f + return np.hypot(2*np.sum(x*np.cos(w*t))/n,2*np.sum(x*np.sin(w*t))/n) + +def dB(v): return 20*np.log10(np.clip(v,1e-9,None)) + +x=np.mean(load(BT+'dual.wav'),axis=1) +refs=[(q,f'dual_b1q_{q}.wav',f) for q in [0.1,1.0,10.0] for f in (500,2000)] +tone_ref={(r,f):dB(tone_cmp(np.mean(load(BT+r),axis=1),f)) for _,r,f in refs} + +# Joint fit: G,W,A,rp with G>0 constraint via log transform +def obj(logp): + lG,W_,A_,rp = logp; G_=np.exp(lG) + tot=[] + for q,ref,f in refs: + X,G,win,hop,n=frames(x,500.0,q,G_,W_,A_,rp) + y=synthe(X,G,win,hop,n); tot.append(dB(tone_cmp(y,f))-tone_ref[(ref,f)]) + return np.mean(np.abs(tot)) + +best=(999,None) +for p0 in [np.log([1.0,0.3,1.0,0.1]), np.log([0.8,0.4,1.5,0.2]), np.log([0.6,0.5,2.0,0.3])]: + r = minimize(obj, p0, method='Nelder-Mead', options=dict(maxiter=5000, xatol=1e-6, fatol=1e-6)) + if r.fun < best[0]: best=(r.fun, r.x) + +p=best[1]; G_=np.exp(p[0]) +print(f'BEST: G={G_:.4f} W={p[1]:.4f} A={p[2]:.4f} rp={p[3]:.4f} mean={best[0]:.3f}') +for q,ref,f in refs: + X,G,win,hop,n=frames(x,500.0,q,G_,p[1],p[2],p[3]) + y=synthe(X,G,win,hop,n) + print(f' {ref} tone{f}: err={dB(tone_cmp(y,f))-tone_ref[(ref,f)]:+.2f}') + +# al_* validation with this model +print('\nal_*:') +for lv in [3,6,9,12,18,24]: + xi=np.mean(np.frombuffer(open(f'{BT}lvl_tone_lv{lv}.wav','rb').read(),dtype=np.int16).astype(float).reshape(-1,1)/32768.0,axis=1) + xo=np.mean(load(f'{BT}al_{lv}.wav'),axis=1) + X,G,win,hop,n=frames(xi,1000.0,0.9999978,G_,p[1],p[2],p[3]) + y=synthe(X,G,win,hop,n) + mr=dB(tone_cmp(xo,1000))-dB(tone_cmp(xi,1000)) + mo=dB(tone_cmp(y,1000))-dB(tone_cmp(xi,1000)) + print(f' lv{lv}: ref={mr:+.2f} out={mo:+.2f} err={mo-mr:+.2f}') \ No newline at end of file