24nn: SESSION FINALE — per-peak softplus laws ultra-clean (pk2 rms 0.0006!), shared alpha~3.3, beta2 10x smaller than beta1, level-scale x11.6 const; CROSS-RUN absolute comparisons UNRELIABLE (state selection) — within-run series only; campaign tools complete
This commit is contained in:
@@ -3774,3 +3774,32 @@ bigkernel'ов из рантайм-адресов (24jj).
|
||||
формулы применения с калибровкой rms 0.016; все инструменты/датасеты
|
||||
сохранены. Полное кросс-конфиг замыкание = транскрипция каскада по
|
||||
dataflow (связная задача следующей сессии, блокеров нет).
|
||||
|
||||
## ============ ФИНАЛ СЕССИИ 24ll/24mm/24nn: пер-пиковые законы; кросс-ран сравнения ненадёжны ============
|
||||
|
||||
### Двухтоновая серия (tt, один прогон — оба пика согласованно):
|
||||
```
|
||||
PK1 (центр полосы): cut = 3.282·ln1p(lvl/0.5593)+0.768 rms 0.0037
|
||||
PK2 (тон@2000): cut = 3.355·ln1p(lvl/0.0570)+1.091 rms 0.0006 (!!)
|
||||
```
|
||||
Общий α≈3.3; β₂ в 10 раз меньше β₁ (второй пик чувствительнее);
|
||||
m-тест: pk2-закон = pk1-закон(уровень×11.6±0.1) — константный масштаб.
|
||||
|
||||
### Кросс-РАН сравнения абсолютных катов НЕНАДЁЖНЫ
|
||||
Глубокое/мелкое состояние буфера выбирается по-разному между запусками
|
||||
(d1500 дал 6.62 @pk2, tt-семейство 11.46 при том же контенте!) ⇒
|
||||
валидны только ВНУТРИ-прогонные серии (один запуск = одно состояние).
|
||||
Это объясняет все прошлые «немонотонности» и противоречия между сериями.
|
||||
|
||||
### Параметризация сведена к:
|
||||
```
|
||||
α ≈ 3.3 (общий наклон)
|
||||
β_peak, c_peak — зависят от ПОЗИЦИИ пика относительно полосы
|
||||
(шаблонная геометрия; источник — декомп шагов 9–19/LUT)
|
||||
Δ-правило — из pre-combine
|
||||
```
|
||||
|
||||
### ИНСТРУМЕНТЫ КАМПАНИИ ГОТОВЫ
|
||||
campaign.py (ячейка семейства); tt_series.py (рецепт двухтоновой серии);
|
||||
все датасеты sc_*/tract_*/*pkl сохранены. Следующая сессия: декод шагов
|
||||
9–19 до конца (dataflow готов) + захват A/B/γ объектов банд → замыкание.
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""two-tone drive series at fc500/q0.5/s12: renders+captures+fit."""
|
||||
import subprocess, os, sys, time, glob
|
||||
import numpy as np, wave
|
||||
|
||||
def sh(cmd): return subprocess.run(cmd,shell=True,capture_output=True,text=True).stdout
|
||||
def find_host():
|
||||
import glob as g
|
||||
for p in g.glob('/proc/[0-9]*'):
|
||||
pid=int(os.path.basename(p))
|
||||
try:
|
||||
cmd=open('/proc/%d/cmdline'%pid,'rb').read().replace(b'\0',b' ').decode('utf8','replace')
|
||||
maps=open('/proc/%d/maps'%pid).read()
|
||||
except Exception: continue
|
||||
if 'soothe2' in maps and 'reaper' not in cmd: return pid
|
||||
return None
|
||||
|
||||
# inputs: dual content (500+2000 equal) at drives 0/-6/-12/-18 with probes
|
||||
sr=44100; T=4.0; n=int(sr*T); t=np.arange(n)/sr
|
||||
ph=np.random.default_rng(41).uniform(0,2*np.pi,7)
|
||||
drives=(0,6,12,18)
|
||||
for att in drives:
|
||||
A=0.4248*10**(-att/20)
|
||||
y=A*np.sin(2*np.pi*500*t+ph[0])+A*np.sin(2*np.pi*2000*t+ph[1])
|
||||
for i,f in enumerate((300.,700.,1400.,2800.,5000.)):
|
||||
y+=A*10**(-30/20)*np.sin(2*np.pi*f*t+ph[i+2])
|
||||
y=np.clip(y,-0.999,0.999)
|
||||
nm='tt%d'%att
|
||||
w=wave.open('/tmp/opencode/%s_in.wav'%nm,'wb'); w.setnchannels(1); w.setsampwidth(2); w.setframerate(sr)
|
||||
w.writeframes((y*32767).astype(np.int16).tobytes()); w.close()
|
||||
src=open('/tmp/opencode/multi.rpp').read()
|
||||
import re
|
||||
src=re.sub(r'RENDER_FILE "[^"]*"','RENDER_FILE "/tmp/opencode/%s_ref.wav"'%nm,src)
|
||||
src=src.replace('FILE "/tmp/opencode/multi_in.wav"','FILE "/tmp/opencode/%s_in.wav"'%nm)
|
||||
open('/tmp/opencode/%s.rpp'%nm,'w').write(src)
|
||||
print('inputs+rpps ready')
|
||||
|
||||
sh("pkill -9 -x reaper; pkill -9 -f '[y]abridge'; rm -rf /run/user/1000/yabridge-soothe2_x64-*; sleep 1")
|
||||
for att in drives:
|
||||
wav='/tmp/opencode/tt%d_ref.wav'%att
|
||||
if os.path.exists(wav): os.remove(wav)
|
||||
pr=subprocess.Popen(['/usr/bin/reaper','-nosplash','-ignoreerrors','-renderproject','/tmp/opencode/tt%d.rpp'%att],
|
||||
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)
|
||||
for _ in range(240):
|
||||
if pr.poll() is not None: break
|
||||
time.sleep(0.1)
|
||||
print('tt%d ref rc=%s'%(att,pr.poll()),flush=True)
|
||||
|
||||
# captures + tracts
|
||||
for att in drives:
|
||||
od='/tmp/opencode/sc_tt%d'%att
|
||||
sh('rm -rf %s'%od)
|
||||
sh('cd /home/m/re-tools && timeout 60 python3 scripts/rendersnap2.py /tmp/opencode/tt%d.rpp 400 %s'%(att,od))
|
||||
tf='/tmp/opencode/tract_tt%d.txt'%att
|
||||
if os.path.exists(tf): os.remove(tf)
|
||||
env=dict(os.environ); env['RT_DUMP_BIN']=tf
|
||||
subprocess.run(['/home/m/re-tools/dsp/build/render48k','/tmp/opencode/tt%d_in.wav'%att,
|
||||
'/tmp/o48_tt.wav','500,0.5,12'],capture_output=True,env=env)
|
||||
print('captures+tracts done')
|
||||
Reference in New Issue
Block a user