dkbuilder: from circuit to LV2 plugin

Programming applications for making music on Linux.

Moderators: MattKingUSA, khz

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Dominique wrote: Mon Sep 16, 2024 9:16 am

Code: Select all

$ python simu.py
/usr/share/guitarix/tools/ampsim/DK/simu.py:1041: SyntaxWarning: "is" with a literal. Did you mean "=="?
  d['pre_filter'] = '_' if pre_filter is None or pre_filter is "dry_wet" else pre_filter

I changed the is by == and it seam to work.

I found https://adamj.eu/tech/2020/01/21/why-do ... s-literal/ on 'is'' for identity, the same object, versus '==' for equality, the same value. It seam to be sure to do that change. == is already used in the same function for other pre_filter tests.

tramp
Established Member
Posts: 2418
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 11 times
Been thanked: 535 times

Re: dkbuilder: from circuit to LV2 plugin

Post by tramp »

Dominique wrote: Tue Sep 17, 2024 10:47 am

It seam to be sure to do that change. == is already used in the same function for other pre_filter tests.

Yes, that is "saver" now with python3

Dominique wrote: Tue Sep 17, 2024 8:53 am

According to Python - regular expression syntax, it is due to the addition of the support of nested sets and set operations as in Unicode Technical Standard #18, and we can-must escape the [.

Yes, that looks good to me.

Does that mean you've already working the tests with python3?

On the road again.
Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

tramp wrote: Tue Sep 17, 2024 2:22 pm

Does that mean you've already working the tests with python3?

Yes, I cloned guitarix on github and made a dkbuilder branch. https://github.com/domichel/guitarix/tree/dkbuilder

Code: Select all

$ python simu.py
/usr/share/guitarix/tools/ampsim/DK/quik.py:408: FutureWarning: Possible nested set at position 8
  KEYVALSEP = re.compile(r'[ \t]*:[[ \t]*(.*)$', re.S)
 0: Choke
 1: Diode_clipper
 2: Diode
 3: Fuzz
 4: InvOpAmp
 5: LinOpAmp
 6: Pentode2
 7: Pentode
 8: Pot
 9: Preamp
10: PushPullTransformer
11: Resonator
12: Tonestack
13: Transformer_GC
14: Transistor
15: Triode1
16: Triode2
17: WahWah_ss
18: WahWah

