Browse Source

add calf2ladspa

boyska 5 years ago
parent
commit
2a401bebd8
2 changed files with 126 additions and 0 deletions
  1. 2 0
      .gitignore
  2. 124 0
      calf2ladspa/calf2ladspa.py

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+calf2ladspa/*.xml
+*.ogg

+ 124 - 0
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))