24ee: variables SEPARATED — softplus form universal (3 independent calibrations rms<=0.016), alpha grows with tone count (1.15->3.22 for 1->2 tones: freq-mixing in steps 9-19); audio=deepest-scratch+const across ALL families; dual two-stage was two-tone artifact
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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')
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user