From 2a401bebd828bcb5de76f75ace4c256dca78c253 Mon Sep 17 00:00:00 2001 From: boyska Date: Wed, 29 Aug 2018 12:24:48 +0200 Subject: [PATCH] add calf2ladspa --- .gitignore | 2 + calf2ladspa/calf2ladspa.py | 124 +++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 .gitignore create mode 100644 calf2ladspa/calf2ladspa.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb099a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +calf2ladspa/*.xml +*.ogg diff --git a/calf2ladspa/calf2ladspa.py b/calf2ladspa/calf2ladspa.py new file mode 100644 index 0000000..df3e9e0 --- /dev/null +++ b/calf2ladspa/calf2ladspa.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +import sys +from xml.dom.minidom import parse +import re + + +def key_change(key): + if key[-1].isdigit(): + num = int(key[-1]) + return '%s_%d' % (key[:-1], num+1) + return key + + +def starting(key, args): + '''returns True if key starts with any of the string in args''' + return any(key.startswith(x) for x in args) + + +def parse_params(preset): + return {par.attributes['name'].value: par.attributes['value'].value + for par in preset.getElementsByTagName('param')} + + +def multibandcompressor_get_params(params): + newparams = {} + for key in params: + if starting(key, ('level_', 'meter_', 'clip_', 'detection', + 'compression', 'mode', 'output', 'notebook')): + continue + if key == 'bypass' or key.startswith('solo'): + newparams[key_change(key)] = bool(int(params[key])) + elif key.startswith('bypass') or re.match(r'output\d', key): + continue + elif starting(key, ('attack', 'ratio', 'release', 'makeup', 'knee', + 'threshold')): + newparams[key_change(key)] = float(params[key]) + elif starting(key, ('mode', 'notebook', 'output')): + newparams[key_change(key)] = int(params[key]) + elif key.startswith('freq'): + num = int(key[-1]) + newparams['split_%d_%d' % (num+1, num+2)] = float(params[key]) + else: + print('!!', key, params[key], file=sys.stderr) + return newparams + + +def filter_get_params(params): + newparams = {} + for key in params: + if key == 'freq': + newparams['frequency'] = float(params[key]) + elif key == 'res': + newparams['resonance'] = float(params[key]) + elif key == 'inertia': + newparams[key] = float(params[key]) + elif key in ('mode',): + newparams[key] = int(params[key]) + else: + print('!!', key, params[key], file=sys.stderr) + return newparams + + +get_params = { + 'multibandcompressor': multibandcompressor_get_params, + 'filter': filter_get_params, +} + + +def ls_value_format(v): + if type(v) is bool: + return 'true' if v else 'false' + if type(v) is int: + return str(v) + if type(v) is float: + return str(v) + if type(v) is str: + return '"%s"' % v # let's hope no quote inside! + raise ValueError('Unsupported type') + + +def ls_format(params, plugin_name): + param_set = ', '.join(['{}={}'.format(k, ls_value_format(v)) + for k, v in params.items()]) + return 'a = ladspa.%s(%s, in)' % (plugin_name, param_set) + + +def usage(): + print('%s: Convert an XML file created by calfjackhost to ' + 'liquidsoap-equivalent code, making use of calf-ladspa' % + sys.argv[0]) + print('\nUsage:') + print(' %s FILENAME.xml [PRESET]' % sys.argv[0]) + print('\nIf PRESET is omitted, the command will print a list of available ' + 'presets found in the specified file') + print('\nIf PRESET is given, the command will convert that preset in ' + 'liquidsoap ladspa code') + + +if __name__ == '__main__': + if len(sys.argv) <= 1: + usage() + sys.exit(2) + if sys.argv[1] in ('-h', '--help'): + usage() + sys.exit(0) + fname = sys.argv[1] + preset = sys.argv[2] if len(sys.argv) > 2 else None + dom = parse(fname) + if preset is None: + print('available presets:') + for preset in dom.getElementsByTagName('preset'): + print('-', preset.attributes['name'].value) + sys.exit(0) + preset = [p for p in dom.getElementsByTagName('preset') + if p.attributes['name'].value == preset][0] + raw_params = parse_params(preset) + fx_type = preset.attributes['plugin'].value + if fx_type not in get_params: + print('plugin <%s> unsupported! output will probably be wrong' % + fx_type, file=sys.stderr) + params = raw_params + else: + params = get_params[fx_type](raw_params) + print(ls_format(params, fx_type))