docs: two-point 180s capture confirms registry stability; twin per-note state = {A[3],B[3]} not 342-dbl; Step C closed
This commit is contained in:
@@ -63,3 +63,16 @@
|
|||||||
- Next: render_long + capture at t=10-20s into sustain, then locate the per-bin
|
- Next: render_long + capture at t=10-20s into sustain, then locate the per-bin
|
||||||
attack/release smoothing coefficients (0x540888/88c set, converted via ln(10)/20)
|
attack/release smoothing coefficients (0x540888/88c set, converted via ln(10)/20)
|
||||||
inside the arena near registry.
|
inside the arena near registry.
|
||||||
|
|
||||||
|
## 2026-08-19b (two-point snapshots t1=8s, t2=40s of render_long 180s)
|
||||||
|
- rtsnap2.py: TWO snapshots of the SAME 180s render at t1/t2; each 318MB/547regs ~0.2s.
|
||||||
|
- Registry tables byte-identical between t1/t2 (stable per-band coeffs; confirmed authoritative).
|
||||||
|
- Diff of arbitrary 342-double windows = pure audio-buffer noise (21981 phantom matches; twin
|
||||||
|
per-band state is NOT a 342-dbl array a level away). Real twin kernel state per NOTES_TWIN:64
|
||||||
|
is {double A[3], double B[3]} per band (6 doubles), seeded in build_twin_coeff FUN_180533ec0.
|
||||||
|
- Conclusion: live per-note-band twin state not usefully separable via full-heap diff; the
|
||||||
|
attack/release input coeffs live in the DSP ctx scalars: 0x540888/0x54088c = expf(p*0.11513)
|
||||||
|
(static-derived), registry holds the per-bin WEIGHT tables (already captured). Twin kernels
|
||||||
|
themselves validated statically (twin_check max|err|=1.27e-5). => Step C goal (window + axes +
|
||||||
|
weights + kernel parity) is effectively CLOSED; only scalar A/R params remain, derived from RPP
|
||||||
|
params, no live capture needed.
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
import subprocess, os, glob, time, struct
|
||||||
|
def mem_open(pid): return os.open(f'/proc/{pid}/mem', os.O_RDONLY)
|
||||||
|
def find_hosts():
|
||||||
|
hosts=[]
|
||||||
|
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:
|
||||||
|
hosts.append(pid)
|
||||||
|
return hosts
|
||||||
|
os.system("pkill -9 -x reaper 2>/dev/null; pkill -9 -f '[y]abridge' 2>/dev/null; sleep 1")
|
||||||
|
proc=subprocess.Popen(['/usr/bin/reaper','-nosplash','-ignoreerrors','-renderproject','/home/m/soothe-bt/render_long.rpp'],
|
||||||
|
stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
|
||||||
|
t0=time.time(); host=None
|
||||||
|
while time.time()-t0<60 and not host:
|
||||||
|
hs=find_hosts(); host=hs[0] if hs else None; time.sleep(0.2)
|
||||||
|
print('host',host, flush=True)
|
||||||
|
fd=mem_open(host)
|
||||||
|
def snap(tag):
|
||||||
|
out=open('/tmp/snap_%s.bin'%tag,'wb'); idx=open('/tmp/snap_%s.idx'%tag,'wb')
|
||||||
|
t0=time.time(); nreg=0; nb=0
|
||||||
|
for line in open(f'/proc/{host}/maps').read().splitlines():
|
||||||
|
p=line.split(); lo,hi=(int(x,16) for x in p[0].split('-'))
|
||||||
|
if 'r' not in p[1]: continue
|
||||||
|
a=lo
|
||||||
|
while a<hi:
|
||||||
|
n=min(hi-a,8*1024*1024)
|
||||||
|
try: d=os.pread(fd,n,a)
|
||||||
|
except Exception: a+=n; continue
|
||||||
|
if not d: a+=n; continue
|
||||||
|
out.write(struct.pack('<QQ',a,len(d))); out.write(d)
|
||||||
|
idx.write(struct.pack('<QQ',a,len(d)))
|
||||||
|
nreg+=1; nb+=len(d); a+=n
|
||||||
|
out.close(); idx.close()
|
||||||
|
print('snap %s: %d MB %d regs in %.1fs'%(tag,nb/1e6,nreg,time.time()-t0), flush=True)
|
||||||
|
time.sleep(8); snap('t1')
|
||||||
|
time.sleep(32); snap('t2')
|
||||||
|
time.sleep(200)
|
||||||
|
if proc.poll() is None: proc.kill()
|
||||||
|
print('done')
|
||||||
Reference in New Issue
Block a user