1#!/usr/bin/python
2#
3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# convert audio.conf from the audio tuning UI to dsp.ini which can be
8# accepted by cras eq/drc plugin.
9
10import json
11import sys
12import fnmatch
13
14biquad_type_name = [
15    "none",
16    "lowpass",
17    "highpass",
18    "bandpass",
19    "lowshelf",
20    "highshelf",
21    "peaking",
22    "notch",
23    "allpass"
24    ]
25
26header = """\
27[output_source]
28library=builtin
29label=source
30purpose=playback
31disable=(not (equal? dsp_name "speaker_eq"))
32output_0={src:0}
33output_1={src:1}
34
35[output_sink]
36library=builtin
37label=sink
38purpose=playback
39input_0={dst:0}
40input_1={dst:1}"""
41
42drc_header = """\
43[drc]
44library=builtin
45label=drc
46input_0={%s:0}
47input_1={%s:1}
48output_2={%s:0}
49output_3={%s:1}
50input_4=%-7d   ; emphasis_disabled"""
51
52drc_param = """\
53input_%d=%-7g   ; f
54input_%d=%-7g   ; enable
55input_%d=%-7g   ; threshold
56input_%d=%-7g   ; knee
57input_%d=%-7g   ; ratio
58input_%d=%-7g   ; attack
59input_%d=%-7g   ; release
60input_%d=%-7g   ; boost"""
61
62eq_header = """\
63[eq2]
64library=builtin
65label=eq2
66input_0={%s:0}
67input_1={%s:1}
68output_2={%s:0}
69output_3={%s:1}"""
70
71eq_param = """\
72input_%d=%-7d ; %s
73input_%d=%-7g ; freq
74input_%d=%-7g ; Q
75input_%d=%-7g ; gain"""
76
77def is_true(d, pattern):
78  for k in d:
79    if fnmatch.fnmatch(k, pattern) and d[k]:
80        return True
81  return False
82
83def intermediate_name(index):
84  return 'intermediate' + ('' if index == 1 else str(index))
85
86def main():
87  f = open(sys.argv[1])
88  d = json.loads(f.read())
89  print header
90
91  has_drc = is_true(d, 'global.enable_drc') and is_true(d, 'drc.*.enable')
92  has_eq = is_true(d, 'global.enable_eq') and is_true(d, 'eq.*.*.enable')
93
94  stages = []
95  if has_drc:
96    stages.append(print_drc)
97  if has_eq:
98    stages.append(print_eq)
99
100  if is_true(d, 'global.enable_swap') and len(stages) >= 2:
101    stages[0], stages[1] = stages[1], stages[0]
102
103  for i in range(len(stages)):
104    print
105    src = 'src' if i == 0 else intermediate_name(i)
106    dst = 'dst' if i == len(stages) - 1 else intermediate_name(i + 1)
107    stages[i](d, src, dst)
108
109def print_drc(d, src, dst):
110  print drc_header % (src, src, dst, dst, int(d['drc.emphasis_disabled']))
111  n = 5
112  for i in range(3):
113    prefix = 'drc.%d.' % i
114    f = d[prefix + 'f']
115    enable = int(d[prefix + 'enable'])
116    threshold = d[prefix + 'threshold']
117    knee = d[prefix + 'knee']
118    ratio = d[prefix + 'ratio']
119    attack = d[prefix + 'attack']
120    release = d[prefix + 'release']
121    boost = d[prefix + 'boost']
122
123    print drc_param % (n, f,
124                       n+1, enable,
125                       n+2, threshold,
126                       n+3, knee,
127                       n+4, ratio,
128                       n+5, attack,
129                       n+6, release,
130                       n+7, boost)
131    n += 8
132
133# Returns two sorted lists, each one contains the enabled eq index for a channel
134def enabled_eq(d):
135    eeq = [[], []]
136    for k in d:
137      s = k.split('.')
138      if s[0] == 'eq' and s[3] == 'enable' and d[k]:
139        ch_index = int(s[1])
140        eq_num = int(s[2])
141        eeq[ch_index].append(eq_num)
142    return sorted(eeq[0]), sorted(eeq[1])
143
144def print_eq(d, src, dst):
145  print eq_header % (src, src, dst, dst)
146  eeq = enabled_eq(d)
147  eeqn = max(len(eeq[0]), len(eeq[1]))
148  n = 4  # the first input index
149  for i in range(0, eeqn):
150    for ch in (0, 1):
151      if i < len(eeq[ch]):
152        prefix = 'eq.%d.%d.' % (ch, eeq[ch][i])
153        type_name = d[prefix + 'type']
154        type_index = biquad_type_name.index(type_name)
155        f = d[prefix + 'freq']
156        q = d[prefix + 'q']
157        g = d[prefix + 'gain']
158      else:
159        type_name = 'none';
160        type_index = 0;
161        f = q = g = 0
162      print eq_param % (n, type_index, type_name,
163                        n+1, f, n+2, q, n+3, g)
164      n += 4
165
166main()
167