re: LIVE N0@44100 = 2048, oversample 4 (two SP instances agree); angle-ramp+Cody-Waite twiddle path confirmed for main FFT; rtone/rtver scripts
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess, os, glob, sys, time, struct
|
||||
|
||||
proc = None
|
||||
RPP = sys.argv[1] if len(sys.argv) > 1 else "/home/m/soothe-bt/render_long.rpp"
|
||||
START = len(sys.argv) > 2 and sys.argv[2] == "start"
|
||||
if START:
|
||||
proc = subprocess.Popen(
|
||||
['reaper', '-nosplash', '-renderproject', RPP],
|
||||
stdout=open('/tmp/rtfind.log', 'w'), stderr=subprocess.STDOUT)
|
||||
print('reaper', proc.pid, flush=True)
|
||||
|
||||
# The SpectralProcessor vtable slot containing ctor 0x180529610
|
||||
CTOR = 0x180529610
|
||||
# candidate vptrs: slots near it
|
||||
VCANDS = [0x1824abb80, 0x1824abb88, 0x1824abb90, 0x1824abb98, 0x1824abba0, 0x1824abba8, 0x1824abbb0]
|
||||
|
||||
def all_mapped(pid):
|
||||
out = []
|
||||
maps = open(f'/proc/{pid}/maps').read()
|
||||
for line in maps.splitlines():
|
||||
p = line.split()
|
||||
lo, hi = (int(x, 16) for x in p[0].split('-'))
|
||||
if 'r' in p[1]:
|
||||
out.append((lo, hi))
|
||||
return out
|
||||
|
||||
def scan(pid, vptr, tgt):
|
||||
mem = os.open(f'/proc/{pid}/mem', os.O_RDONLY)
|
||||
hits = []
|
||||
for lo, hi in all_mapped(pid):
|
||||
try:
|
||||
d = os.pread(mem, hi - lo, lo)
|
||||
except Exception:
|
||||
continue
|
||||
i = 0
|
||||
while True:
|
||||
i = d.find(tgt, i)
|
||||
if i < 0:
|
||||
break
|
||||
hits.append(lo + i)
|
||||
i += 1
|
||||
os.close(mem)
|
||||
return hits
|
||||
|
||||
def filter_candidates(pid, hit_addrs):
|
||||
# for each candidate object addr (addr = where vptr stored => object base), read fields
|
||||
out = []
|
||||
mem = os.open(f'/proc/{pid}/mem', os.O_RDONLY)
|
||||
for a in hit_addrs:
|
||||
try:
|
||||
d = os.pread(mem, 0x600, a)
|
||||
except Exception:
|
||||
continue
|
||||
f4 = struct.unpack('<%dI' % (len(d) // 4), d)
|
||||
# look for N at +0x19c and oversample at +0x1ac
|
||||
n = f4[0x19c // 4] if (0x19c // 4) < len(f4) else 0
|
||||
u = f4[0x1ac // 4] if (0x1ac // 4) < len(f4) else 0
|
||||
w = struct.unpack('<d', d[0x1a4:0x1a4 + 8])[0] if len(d) >= 0x1a4 + 8 else 0
|
||||
ok = (n in (256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536) and
|
||||
u in (2, 4, 8, 16))
|
||||
if w != 0 and (n > 0 or ok):
|
||||
out.append((a, n, u, w, ok))
|
||||
os.close(mem)
|
||||
return out
|
||||
|
||||
hosts = {}
|
||||
t0 = time.time()
|
||||
seen = set()
|
||||
while time.time() - t0 < 90:
|
||||
for p in glob.glob('/proc/[0-9]*'):
|
||||
try:
|
||||
pid = int(os.path.basename(p))
|
||||
if pid in seen:
|
||||
continue
|
||||
maps = open(f'/proc/{pid}/maps').read()
|
||||
if 'soothe2' not in maps or 'yabridge-host.exe' not in open(f'/proc/{pid}/cmdline', 'rb').read().decode('utf8', 'replace'):
|
||||
continue
|
||||
except Exception:
|
||||
continue
|
||||
seen.add(pid)
|
||||
print('host', pid, flush=True)
|
||||
# scan whole maps for each candidate vptr
|
||||
for v in VCANDS:
|
||||
h = scan(pid, v, struct.pack('<Q', v))
|
||||
if h:
|
||||
res = filter_candidates(pid, h)
|
||||
print(' vptr', hex(v), 'hits', len(h), 'obj-cands', len(res), flush=True)
|
||||
for r in res[:10]:
|
||||
print(' obj', hex(r[0]), 'N', r[1], 'ups', r[2], 'win', r[3], 'OK' if r[4] else '', flush=True)
|
||||
time.sleep(0.4)
|
||||
if proc:
|
||||
proc.kill()
|
||||
print('done', flush=True)
|
||||
Reference in New Issue
Block a user