Please select: 0
Traceback (most recent call last):
  File "/usr/share/guitarix/tools/ampsim/DK/simu.py", line 1452, in <module>
    main()
  File "/usr/share/guitarix/tools/ampsim/DK/simu.py", line 1448, in main
    plot_output(g, tests, args)
  File "/usr/share/guitarix/tools/ampsim/DK/simu.py", line 1252, in plot_output
    plot_one(g[t](), args, t)
  File "/usr/share/guitarix/tools/ampsim/DK/simu.py", line 1219, in plot_one
    p = dk_simulator.get_executor(
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 1831, in get_executor
    sim = SimulatePy(EquationSystem(parser), solver)
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 908, in __init__
    self.calc_dc(parser.op, method=dc_method)
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 1055, in calc_dc
    self.v0 = self.solve_using_homotopy(func, self.v0).x
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 999, in solve_using_homotopy
    res = self.solve(func, v0, args=(points[1],), method=method, options=options)
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 985, in solve
    res = opt.root(func, v0, args=args, method=method, options=options)
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/scipy/optimize/_root.py", line 236, in root
    sol = _root_hybr(fun, x0, args=args, jac=jac, **options)
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py", line 232, in _root_hybr
    shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py", line 29, in _check_func
    res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
  File "/usr/share/guitarix/tools/ampsim/DK/dk_simulator.py", line 1054, in func
    return (p + Hc1 * fact + KK * self.calc_i(v) - ml.matrix(self.eq.CZ * v).T).A1
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/numpy/matrixlib/defmatrix.py", line 221, in __mul__
    return N.dot(self, asmatrix(other))
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/numpy/matrixlib/defmatrix.py", line 70, in asmatrix
    return matrix(data, dtype=dtype, copy=False)
  File "/home/dom/.virtualenvs/guitarix/lib/python3.9/site-packages/numpy/matrixlib/defmatrix.py", line 118, in __new__
    warnings.warn('the matrix subclass is not the recommended way to '
PendingDeprecationWarning: the matrix subclass is not the recommended way to represent matrices or deal with linear algebra (see https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). Please adjust your code to use regular ndarray.

In fact they removed these functions. I took an incomplete look into the numpy's release note. They say they will keep the compatibility for existing code with the 2.0 series, but that's not true, it issue the same traceback.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

As I need a working dkbuilder, I begun to experiment with the current docker env. The build-plug.py script is working fine, but when I compile the generated code into my regular user env, and compile it with gcc13, I get a severe warning:

Code: Select all

/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: warning: gui/pswitch.o: missing .note.GNU-stack section implies executable stack
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker

It compile and run, but it is a matter of time for that issue to become an error.

simu.py fail with the docker image, that because the Tcl stuff need a X display. So maybe I will try to add fvwm and a xterm into it, and run it with x11docker: https://github.com/mviereck/x11docker

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Dominique wrote: Wed Sep 18, 2024 7:58 pm

simu.py fail with the docker image, that because the Tcl stuff need a X display. So maybe I will try to add fvwm and a xterm into it, and run it with x11docker: https://github.com/mviereck/x11docker

I found a smarter solution. See https://askubuntu.com/questions/1161646 ... ion-window

It is just to pass the current DISPLAY and the X temporary directory to docker run:

Code: Select all

-e DISPLAY \
       -v "${gitpath}":/mnt/data -v /tmp/.X11-unix:/tmp/.X11-unix

in docker-dkbuilder.

In most system, it may be necessary to run 'xhost local:docker' before docker-dkbuilder.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

The BlowMe preamplifier:
https://pastebin.com/dciYizPf
The BlowMe amplifier:
https://pastebin.com/AZgfpSRf

I build them with:

Code: Select all

# ./build-plug.py -i BlowMePreAmp-orig.sch --buildlv2 -n BlowMePreAmplifier
# ./build-plug.py -i BlowMeAmp-orig.sch --buildlv2 -n BlowMeAmplifier
# ./build-plug.py -i BlowMePreAmp-orig.sch BlowMeAmp-orig.sch --buildlv2 -n BlowMeAmpMono
# ./build-plug.py -i BlowMePreAmp-orig.sch BlowMeAmp-orig.sch -2 --buildlv2 -n BlowMeAmpStereo

They works fine into guitarix.

I try to build it with --bypass, but it fail:

Code: Select all

./build-plug.py -i BlowMePreAmp-orig.sch BlowMeAmp-orig.sch --bypass --buildlv2 -n BlowMeAmpMono
...
../dkbuild/blowmeampmono//blowmeampmono.dsp : 88 : ERROR : undefined symbol : bypass_fade
Traceback (most recent call last):
  File "../../..//dsp2cc", line 2376, in <module>
    main()
  File "../../..//dsp2cc", line 2356, in main
    options)
  File "../../..//dsp2cc", line 601, in __init__
    self.faust_version = headvers.group(3)
AttributeError: 'NoneType' object has no attribute 'group'
Error, see message above

Also, I was a little bit confused by the volume at first, because the blowmepreamp add a lot of gain. Together with its amp, to be useful, the master and drive volume of the main guitarix amp must be set to their minimum. So I have done a new settings bank. In the preamp, the input volume is set as value=1M,var=Input,a=3, and the same with 680k in the amp.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

I made a version of the BlowMeAmp with an attenuator at its output.
https://pastebin.com/f8uLR4gg

Now, with its volume knobs in the middle, One will get about the same volume than when it is bypassed. Which make it usable as a lv2 plugin in hosts like jalv.

With the first version, such an amplifier (the build with preamp + amp) will have a sensitivity of around 1.2 mV for 55 WRMS on 8 ohms at its output, which give 1.2 mV for about 21 V => a voltage gain of around 17'480. With the attenuator, the voltage gain at full volume is around 23.28, which is more than enough to put the vu-meter in the red.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Playing with dkbuiilder, I saw that libzita-resampler-dev is missing into the Dockerfile.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Dominique wrote: Mon Sep 23, 2024 11:20 pm

Now, with its volume knobs in the middle, One will get about the same volume than when it is bypassed. Which make it usable as a lv2 plugin in hosts like jalv.

Another solution to get that is to change a=3 to a=17 or 16 for the master volume into the original version. For the same price, you will get the full gain when that volume is set full. :lol:

But I prefer the sound of the first version with the Master of the gxhead at its minimum. I give the same volume than with n=17 and Master gxhead at full, but the loudness is better.

Maybe because the decoupling caps of the BlowMe are calculated in order to get a good bandwidth with no phase shift in the basses. They are parts of a RC net, and the issue with such filters is that the phase shift begin 1 decade before the - 3 dB voltage shift. Which imply that, in order to get no phase shift in the basses, the cap values are calculated one decade lower than wanted for the voltage shift. Which imply that amp can be used for all possible use cases.

Even with an amplifier with feedback, it is good to do so, because the feedback will not have to correct the phase and the resulting sound will be much more precise and punchy into the basses. In real hardware, put a second cap, a good quality paper or polypropylene cap of a few hundreds nF, in parallel to the decoupling caps. It is for the trebles and will give the same sonic result than using a huge value paper cap (if it is possible to find it...), but for a much better price.

Last edited by Dominique on Wed Sep 25, 2024 7:11 am, edited 1 time in total.
Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Dominique wrote: Mon Sep 23, 2024 6:24 pm

I try to build it with --bypass, but it fail:

Code: Select all

./build-plug.py -i BlowMePreAmp-orig.sch BlowMeAmp-orig.sch --bypass --buildlv2 -n BlowMeAmpMono
...
../dkbuild/blowmeampmono//blowmeampmono.dsp : 88 : ERROR : undefined symbol : bypass_fade
Traceback (most recent call last):
  File "../../..//dsp2cc", line 2376, in <module>
    main()
  File "../../..//dsp2cc", line 2356, in main
    options)
  File "../../..//dsp2cc", line 601, in __init__
    self.faust_version = headvers.group(3)
