#!/usr/bin/env python3 """campaign.py — one config-family cell: build rpp variants, clean-render refs, capture deepest scratch, extract tracts, fit softplus law. Usage: campaign.py Inputs must exist as _in.wav for drive in list. """ import subprocess, os, re, sys, time, glob import numpy as np sys.path.insert(0,'/home/m/re-tools/scripts') 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 def main(): base,freq,q,sens,pref,drives,outp=sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5],sys.argv[6].split(','),sys.argv[7] # build rpps for a in drives: src=open(base).read() src=src.replace('FILE "/home/m/soothe-bt/tone1k.wav"',f'FILE "{pref}{a}_in.wav"') src=re.sub(r'RENDER_FILE "[^"]*"',f'RENDER_FILE "{outp}/{a}_ref.wav"',src) tmp=f'{outp}/{a}_tmp.rpp' open(tmp,'w').write(src) out=sh(f'cd /home/m/re-tools && python3 patchparam.py {tmp} {outp}/{a}.rpp ' f'"band1 freq"={freq} "band1 q"={q}') if 'patched' not in out and 'warning' not in out: print(f'drive {a}: patch issue: {out[:100]}') sh("pkill -9 -x reaper; pkill -9 -f '[y]abridge'; " "rm -rf /run/user/1000/yabridge-soothe2_x64-*; sleep 1") # render refs cleanly for a in drives: wav=f'{outp}/{a}_ref.wav' if os.path.exists(wav): os.remove(wav) pr=subprocess.Popen(['/usr/bin/reaper','-nosplash','-ignoreerrors','-renderproject',f'{outp}/{a}.rpp'], stdout=subprocess.DEVNULL,stderr=subprocess.STDOUT) t0=time.time() while time.time()-t0<30 and pr.poll() is None: time.sleep(0.2) for _ in range(60): if pr.poll() is not None: break time.sleep(0.1) print(f'drive {a}: ref rc={pr.poll()} size={os.path.getsize(wav) if os.path.exists(wav) else 0}',flush=True) if __name__=='__main__': main()