- Инфраструктура: RTTI-дампы (rtti_dsp/full.json), декомпиляции DSP-классов (decomp_*.txt), Ghidra-скрипты (Dump*.java, ImportRtti*.java, Diag.java), depthcurve/curve_fits LUT. - Поведенческая модель sim_v5.py + sim.py (RMSE ~0.3dB), утилиты (measure, tt_sweep, patchparam, sweep, harness_*, verify_sim). - summary.md + roadmap.md (контракт из manual M1-M12, топология пайплайна из OCR, фазы A-C). - pipeline_ocr.txt: OCR диаграммы Appendix A (mid/side ручка, trim/mix/bypass порядок).
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
#!/usr/bin/env python3
|
|
import sys
|
|
sys.path.insert(0, '/home/m/re-tools')
|
|
import re, base64
|
|
from sweep import load_state
|
|
|
|
TPL = sys.argv[1]
|
|
rpp_out = sys.argv[2]
|
|
out_wav = sys.argv[3]
|
|
params = dict(a.split('=', 1) for a in sys.argv[4:])
|
|
|
|
txt, vi, end, blob, out = load_state(TPL)
|
|
xml_idx = out.find(b'<?xml')
|
|
header = out[:xml_idx]
|
|
xml = out[xml_idx:-1].decode('utf8', 'replace')
|
|
for pid, val in params.items():
|
|
m = re.search(rf'<PARAM id="{re.escape(pid)}" value="([^"]*)"', xml)
|
|
if not m:
|
|
raise ValueError(f"param not found: {pid}")
|
|
orig = m.group(1)
|
|
if '.' in orig and len(orig.split('.')[1]) > 4:
|
|
full = f"{float(val):.16f}"
|
|
elif '.' in orig:
|
|
full = f"{float(val):.{len(orig.split('.')[1])}f}"
|
|
else:
|
|
full = val
|
|
xml = xml[:m.start()] + f'<PARAM id="{pid}" value="{full}"' + xml[m.end():]
|
|
newb = base64.b64encode(header + xml.encode('utf8') + out[-1:]).decode()
|
|
lines = [newb[i:i+128] for i in range(0, len(newb), 128)]
|
|
txt2 = txt[:vi+1] + [' ' + l for l in lines]
|
|
if end < len(txt) - 1:
|
|
txt2 = txt2 + txt[end:]
|
|
txt2 = [l if not l.strip().startswith('RENDER_FILE')
|
|
else f' RENDER_FILE "{out_wav}"' for l in txt2]
|
|
open(rpp_out, 'w').write('\n'.join(txt2))
|
|
print("wrote", rpp_out, params) |