23f: live scratch series across q sweep (11 configs) — center strictly constant over q, x1.805 hits real cuts within 0.14dB at both known points, scr171(res) nonlinear consistent with 22x exponent; detector smoothing located between raw bands[] write and DESIGN (raw blinks 0.3..382 while scratch steady)

This commit is contained in:
2026-08-23 22:27:13 +03:00
parent 7902acfbb8
commit 70cafc1700
2 changed files with 90 additions and 0 deletions
+27
View File
@@ -2354,3 +2354,30 @@ CONT, дамп rcx/rdx на хите (скрипт fnall.py готов, нуже
2. Найти источник масштаба 1.805 (декод потребителя FIR: кто читает 0x540668). 2. Найти источник масштаба 1.805 (декод потребителя FIR: кто читает 0x540668).
3. Транскрипция RT_FIRCONV=1: bands=STFT-спектр кадра → scratch=G(...) → 3. Транскрипция RT_FIRCONV=1: bands=STFT-спектр кадра → scratch=G(...) →
kernel=exp·HannWin → rfft-свёртка overlap-add → гейт корпуса. 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 аппроксимировать таблично по этой серии.
+63
View File
@@ -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()