From 70cafc170004dd76c9edf28cadf97f5c5da1140b Mon Sep 17 00:00:00 2001 From: Matiq Date: Sun, 23 Aug 2026 22:27:13 +0300 Subject: [PATCH] =?UTF-8?q?23f:=20live=20scratch=20series=20across=20q=20s?= =?UTF-8?q?weep=20(11=20configs)=20=E2=80=94=20center=20strictly=20constan?= =?UTF-8?q?t=20over=20q,=20x1.805=20hits=20real=20cuts=20within=200.14dB?= =?UTF-8?q?=20at=20both=20known=20points,=20scr171(res)=20nonlinear=20cons?= =?UTF-8?q?istent=20with=2022x=20exponent;=20detector=20smoothing=20locate?= =?UTF-8?q?d=20between=20raw=20bands[]=20write=20and=20DESIGN=20(raw=20bli?= =?UTF-8?q?nks=200.3..382=20while=20scratch=20steady)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handoff/NOTES_LEVEL.md | 27 ++++++++++++++++++ scripts/qseries.py | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 scripts/qseries.py diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index a2fdc92..085d0c0 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -2354,3 +2354,30 @@ CONT, дамп rcx/rdx на хите (скрипт fnall.py готов, нуже 2. Найти источник масштаба 1.805 (декод потребителя FIR: кто читает 0x540668). 3. Транскрипция RT_FIRCONV=1: bands=STFT-спектр кадра → scratch=G(...) → kernel=exp·HannWin → rfft-свёртка overlap-add → гейт корпуса. + +## ============ UPDATE 2026-08-23j (23f): q-СЕРИЯ ЖИВЫХ SCRATCH ============ + +scripts/qseries.py: rendersnap по dual_b1q_{0.1..10}.rpp (11 конфигов). +Стационарная подвыборка (scr43≈−0.6565): q={0.2,0.3,0.5,0.7,1.0,1.5,3.0} +(q=0.1,2,5,10 поймали нестационар scr43≈−0.18 — фильтровать по scr43!). +Таблица (FIR-cut дБ = −20log10 exp(0.984·scr); ×1.805 — эмпир. масштаб): +| q | scr43 | scr171 | FIR@43 | FIR@171 | ×1.805 @171 | real@171 | +|---|---|---|---|---|---|---| +| 0.2 | −0.6565 | −0.8965 | 5.61 | 7.66 | 13.83 | — | +| 0.3 | −0.6565 | −0.8332 | 5.61 | 7.12 | 12.85 | — | +| 0.5 | −0.6565 | −0.7570 | 5.61 | 6.47 | 11.68 | 11.82 | +| 0.7 | −0.6565 | −0.7192 | 5.61 | 6.15 | 11.09 | — | +| 1.0 | −0.6564 | −0.6923 | 5.61 | 5.92 | 10.68 | 10.78 | +| 1.5 | −0.6562 | −0.6750 | 5.61 | 5.77 | 10.41 | — | +| 3.0 | −0.6551 | −0.6633 | 5.60 | 5.67 | 10.23 | 10.32 | +Выводы: (а) центр строго const ∀q; (б) ×1.805 попадает в real с ошибкой +≤0.14 дБ на обеих известных точках; (в) scr171(res2000) НЕлинеен в ln res +(локальный наклон падает 0.135→0.088 ln/res) — согласуется с экспоненциальной +формой 22x; (г) сырой bands[] мигает на порядки (0.3↔382) при стабильном +scratch ⇒ детекторное сглаживание (attack/release IIR) сидит МЕЖДУ записью +bands[] и DESIGN — искать его адрес в цепи до 52b550. +### NEXT +1. am-серия (t_-24..t_+24 rpp уже есть в Recent!) → наклон по амплитуде → + полная форма G=log-домена: scr = c0 + ka·ln(am) + f(res). +2. Декод читателя 0x540668 (источник ×1.805) + детекторного IIR перед DESIGN. +3. RT_FIRCONV=1 транскрипция: G аппроксимировать таблично по этой серии. diff --git a/scripts/qseries.py b/scripts/qseries.py new file mode 100644 index 0000000..26deba4 --- /dev/null +++ b/scripts/qseries.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +"""qseries.py — run rendersnap across dual_b1q_*.rpp configs, extract steady +scratch/FIR at bins 43/171 into one table vs the real cuts from NOTES 22x.""" +import glob +import os +import subprocess +import sys + +import numpy as np + +QS = ['0.1', '0.2', '0.3', '0.5', '0.7', '1.0', '1.5', '2.0', '3.0', '5.0', '10.0'] +REAL = { # from NOTES_LEVEL 22x table: cut@500, cut@2000 + '0.1': (10.32, 15.33), '0.5': (10.32, 11.82), '1.0': (10.32, 10.78), + '3.0': (10.29, 10.32), '10': (9.94, 10.25), +} +RES2000 = {'0.1': 0.216, '0.5': 0.839, '1.0': 1.353, '3.0': 1.880, '10': 1.988} + + +def steady_scratch(tag): + fs = sorted(glob.glob(f'/tmp/opencode/rendersnap/phase*.npz')) + best = None + for f in fs[::-1]: + z = np.load(f) + sc = z['0x540628'] + if abs(sc[43]) > 1e-6 and abs(sc[171] - sc[43]) > 1e-6 or (abs(sc[43]) > 1e-6): + best = (sc[43], sc[171]) + if abs(sc[171] - sc[43]) > 1e-4: + break + return best + + +def main(): + rows = [] + for q in QS: + rpp = f'/home/m/soothe-bt/dual_b1q_{q}.rpp' + if not os.path.exists(rpp): + continue + subprocess.run( + ['timeout', '100', 'python3', '/home/m/re-tools/scripts/rendersnap.py', + rpp], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + st = steady_scratch(q) + if not st: + print(q, 'NO DATA') + continue + s43, s171 = st + f43 = -20 * np.log10(np.exp(0.984 * s43)) + f171 = -20 * np.log10(np.exp(0.984 * s171)) + rc = REAL.get(q.rstrip('.0') if q.endswith('.0') else q) + row = dict(q=q, scr43=round(s43, 4), scr171=round(s171, 4), + fir43=round(f43, 2), fir171=round(f171, 2), + x18_43=round(f43 * 1.805, 2), x18_171=round(f171 * 1.805, 2)) + if rc: + row['real43'], row['real171'] = rc + row['ratio'] = round(rc[0] / f43, 3), round(rc[1] / f171, 3) + if q in RES2000: + row['res2000'] = RES2000[q] + rows.append(row) + print(row, flush=True) + np.save('/tmp/opencode/qseries.npy', rows, allow_pickle=True) + + +if __name__ == '__main__': + main()