From 0fbff6dc6eec2e29b54455dbe23f9908adcb8c7b Mon Sep 17 00:00:00 2001 From: Matiq Date: Tue, 25 Aug 2026 09:21:44 +0300 Subject: [PATCH] =?UTF-8?q?24ee:=20variables=20SEPARATED=20=E2=80=94=20sof?= =?UTF-8?q?tplus=20form=20universal=20(3=20independent=20calibrations=20rm?= =?UTF-8?q?s<=3D0.016),=20alpha=20grows=20with=20tone=20count=20(1.15->3.2?= =?UTF-8?q?2=20for=201->2=20tones:=20freq-mixing=20in=20steps=209-19);=20a?= =?UTF-8?q?udio=3Ddeepest-scratch+const=20across=20ALL=20families;=20dual?= =?UTF-8?q?=20two-stage=20was=20two-tone=20artifact?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handoff/NOTES_LEVEL.md | 28 ++++++++++++++++++ scripts/finish_f.py | 65 ++++++++++++++++++++++++++++++++++++++++++ scripts/rendersnap2.py | 3 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 scripts/finish_f.py diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 700bb5e..44d2fa2 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -3596,3 +3596,31 @@ Bit-exact замыкание ВСЕХ конфигураций = декод ге и амплитудного тракта am[] до уровня формул. Модули известны: dsp/twin.cpp (наша транскрипция), detkernel::build_twin_coeff, детекторный анализ в fn529fe0.cpp. Задача связная, на отдельную сессию. + +## ============ UPDATE 24ee: РАЗДЕЛЕНИЕ ПЕРЕМЕННЫХ — ФОРМА ЗАКОНА УНИВЕРСАЛЬНА, КОНСТАНТЫ КОНТЕНТ-ЗАВИСИМЫ ============ + +### Контролируемый эксперимент (patchparam + генератор входов): +``` +семейство α β c rms +fc500 ДВА тона (dual) 3.2193 0.4927 +0.54 0.016 +fc1000 ОДИН тон (k-серия) 1.6151 0.3645 +0.48 0.010 +fc500 ОДИН тон (f-серия) 1.1530 0.4038 +0.33 0.0013!! +``` +1. Мягкоплюс-форма ПОДТВЕРЖДЕНА трижды независимо (rms ≤0.016). +2. α растёт с ЧИСЛОМ ТОНОВ контента (1.15→3.22 при 1→2 тонах): детектор- + уровень пика получает вклад от соседних областей (частотное смешение + в шагах 9–19!), и двухтоновый контент удваивает эффективную крутизну. +3. fc-зависимость слабее контент-зависимости (1.15@500 vs 1.62@1000 + для одного тона — осторожно, β тоже меняется). +4. Аудио = deepest-scratch + константа (+0.13..+0.18 дБ) ВО ВСЕХ трёх + семействах — двухстадийность dual была артефактом двухтонового + контента (второй тон создавал отдельное глубокое состояние!). + +### Следствие для архитектуры транскрипции +Универсальная форма + пер-контент константы = рабочая схема. Полная +универсальность требует декода шагов 9–19 (механизм смешения), где +константы станут вычисляемыми. + +### Инструменты/данные раунда +scripts/finish_f.py; k-серия (sc_k*, k*_ref); f-серия (sc_f*, f*_ref); +k_series.pkl, f_series.pkl. Все рефы отрендеры чисто (без kill). diff --git a/scripts/finish_f.py b/scripts/finish_f.py new file mode 100644 index 0000000..219cede --- /dev/null +++ b/scripts/finish_f.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""finish_f.py — patch band freq=500, render refs, capture scratches, build tracts.""" +import subprocess, os, re, sys, time, wave, glob +import numpy as np + +sys.path.insert(0,'/home/m/re-tools/scripts') + +def sh(cmd): + r=subprocess.run(cmd,shell=True,capture_output=True,text=True) + return r.stdout+r.stderr + +# 1. patch band freq=500 into raw clones +for a in (0,6,12,24): + src=open(f'/tmp/opencode/f{a}_raw.rpp').read() + open(f'/tmp/opencode/f{a}.rpp','w').write(src) +print('freq left as base1k default (band1 freq=1000?) — CHECK') +# base1k was cloned from multi.rpp which had band1 freq=500 already! +# t1k_base.rpp got 'band1 freq'=1000 patched; f*_raw cloned from base1k -> 1000. +# We need 500: patch each: +for a in (0,6,12,24): + out=sh(f'cd /home/m/re-tools && python3 patchparam.py /tmp/opencode/f{a}_raw.rpp /tmp/opencode/f{a}.rpp "band1 freq"=500.0') + if 'patched 1' not in out: print(f'f{a} patch issue:',out.strip()[:80]) +print('patched to 500') + +def find_host(): + for p in glob.glob('/proc/[0-9]*'): + pid=int(os.path.basename(p)) + try: + cmd=open(f'/proc/{pid}/cmdline','rb').read().replace(b'\0',b' ').decode('utf8','replace') + maps=open(f'/proc/{pid}/maps').read() + except Exception: continue + if 'soothe2' in maps and 'reaper' not in cmd: return pid + return None + +sh("pkill -9 -x reaper; pkill -9 -f '[y]abridge'; " + "rm -rf /run/user/1000/yabridge-soothe2_x64-*; sleep 1") + +for a in (0,6,12,24): + wav=f'/tmp/opencode/f{a}_ref.wav' + if os.path.exists(wav): os.remove(wav) + pr=subprocess.Popen(['/usr/bin/reaper','-nosplash','-ignoreerrors','-renderproject',f'/tmp/opencode/f{a}.rpp'], + stdout=subprocess.DEVNULL,stderr=subprocess.STDOUT) + t0=time.time(); host=None + while time.time()-t0<30 and not host: host=find_host(); time.sleep(0.002) + # wait for natural finish + for _ in range(200): + if pr.poll() is not None: break + try: + if not os.path.exists('/proc/%d'%host) if host else True: break + except Exception: break + time.sleep(0.05) + for _ in range(60): + if pr.poll() is not None: break + time.sleep(0.1) + print(f'f{a} rendered rc={pr.poll()} wav={os.path.getsize(wav) if os.path.exists(wav) else "NONE"}') + +# tracts +env=dict(os.environ) +for a in (0,6,12,24): + tf=f'/tmp/opencode/tract_f{a}.txt' + if os.path.exists(tf): os.remove(tf) + e=dict(env); e['RT_DUMP_BIN']=tf + subprocess.run(['/home/m/re-tools/dsp/build/render48k',f'/tmp/opencode/{a}_in.wav' if False else f'/tmp/opencode/f{a}_in.wav', + '/tmp/o48_f.wav','500,0.5,12'],capture_output=True,env=e) +print('tracts done') diff --git a/scripts/rendersnap2.py b/scripts/rendersnap2.py index 61ef7a9..7684734 100644 --- a/scripts/rendersnap2.py +++ b/scripts/rendersnap2.py @@ -19,7 +19,8 @@ import time import numpy as np SLOTS = [0x540668, 0x540548, 0x540550, 0x540598, 0x540628, - 0x540678, 0x540688, 0x540768, 0x540788, 0x5407f8] + 0x540678, 0x540688, 0x5406c8, 0x5406e8, 0x540768, + 0x540788, 0x5407f8] NARR = 8194 SCAL_OFF = 0x540860 SCAL_N = 24 # floats -> 0x540860..0x5408c0