This is a very simple generator for JSFX scripts that remap CC numbers. The main idea is that when you have a synth that takes controls like filter frequency on certain CC's, and you have a controller like a Midimix, which generates fixed CC numbers for each knob, this allows you to create a mapper between the two. Very quick and dirty. The main intended use are the Ostirus and Nodal Red emulations of the Virus TI and Nord Rack 2X respectively, or indeed the hardware Rack 2X I have lying around. ## Input File Example ``` mr_flibble_says_hi 10 50 40 55 # comment 5 6 # other comment ``` The first line is the name (output is `name.jsfx`, desc line is `desc: name`). The remaining lines, after `# comments` are stripped, consist of two numbers. These can be integers like `42` or hex values like `0x42`. Example output: ``` desc: mr_flibble_says_hi @block while ( midirecv(ts,msg1,msg2,msg3) ? ( c = msg1 & 0xF; s = msg1 >> 4; ( s == 0xB ) ? ( cc = msg2; val = msg3; ( cc == 5 ) ? ( cc = 6 ) : ( cc == 10 ) ? ( cc = 50 ) : ( cc == 64 ) ? ( cc = 55 ); midisend(ts,msg1,cc,val); ) : ( midisend(ts,msg1,msg2,msg3); ); )); ``` ## Python Script ``` #!/usr/bin/env python import argparse def main(): parser = argparse.ArgumentParser(prog="cc_map_gen", description="CC Mapper JSFX Generator") parser.add_argument("files",nargs="+") ns = parser.parse_args() for fn in ns.files: proc(fn) def decodehex(x): try: if x.startswith("0x"): return int(x[2:],16) return int(x) except ValueError as e: raise ValueError(f"Failed to parse as int or hex: {x}") def proc(fn): try: with open(fn) as f: lines = f.read().rstrip().splitlines() except Exception as e: print("#Exception",type(e),e,fn) return name = lines.pop(0) d = {} ks = set() for line in lines: line = line.split("#")[0].strip() xs = line.split(" ") if len(xs) != 2: continue try: xs = [ decodehex(x) for x in xs ] except ValueError as e: print("#Exception",e) continue s,t = xs ks.add(s) d[s] = t ks = sorted(ks) """ ( cc == {s} ) ? ( cc = {t} ) : ( cc == {s} ) ? ( cc = {t} ) """ out_lines = [ f" ( cc == {s} ) ? ( cc = {d[s]} )" for s in ks ] out = " : \n".join(out_lines) + ";" ofn = name + ".jsfx" jsfx = gen_jsfx(name,out) with open(ofn,"wt") as f: print(jsfx,file=f) print("Written",ofn) def gen_jsfx(name,payload): return f"""desc: {name} @block while ( midirecv(ts,msg1,msg2,msg3) ? ( c = msg1 & 0xF; s = msg1 >> 4; ( s == 0xB ) ? ( cc = msg2; val = msg3; {payload} midisend(ts,msg1,cc,val); ) : ( midisend(ts,msg1,msg2,msg3); ); )); """ if __name__ == "__main__": main() ```