AttributeError: 'NoneType' object has no attribute 'group'
Error, see message above

I get about the same error with the --table option and EQ.sch. It look like the cause is that faust-0.9.90 was removed from Buster and updated to 2.14.4.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

But that doesn't matter. For EQ.sch, it is no ground and if I add one with a 10meg resistor, it build. So I think that for --bypass to work, it must be implemented into the schematic in some way.

tramp
Established Member
Posts: 2418
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 11 times
Been thanked: 535 times

Re: dkbuilder: from circuit to LV2 plugin

Post by tramp »

bypass_fade is a basic function in faust:
https://faustlibraries.grame.fr/libs/ba ... ypass_fade

There is always the chance that a circuit fail to build, for various reasons.

Dominique wrote: Tue Sep 24, 2024 3:58 pm

AttributeError: 'NoneType' object has no attribute 'group'

That means that dkbuilder fail to generate working dsp code from the circuit, if that happen there are only the controls which been added by build-plug.py
Then, beside the complete dsp code,

Code: Select all

import("stdfaust.lib");

is missing and therewith the definition of the bypass_fade.

The later conversation from dsp to c++ is done by the dsp2cc script, which works nicely with the latest faust version, so you don't need to take care which faust version you use.

Anyway, my workflow have changed to XUiDesigner this day's, I only generate faust dsp files with the dkbuilder and then generate a LV2 plug with XUiDesigner. This makes it easier for me to work on the GUI, and it allow to add a real bypass switch.

On the road again.
Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

tramp wrote: Wed Sep 25, 2024 11:08 am

Anyway, my workflow have changed to XUiDesigner this day's, I only generate faust dsp files with the dkbuilder and then generate a LV2 plug with XUiDesigner. This makes it easier for me to work on the GUI, and it allow to add a real bypass switch.

Thank You for the tips and the good work. XUIDesigner seam to be a great tool. I will make a gentoo ebuild for it and publish it into the proaudio-audio overlay.

I begun to work on the most complicated part of the BlowMe, a 3 bands tone control. With it, I saw that the plot option of build-plug.py is really great. It begun to run fine, but Q=0.5 doesn't seam to be the right Q for RLC filters in such a context. The sound is good, but the freq plot is a little bit chaotic at the chosen Fc. I think I will work on one band at a time, and combine them later.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

Dominique wrote: Thu Sep 26, 2024 3:16 pm

Thank You for the tips and the good work. XUIDesigner seam to be a great tool. I will make a gentoo ebuild for it and publish it into the proaudio-audio overlay.

I am also thinking about a gentoo bug report to add it into the main tree, which, as dkbuilder is needed to generate the dsp code, imply that I must provide a main tree compatible version of my guitarix[dkbuilder] ebuild. For that, it will provide a version of the docker script and associated files that will let the user install dkbuilder in /home/$(id -un)/<some_path> with a single command in $PATH (in /usr/bin). It is almost done, I still have to pass the user that do the build to RUN into the DockerFile and test it from /usr/bin.

Dominique
Established Member
Posts: 109
Joined: Sat May 26, 2018 10:24 am
Has thanked: 5 times
Been thanked: 5 times

Re: dkbuilder: from circuit to LV2 plugin

Post by Dominique »

It is still something I don't understand with the --table option and the non linear concept. With that schematic of a 2 ways RLC tone control: https://pastebin.com/nmL3y2cQ

even if it doesn't do what I want for now,

Code: Select all

./build-plug.py  -i B2ToneEQ-origQeA.sch -p freq --buildlv2 -n B2ToneEQOrigQeA

works fine, but if I add '--table 1' after '-p freq', it fail with

Code: Select all

../dkbuild/b2toneeqorigqe//b2toneeqorigqe.dsp : 48 : ERROR : syntax error, unexpected SUB, expecting LPAR or DEF
Traceback (most recent call last):
  File "../../..//dsp2cc", line 2376, in <module>
    main()
  File "../../..//dsp2cc", line 2356, in main
    options)
  File "../../..//dsp2cc", line 601, in __init__
    self.faust_version = headvers.group(3)
AttributeError: 'NoneType' object has no attribute 'group'

So, according to the message, I can think that something is wrong with my schematics, but this is surprising because it works fine without the table option. What is needed into a schematic for the table option to work?

Another issue for me is to know when the table option is needed. In other terms, what makes a circuit to behave in such a non linear way that the table option is needed?

Post Reply