1#!/usr/bin/env python
2
3import os
4from shutil import copy2
5import argparse,sys
6import re
7sys.path.append(".")
8
9class ArgParser(argparse.ArgumentParser):
10    def error(self, message):
11        sys.stderr.write('error: %s\n' % message)
12        self.print_help()
13        sys.exit(0)
14
15parser = ArgParser(description='Build script to generate guitarix or LV2 plugins from schematic files.', usage='')
16#parser = argparse.ArgumentParser(description='Build script for guitarix plugins.')
17parser.add_argument('-i','--input', metavar='*.sch', nargs='+', help='Input schematic file(s) name(s) [ONE REQUIRED]',required=True)
18parser.add_argument('-n','--name',help='Name for plugin [OPTIONAL]', required=False)
19parser.add_argument('-s','--shortname',help='Shortname for plugin [OPTIONAL]', required=False)
20parser.add_argument('-d','--description',help='Description for plugin [OPTIONAL]', required=False)
21parser.add_argument('-c','--category',help='Category for plugin [OPTIONAL]', required=False)
22parser.add_argument('-m','--module_id',help='Module ID for plugin [OPTIONAL]', required=False)
23parser.add_argument('-p','--plot', type=str, nargs='?', const='freq', help='frequency response (freq), sinewave (sine) or harmonics (harm) plot from the circuit [OPTIONAL]', required=False)
24parser.add_argument('-b','--build',help='build guitarix plugin from the circuit [OPTIONAL]',action="store_true", required=False)
25parser.add_argument('-l','--buildlv2',help='build lv2 plugin from the circuit [OPTIONAL]',action="store_true", required=False)
26parser.add_argument('-F','--buildfaust',help='build faust code only from the circuit [OPTIONAL]',action="store_true", required=False)
27parser.add_argument('--deploy',help='build C++ code only from the circuit [OPTIONAL]',action="store_true", required=False)
28parser.add_argument('-2','--stereo',help='build stereo plugin from the circuit [OPTIONAL]',action="store_true", required=False)
29parser.add_argument('--switch', metavar='N=Name', nargs='+', help='add on/off switch with "Name" for the N\'t circuit [OPTIONAL]', required=False)
30parser.add_argument('-T','--faust_table', help='build faust, instead C based nonlinear response tables [OPTIONAL]',action="store_true", required=False)
31parser.add_argument('-t','--table', metavar='N', type=int, nargs='+', help='build nonlinear response table from the N\'t circuit [OPTIONAL]', required=False)
32parser.add_argument('-g','--table_neg', metavar='N', type=int, nargs='+', help='build negative nonlinear response table from the N\'t circuit (imply --table)[OPTIONAL]', required=False)
33parser.add_argument('-x','--sig_max', metavar='N', type=float, nargs='+', help='max signal send to build the nonlinear response table from the circuit [OPTIONAL]', required=False)
34parser.add_argument('-/','--table_div', metavar='N', type=float, nargs='+', help='divider for nonlinear response table from the circuit [OPTIONAL]', required=False)
35parser.add_argument('-S','--scip_div',help='skip the divider for the negative nonlinear response table[OPTIONAL]',action="store_true", required=False)
36parser.add_argument('-o','--table_op', metavar='N', type=float, nargs='+', help='step operator multiplier for nonlinear response table from the circuit [OPTIONAL]', required=False)
37parser.add_argument('--oversample', metavar='N', type=int, help='set oversample rate [OPTIONAL]', required=False)
38parser.add_argument('--fixedrate', metavar='N', type=int, help='set fixed samplerate [OPTIONAL]', required=False)
39parser.add_argument('--samplerate', metavar='N', type=int, help='set samplerate to be used in sim (default 96000) [OPTIONAL]', required=False)
40parser.add_argument('--bypass',  help='add bypass switch  [OPTIONAL]',action="store_true", required=False)
41parser.add_argument('-f','--freqsplit', help='use frequency splitter for all filters [OPTIONAL]',action="store_true", required=False)
42parser.add_argument('-N','--nonlinsplit', help='use frequency splitter only for nonlinear response [OPTIONAL]',action="store_true", required=False)
43parser.add_argument('-v','--vectorize', help='generate vectorized loop [OPTIONAL]',action="store_true", required=False)
44parser.add_argument('-V','--vector_size', metavar='N', type=int, help='use vector size N [OPTIONAL]', required=False)
45parser.add_argument('-r','--reduce_gain', metavar='N=value', nargs='+', help='reduce gain output from the circuit N by value [OPTIONAL]', required=False)
46
47
48args = parser.parse_args()
49
50def parse_var(s):
51    items = s.split('=')
52    key = items[0].strip() # we remove blanks around keys, as is logical
53    if len(items) > 1:
54        # rejoin the rest:
55        value = '='.join(items[1:])
56    return (key, value)
57
58
59def parse_vars(items):
60    """
61    Parse a series of key-value pairs and return a dictionary
62    """
63    d = {}
64
65    if items:
66        for item in items:
67            key, value = parse_var(item)
68            d[key] = value
69    return d
70
71os.chdir("../")
72
73comandline = "\n\n/*******************************************************************************\n"
74comandline += "**************************** File generated by *********************************\n"
75comandline += "********************************************************************************\n"
76for arg in sys.argv:
77    comandline += " %s" % arg
78comandline += "\n*******************************************************************************/\n\n"
79
80del sys.argv[1:]
81from analog import *
82import circ_table_gen as ci
83
84faust_table_template = """
85/*******************************************************************************
86  * 1-dimensional function table for linear interpolation
87*******************************************************************************/
88rd = library("reducemaps.lib");
89
90//-- Rdtable from waveform
91rtable(table, r) = (table, int(r)):rdtable;
92
93//-- Copy the sign of x to f
94ccopysign(f, x) = ma.fabs(f) * sign(x);
95
96//-- Get sign of value x
97sign(x) = x<0, 1, -1 : select2;
98
99//-- Check if value x is negative
100fsignbit(x) = x<0;
101
102//-- Get fractal part of value n
103fractal(n) = n - int(n);
104
105//-- Interpolate value between i and i+1 in table with fractal coefficient f.
106interpolation(table, size, f, i) = select2(i<0,select2(i>size-2,
107    rtable(table, i)*(1-f) + rtable(table,i+1)*f, rtable(table, size-1)),
108    rtable(table, 0)) : table_gate(table);
109
110//-- reduce dc-offset (noise) from table response for very low values
111table_gate(table,x) = select2(ma.fabs(x):rd.maxn(4096)<ma.fabs(rtable(table, 1))*(0.12), x, x*x*x);
112
113//-- Linear interpolation for value x in rdtable
114circuit_response(table, low, high, step, size, x) =
115    interpolation(table, size, fractal(linindex(step, x)),
116    int(linindex(step, x))), x : ccopysign;
117
118//-- Calculate linear table index for value x
119linindex(step, x) = ma.fabs(x) * step;
120
121//-- predefined filterbank
122freq_split = fi.filterbank(3, (86.0,210.0,1200.0,6531.0));
123"""
124
125class Filter(object):
126
127    def calc_highpass_f0(self,c1, c2, pot):
128        from scipy.optimize import curve_fit
129        sig = Signal()
130        s = c1.make_signal_vector(sig(0.01*sig.impulse(), timespan=1))
131        f0 = numpy.zeros(11)
132        fl = numpy.logspace(numpy.log10(s.start_freq), numpy.log10(s.stop_freq), 200)
133        w = 2 * numpy.pi * fl / s.fs
134        for i, Level in enumerate(numpy.linspace(0, 1, 11)):
135            c1.set_pot_variable(pot, Level)
136            c1.stream(s)
137            h1 = s.get_spectrum(c1.last_output[:,0], w)
138
139            c2.set_pot_variable(pot, Level)
140            c2.stream(s)
141            h2 = s.get_spectrum(c2.last_output[:,0], w)
142
143            ydata = numpy.log(abs(h1/h2))
144            e = numpy.exp(-1j*w)
145            a1 = -1
146            def f(e, a1):
147                return numpy.log(abs((1-a1)/2 * (1 - e) / (1 + a1 * e)))
148            res = curve_fit(f, e, ydata, a1)
149
150            a1 = res[0][0]
151            f0[i] = s.fs*(1 + a1)/(numpy.pi*(1 - a1))
152        return numpy.mean(f0)
153
154class FrequencyPlot(object):
155
156    def freq_plot(self, c1,name):
157        sig = Signal()
158        s = c1.make_signal_vector(sig(sig.impulse(), timespan=1))
159        c1.stream(s)
160        s.plot_spectrum(c1.last_output)
161        ax = pylab.gca()
162        ax.grid()
163        ax.yaxis.set_major_formatter(pylab.FormatStrFormatter('%d dB'))
164        ax.xaxis.set_major_formatter(pylab.FormatStrFormatter('%d Hz'))
165        pylab.title(name)
166        pylab.xlabel('Frequency')
167        pylab.ylabel('Magnitude')
168        pylab.show()
169
170    def sine_plot(self, c1,name):
171        sig = Signal()
172        s = c1.make_signal_vector(sig(sig.sine(), timespan=0.00907))
173        c1.stream(s)
174        s.plot(c1.last_output)
175        ax = pylab.gca()
176        ax.grid()
177        ax.yaxis.set_major_formatter(pylab.FormatStrFormatter('%d dB'))
178        pylab.title(name)
179        pylab.ylabel('Magnitude')
180        pylab.show()
181
182    def harmonic_plot(self, c1,name):
183        sig = Signal()
184        s = c1.make_signal_vector(sig(sig.sweep()))
185        c1.stream(s)
186        s.plot(c1.last_output,"Harmonic")
187        ax = pylab.gca()
188        ax.grid()
189        ax.yaxis.set_major_formatter(pylab.FormatStrFormatter('%d dB'))
190        ax.xaxis.set_major_formatter(pylab.FormatStrFormatter('%d Hz'))
191        ax.legend()
192        pylab.title(name)
193        pylab.xlabel('Frequency')
194        pylab.ylabel('Magnitude')
195        pylab.show()
196
197class Generators(object):
198
199    def generate_nonlin_table(self, c1, modulename, sig_max, table_op, scip_div, table_neg, table_div=None, faust_table=None):
200        v = ci.Circ_table(modulename, c1.S,c1.V, sig_max, table_op, table_div)
201        parser = dk_simulator.Parser(v.S, v.V, v.FS)
202        p = dk_simulator.get_executor(
203        modulename, parser, v.solver, '-p', c_tempdir='/tmp', c_verbose='--c-verbose',
204        c_debug_load='', linearize='', c_real=("double"))
205        y = p(v.signal())
206        if (faust_table) :
207            td = v.generate_faust_table(p, y,"")
208        else :
209            td = v.generate_table(p, y,"")
210        v.plot(p,y)
211        if (table_neg):
212            if (scip_div) :
213                td = None
214            v = ci.Circ_table(modulename+"_neg", c1.S,c1.V, -1.0*sig_max, table_op, td)
215            parser = dk_simulator.Parser(v.S, v.V, v.FS)
216            p = dk_simulator.get_executor(
217            modulename, parser, v.solver, '-p', c_tempdir='/tmp', c_verbose='--c-verbose',
218            c_debug_load='', linearize='', c_real=("double"))
219            y = p(v.signal())
220            if (faust_table) :
221                v.generate_faust_table(p, y,"")
222            else :
223                td = v.generate_table(p, y,"")
224            v.plot(p,y)
225
226    def write_final_file(self, a, dspfile,fdata,dspfileui,fuidata,freqs,gain_stages,switch=None,stereo=None,faust_table=None,bypass=None):
227        button = ''
228        if not stereo:
229            if not freqs:
230                if (bypass):
231                    process_line = '\n\nbypass = checkbox("Enable[name:Enable");\n'
232                    process_line += "\nproc = "
233                else:
234                    process_line = "\nprocess = "
235                for x in xrange(1,a+1,1):
236                    if str(x) in switch:
237                        process_line += 'ba.bypass_fade(ma.SR/10, 1 - b%s, p%s) ' % (x,x)
238                        button += '\nb%s = checkbox("%s[name:%s");' % (x,switch[str(x)],switch[str(x)])
239                    else:
240                        process_line += ' p%s ' % x
241                    if str(x) in gain_stages:
242                        stage = 'p%s' % x
243                        gain_stage = ' : *(%s)' % gain_stages[str(x)]
244                        process_line = process_line.replace(stage,stage+gain_stage)
245                    if a>x :
246                        process_line += ':'
247                    else :
248                        process_line += ';\n'
249                fdata += button
250                if (bypass):
251                    process_line += '\nprocess = ba.bypass_fade(ma.SR/10, 1- bypass, proc);\n'
252                fdata += process_line
253            else:
254                process_line = "\namp = "
255                for x in xrange(1,a+1,1):
256                    if str(x) in switch:
257                        process_line += 'ba.bypass_fade(ma.SR/10, 1 - b%s, p%s) ' % (x,x)
258                        button += '\nb%s = checkbox("%s[name:%s");\n' % (x,switch[str(x)],switch[str(x)])
259                    else:
260                        process_line += ' p%s ' % x
261                    if str(x) in gain_stages:
262                        stage = 'p%s' % x
263                        gain_stage = ' : *(%s)' % gain_stages[str(x)]
264                        process_line = process_line.replace(stage,stage+gain_stage)
265                    if a>x :
266                        process_line += ':'
267                    else :
268                        process_line += ';\n'
269                if not (faust_table):
270                    process_line += '\nfreq_split = fi.filterbank(3, (86.0,210.0,1200.0,6531.0));\n'
271                if (bypass):
272                    process_line += '\nbypass = checkbox("Enable[name:Enable");\n'
273                    process_line += "\nproc = freq_split: ( amp , amp , amp, amp, amp) :>_;\n"
274                else:
275                    process_line += '\n\nprocess    = freq_split: ( amp , amp , amp, amp, amp) :>_;\n'
276                fdata += button
277                if (bypass):
278                    process_line += '\nprocess = ba.bypass_fade(ma.SR/10, 1- bypass, proc);\n'
279                fdata += process_line
280        else:
281            if not freqs:
282                process_line = "\nchanel = "
283                for x in xrange(1,a+1,1):
284                    if str(x) in switch:
285                        process_line += 'ba.bypass_fade(ma.SR/10, 1 - b%s, p%s) ' % (x,x)
286                        button += '\nb%s = checkbox("%s[name:%s");' % (x,switch[str(x)],switch[str(x)])
287                    else:
288                        process_line += ' p%s ' % x
289                    if str(x) in gain_stages:
290                        stage = 'p%s' % x
291                        gain_stage = ' : *(%s)' % gain_stages[str(x)]
292                        process_line = process_line.replace(stage,stage+gain_stage)
293                    if a>x :
294                        process_line += ':'
295                    else :
296                        process_line += ';\n'
297                if (bypass):
298                    process_line += '\n\nbypass = checkbox("Enable[name:Enable");\n'
299                    process_line += "\nproc = chanel , chanel ;\n"
300                else:
301                    process_line += '\nprocess = chanel , chanel ;\n'
302                fdata += button
303                if (bypass):
304                    process_line += '\nprocess = ba.bypass_fade(ma.SR/10, 1- bypass, proc);\n'
305                fdata += process_line
306            else:
307                process_line = "\namp = "
308                for x in xrange(1,a+1,1):
309                    if str(x) in switch:
310                        process_line += 'ba.bypass_fade(ma.SR/10, 1 - b%s, p%s) ' % (x,x)
311                        button += '\nb%s = checkbox("%s[name:%s");' % (x,switch[str(x)],switch[str(x)])
312                    else:
313                        process_line += ' p%s ' % x
314                    if str(x) in gain_stages:
315                        stage = 'p%s' % x
316                        gain_stage = ' : *(%s)' % gain_stages[str(x)]
317                        process_line = process_line.replace(stage,stage+gain_stage)
318                    if a>x :
319                        process_line += ':'
320                    else :
321                        process_line += ';\n'
322                if not (faust_table):
323                    process_line += '\nfreq_split = fi.filterbank(3, (86.0,210.0,1200.0,6531.0));\n'
324                process_line += "\nchanel = freq_split: ( amp , amp , amp, amp, amp) :>_;\n"
325                if (bypass):
326                    process_line += '\n\nbypass = checkbox("Enable[name:Enable");\n'
327                    process_line += "\nproc = chanel , chanel ;\n"
328                else:
329                    process_line += '\n\nprocess    = chanel , chanel ;\n'
330                fdata += button
331                if (bypass):
332                    process_line += '\nprocess = ba.bypass_fade(ma.SR/10, 1- bypass, proc);\n'
333                fdata += process_line
334        if(faust_table):
335            fdata = fdata.replace('import("stdfaust.lib");', 'import("stdfaust.lib");\n%s') % faust_table_template
336        fdata = comandline + fdata
337        with open(dspfile, 'w') as f:
338            f.write(fdata)
339        f.close()
340        x = 1
341        for line in button.split('\n'):
342            if not len(line.strip()) == 0 :
343                fuidata = fuidata.replace('b.openHorizontalBox("");','b.openHorizontalBox("");\n\n    b.create_switch("minitoggle",PARAM("%s"), "%s");') % (switch[str(x)],switch[str(x)])
344                x = x+1
345        if (bypass):
346            fuidata = fuidata.replace('b.openHorizontalBox("");','b.openHorizontalBox("");\n\n    b.create_switch("switch",PARAM("Enable"), "Enable");')
347
348        with open(dspfileui, 'w') as f:
349            f.write(fuidata)
350        f.close()
351
352    def generate_gx_plugin(self, arg, dspfile, rs, vec, vs, nonlin=None):
353        if nonlin :
354            print ("build nonlin gx_plugin from: %s" % arg)
355        else :
356            print ("build gx_plugin from: %s" % arg)
357        datatype="double"
358        pgm = os.path.abspath("../../build-faust")
359        opts = " " if datatype == "float" else ""
360        if (vec):
361            opts += " -V "
362        if (vs):
363            opts += " -S %s " % vs
364        if (rs):
365            opts += " -r "
366        os.system("%s %s -c -k %s" % (pgm, opts, dspfile))
367
368    def generate_lv2_plugin(self, arg, dspfile, tablename, modulename, name, rs, vec, vs, nonlin=None, nonlin_neg=None, faust_table=None):
369        if nonlin :
370            print ("build nonlin lv2_plugin from: %s" % arg)
371        else :
372            print ("build lv2_plugin from: %s" % arg)
373        p = os.getcwd()
374        os.chdir("buildlv2/")
375        pgm = os.path.abspath("./make_lv2_X11bundle.sh")
376        if (vec):
377            opts = " -V "
378        else:
379            opt = ""
380        if (vs):
381            opts += " -S %s " % vs
382        if not rs :
383            result = os.system("%s -p ../%s %s -n  %s" % (pgm, dspfile, opt, name ))
384        else :
385            result = os.system("%s -p ../%s %s -r -n  %s" % (pgm, dspfile, opt, name ))
386        if (result):
387            print ('\033[91m'+"Error, see message above"+'\033[0m')
388            exit (1)
389        # copy table to bundle
390        if not faust_table :
391            if nonlin :
392                for a in nonlin:
393                    src1 = '../dkbuild/%s_table.h' %  tablename[a-1]
394                    dst1 = 'gx_%s.lv2/dsp/' % modulename
395                    copy2(src1, dst1)
396            if nonlin_neg :
397                for a in nonlin_neg:
398                    src1 = '../dkbuild/%s_neg_table.h' %  tablename[a-1]
399                    dst1 = 'gx_%s.lv2/dsp/' % modulename
400                    copy2(src1, dst1)
401        os.chdir('gx_%s.lv2' % modulename)
402        os.system('make uninstall && make && make install')
403        os.chdir(p)
404
405    def deploy_c(self, c1):
406        c1.build_script = sys.argv[0]
407        c1.backward_euler = True
408        c1.transform_opts.partition = True
409        c1.transform_opts.decompose = True
410        c1.sys_reduce_tol = 1e-5
411        c1.set_tempdir("gencode")
412        c1.keep_tempdir()
413        c1.set_solver(dict(method='hybr', factor=1e5))
414        c1.deploy()
415
416
417class DKbuilder(object):
418
419    name = args.name
420    shortname = args.shortname
421    description = args.description
422    category = args.category
423    oversample = args.oversample
424    fixedrate = args.fixedrate
425    samplerate = args.samplerate
426    faust_table = args.faust_table
427    rs = False
428    freqsplit = args.freqsplit
429    frs = False
430    tablename = {}
431    gain_stages = {}
432    switch = {}
433
434    if (args.table_neg):
435        if (not args.table):
436            args.table = args.table_neg
437        else:
438            args.table += args.table_neg
439
440    if name:
441        modulename = name.lower()
442    else:
443        schema = args.input[0]
444        modulename = schema.split('.')[0].lower()
445
446    if (args.vectorize):
447        vec = True
448    else:
449        vec = False
450
451    if (args.vector_size):
452        vs = args.vector_size
453        vec = True
454    else:
455        vs = 0
456
457    if (args.reduce_gain):
458        gain_stages = parse_vars(args.reduce_gain)
459
460    if (args.switch):
461        switch = parse_vars(args.switch)
462
463    def index_exists(self,ls, i):
464        return (0 <= i < len(ls)) or (-len(ls) <= i < 0)
465
466    def build(self):
467
468        fdata = ""
469        fuidata = ""
470        table_counter = 0
471        dsp_counter = 0
472        ui_counter = 0
473        in_files = len(args.input)
474
475        if not (self.samplerate):
476            self.samplerate = 96000
477
478        g = Generators()
479        c1 = Circuit(FS=self.samplerate)
480
481        # generate faust code and nonlin table
482        for sch in args.input:
483            dsp_counter +=1
484            print ("\nInput file %s: %s" % (dsp_counter, args.input[dsp_counter-1]))
485           # fileName, fileExtension = os.path.splitext(args.input[dsp_counter-1])
486           # if fileExtension == ".dsp":
487           #     read_dsp_file(args.input[dsp_counter-1])
488           #     continue
489
490            schema = args.input[dsp_counter-1]
491            workfile="gschem-schematics/"+schema
492            path = "tmp"
493
494            module_id = args.module_id
495            if not module_id:
496                module_id = self.modulename
497            print ("module_id: %s" % module_id )
498
499            dst = 'dkbuild/%s/' % self.modulename
500            dspname = dst+self.modulename
501            dspfile = dspname+".dsp"
502            dspfileui = dspname+"_ui.cc"
503
504            # set_log_level(INFO)
505            c1.plugindef = dk_simulator.PluginDef(module_id)
506            if not self.name:
507                self.name = module_id
508            c1.plugindef.name = self.name
509            if not self.shortname:
510                self.shortname = self.name
511            c1.plugindef.shortname = self.shortname
512            if not self.description:
513                self.description = self.name
514            c1.plugindef.description = self.description
515            if not self.category:
516                self.category = "Extern"
517            c1.plugindef.category = self.category
518            if self.oversample:
519                c1.plugindef.oversample = self.oversample
520                self.rs = True
521            if self.fixedrate:
522                c1.plugindef.fixedrate = self.fixedrate
523                self.rs = True
524            if self.freqsplit:
525                self.frs = True
526
527            c1.plugindef.id = module_id
528            c1.set_module_id(module_id)
529            c1.read_gschem(workfile)
530            #c1.show_status()
531            #c1.print_netlist()
532
533            if args.plot:
534                f = FrequencyPlot()
535                if args.plot == "harm":
536                    f.harmonic_plot(c1,self.name)
537                elif args.plot == "sine":
538                    f.sine_plot(c1,self.name)
539                else:
540                    f.freq_plot(c1,self.name)
541                # generate faust source and build dir
542            if args.deploy:
543                g.deploy_c(c1)
544            elif args.build or args.buildlv2 or not args.plot:
545                dlimer = """/*******************************************************************************
546  * %s generated by dkbuiler from %s
547*******************************************************************************/
548""" % (schema.split('.')[0].lower(), schema)
549                if not os.path.exists(dst):
550                    os.makedirs(dst)
551                if dsp_counter == 1 :
552                    faustdsp, faustui = c1.get_faust_code(filename=str(dspname))
553                else :
554                    faustdsp, faustui = c1.get_simple_faust_code(filename=str(dspname))
555                if args.table and dsp_counter in args.table:
556                    s = False
557                    tn = False
558                    self.tablename[dsp_counter-1] = schema.split('.')[0].lower()
559                    table_counter += 1
560                    if args.sig_max and self.index_exists(args.sig_max,table_counter-1) :
561                        m = args.sig_max[table_counter-1]
562                    else :
563                        m = 1.4
564                    if args.table_op and self.index_exists(args.table_op,table_counter-1):
565                        o = args.table_op[table_counter-1]
566                    else:
567                        o = 1.0
568                    if args.table_div and self.index_exists(args.table_div,table_counter-1):
569                        d = args.table_div[table_counter-1]
570                    else:
571                        d = None
572                    if args.table_neg and dsp_counter in args.table_neg:
573                        tn = True
574                        if (args.scip_div):
575                            s = True
576                    g.generate_nonlin_table(c1, self.tablename[dsp_counter-1], m, o, s, tn, d,args.faust_table)
577                    if (args.faust_table) :
578                        tsrc = 'dkbuild/%s_table.lib' %  self.tablename[dsp_counter-1]
579                        with open(tsrc, 'r') as f:
580                            mytable = f.read()
581                        f.close()
582                    else:
583                        src = 'dkbuild/%s_table.h' %  self.tablename[dsp_counter-1]
584                        # copy table to build dir
585                        copy2(src, dst)
586                    if (tn) :
587                        if (args.faust_table) :
588                            tsrc = 'dkbuild/%s_neg_table.lib' %  self.tablename[dsp_counter-1]
589                            with open(tsrc, 'r') as f:
590                                myneg_table = f.read()
591                            f.close()
592                        else :
593                            src = 'dkbuild/%s_neg_table.h' %  self.tablename[dsp_counter-1]
594                            # copy table to build dir
595                            copy2(src, dst)
596                    # include table use in faust code
597                    if (tn):
598                        faustdsp = faustdsp.replace('with', ': %sclip with' ) % self.tablename[dsp_counter-1]
599                        if (args.faust_table) :
600                            faustdsp = faustdsp.replace('//TABLE', '%s\n%s') % (mytable,myneg_table)
601                            faustdsp = faustdsp.replace('process', '%s\nprocess') % dlimer
602                            if (args.nonlinsplit):
603                                faustdsp +=  '\n{st}p = _<: ba.if(fsignbit(_), {st}_neg_clip, {st}_clip) :>_ ;\n'.format(st=self.tablename[dsp_counter-1])
604                                faustdsp += '\n{st}clip = freq_split: ( {st}p , {st}p , {st}p, {st}p, {st}p) :>_;\n'.format(st=self.tablename[dsp_counter-1])
605                            else:
606                                faustdsp +=  '\n{st}clip = _<: ba.if(fsignbit(_), {st}_neg_clip, {st}_clip) :>_ ;\n'.format(st=self.tablename[dsp_counter-1])
607                        else:
608                            faustdsp = faustdsp.replace('//TABLE', '\n\n%s') % dlimer
609                            if (args.nonlinsplit):
610                                faustdsp +=  '\n{st}p = _<: ba.if(signbit(_), {st}_neg_clip, {st}_clip) :>_  with  '.format(st=self.tablename[dsp_counter-1])
611                                faustdsp +=  '{\n'
612                                faustdsp +=  '\n    signbit = ffunction(int signbit(float), "math.h", "");\n'
613                                faustdsp +=  '\n    {st}_clip = ffunction(float {st}clip(float), "{st}_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
614                                faustdsp +=  '\n    {st}_neg_clip = ffunction(float {st}_negclip(float), "{st}_neg_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
615                                faustdsp +=  '\n};\n'
616                                faustdsp += '\n{st}clip = freq_split: ( {st}p , {st}p , {st}p, {st}p, {st}p) :>_;\n'.format(st=self.tablename[dsp_counter-1])
617                            else:
618                                faustdsp +=  '\n{st}clip = _<: ba.if(signbit(_), {st}_neg_clip, {st}_clip) :>_  with  '.format(st=self.tablename[dsp_counter-1])
619                                faustdsp +=  '{\n'
620                                faustdsp +=  '\n    signbit = ffunction(int signbit(float), "math.h", "");\n'
621                                faustdsp +=  '\n    {st}_clip = ffunction(float {st}clip(float), "{st}_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
622                                faustdsp +=  '\n    {st}_neg_clip = ffunction(float {st}_negclip(float), "{st}_neg_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
623                                faustdsp +=  '\n};\n'
624                    else :
625                        if not (args.nonlinsplit):
626                            faustdsp = faustdsp.replace('with', ': %s_clip with' ) % self.tablename[dsp_counter-1]
627                        else:
628                            faustdsp = faustdsp.replace('with', ': %sp with' ) % self.tablename[dsp_counter-1]
629                        if (args.faust_table) :
630                            faustdsp = faustdsp.replace('//TABLE', '\n%s') % mytable
631                            if (args.nonlinsplit):
632                                faustdsp += '\n    {st}p = freq_split: ( {st}_clip , {st}_clip , {st}_clip, {st}_clip, {st}_clip) :>_;\n'.format(st=self.tablename[dsp_counter-1])
633                        else :
634                            faustdsp = faustdsp.replace('//TABLE', '')
635                            if (args.nonlinsplit):
636                                faustdsp = faustdsp.replace('with', ': %s_clip with' ) % self.tablename[dsp_counter-1]
637                                faustdsp += '\n    freq_split = fi.filterbank(3, (86.0,210.0,1200.0,6531.0));\n'
638                                faustdsp +=  '\n    {st}p = ffunction(float {st}clip(float), "{st}_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
639                                faustdsp += '\n    {st}_clip = freq_split: ( {st}p , {st}p , {st}p, {st}p, {st}p) :>_;\n'.format(st=self.tablename[dsp_counter-1])
640                            else:
641                                faustdsp +=  '\n    {st}_clip = ffunction(float {st}clip(float), "{st}_table.h", "");\n'.format(st=self.tablename[dsp_counter-1])
642                else:
643                    faustdsp = faustdsp.replace('//TABLE', '\n\n%s') % dlimer
644                faustdsp = faustdsp.replace('process', "p%s" % dsp_counter)
645                fdata += faustdsp
646                if faustui:
647                    ui_counter +=1
648                    if (ui_counter ==2) and ( dsp_counter != in_files):
649                        fuidata = fuidata.rsplit("\n", 2)[0]
650                        faustui = faustui.replace('b.openHorizontalBox("");\n', '')
651                        faustui = faustui.replace('b.closeBox();\n', '')
652                    elif (ui_counter ==2) and ( dsp_counter == in_files):
653                        fuidata = fuidata.rsplit("\n", 2)[0]
654                        faustui = faustui.replace('b.openHorizontalBox("");\n', '')
655                    elif (ui_counter >2) and ( dsp_counter != in_files):
656                        fuidata = fuidata.rsplit("\n", 1)[0]
657                        faustui = faustui.replace('b.openHorizontalBox("");\n', '')
658                        faustui = faustui.replace('b.closeBox();\n', '')
659                    elif (ui_counter >2) and ( dsp_counter == in_files):
660                        fuidata = fuidata.rsplit("\n", 1)[0]
661                        faustui = faustui.replace('b.openHorizontalBox("");\n', '')
662                elif (ui_counter >1) and ( dsp_counter == in_files):
663                    faustui += 'b.closeBox();\n'
664                fuidata += faustui
665
666        if any ([args.build, args.buildlv2, args.buildfaust]):
667            g.write_final_file(dsp_counter,dspfile,fdata,dspfileui,fuidata,self.frs,self.gain_stages,self.switch,args.stereo,args.faust_table,args.bypass)
668        # create a guitarix module
669        if args.build or (not args.table and not args.plot and not args.buildlv2 and not args.buildfaust and not args.deploy) :
670            g.generate_gx_plugin(args.input, dspfile, self.rs, self.vec, self.vs, args.table)
671        # create a LV2 module
672        elif args.buildlv2 :
673            g.generate_lv2_plugin(args.input, dspfile, self.tablename, self.modulename, self.name, self.rs, self.vec, self.vs, args.table, args.table_neg, args.faust_table)
674
675def main(argv):
676    dk = DKbuilder()
677    dk.build()
678
679if __name__ == "__main__":
680    main(sys.argv[1:])
681