#!/usr/bin/env python3 """unify.py — global unified-law fit: cut = alpha*ln1p(am*s/res^p / beta)+c across multi6 (6 peaks) + tt-series (8 points, both peaks).""" import numpy as np, glob, wave from scipy.optimize import least_squares def deepest(dirname,b): best=None for fn in sorted(glob.glob(dirname+'/ph*.npz')): d=np.load(fn) if '0x540628' not in d.files: continue s=d['0x540628'].astype(np.float64) if best is None or s[b]=0x800000,s-0x1000000,s).astype(np.float64).reshape(-1,ch).mean(1)/8388608 def ta(x,f,sr=44100,L=None): x=x[-L:]; t=np.arange(len(x))/sr; c=np.cos(2*np.pi*f*t); sn=np.sin(2*np.pi*f*t) return np.hypot(2*(x*c).sum(),2*(x*sn).sum())/len(x) pts=[] # multi6 six peaks S=deepest('/tmp/opencode/sc_multi6',85) cut=np.maximum(-S*8.685889638,0) am=np.zeros(len(S)); rs=np.zeros(len(S)) for ln in open('/tmp/opencode/tract_multi6.txt'): if ln.startswith('#'): continue p=ln.split(); kk=int(p[0]) if kk1.0 and am[kk]>0.01: pts.append(('m6',am[kk],rs[kk],cut[kk])) # tt-series 4 drives x 2 peaks (ref-domain cuts via Goertzel) inp0=loadwav('/tmp/opencode/tt0_in.wav') rc={0:(10.34,11.84),6:(8.12,9.57),12:(6.12,7.45),18:(4.40,5.55)} for att,(c1v,c2v) in rc.items(): tf='/tmp/opencode/tract_tt%d.txt'%att d43=d171=None; r43=r171=None for ln in open(tf): if ln.startswith('#'): continue p=ln.split(); kk=int(p[0]) if kk==43: r43=float(p[2]); d43=am0=None; d43=float(p[1]) if kk==171: r171=float(p[2]); d171=float(p[1]) pts.append(('tt%d-pk1'%att,d43,r43,c1v)) pts.append(('tt%d-pk2'%att,d171,r171,c2v)) print('points:',len(pts)) def resid(p): al,be,cc,pp,ss=p out=[] for nm,a,r,c in pts: X=a*ss/max(r**pp,1e-12) out.append(al*np.log1p(X/be)+cc-c) return np.array(out) p0=[3.28,0.56,0.77,1.25,1.0] lb=[0.5,0.01,-5,0.05,0.05] ub=[8,5,5,4,50] r=least_squares(resid,p0,bounds=(lb,ub),max_nfev=8000) mm=-resid(r.x)+np.array([c for _,_,_,c in pts]) tgt=np.array([c for _,_,_,c in pts]) rms=np.sqrt(((mm-tgt)**2).mean()) print('UNIFIED: alpha=%.3f beta=%.4f c=%+.3f p=%.3f s=%.3f ; rms=%.4f max=%.3f' % ( *r.x,rms,np.abs(mm-tgt).max())) for (nm,a,rr,c),pv in zip(pts,mm): print(' %-10s am=%.4f res=%.4f cut=%6.2f pred=%6.2f err=%+.2f' % (nm,a,rr,c,pv,c-pv))