#!/usr/bin/env python3 import base64, re, sys, os # Reads render_v5.rpp, changes plugin PARAM values, writes a new RPP targeting an output name. TPL = "/home/m/soothe-bt/render_v5.rpp" def load_state(rpp=TPL): txt = open(rpp).read().split('\n') vi = [i for i,l in enumerate(txt) if 'VST "VST3: soothe2' in l][0] blob = [] end = vi for i in range(vi+1, vi+40): s = txt[i].strip() if s == '>' or not s: end = i break blob.append(s) out = b'' for l in blob: out += base64.b64decode(l + '=' * ((-len(l)) % 4)) return txt, vi, end, blob, out def save_state(txt, vi, end, blob, out, binary_len, rpp_out): # re-encode: binary_len bytes header + rest is ascii xml header = out[:binary_len] xml = out[binary_len:] new = base64.b64encode(header + xml).decode() lines = [new[i:i+128] for i in range(0, len(new), 128)] newblk = [' ' + l for l in lines] txt2 = txt[:vi+1] + newblk + [txt[end]] open(rpp_out, 'w').write('\n'.join(txt2)) def set_params(rpp, out_rpp, out_wav, params): txt, vi, end, blob, out = load_state(rpp) # preserve everything: prefix before ' 4: # full-precision param (e.g. depth) -> needs 16 decimals full = f"{float(val):.16f}" elif '.' in orig: # short-form param (e.g. selectivity "10.0") -> keep decimal count full = f"{float(val):.{len(orig.split('.')[1])}f}" else: full = val xml = xml[:m.start()] + f' [id=val ...] rpp_out = sys.argv[1] out_wav = sys.argv[2] params = dict(a.split('=', 1) for a in sys.argv[3:]) set_params(TPL, rpp_out, out_wav, params) print("wrote", rpp_out, params)