***Warning: experimental/unfinished code, incomplete documentation...***

This directory contains tools for analog electronic circuit simulation, like e.g. Spice
but with an emphasis on automatic code generation for real-time execution
(which means it can directly generate Guitarix modules).

The DK simulator uses the "DK method" and generates/compiles optimized C++ code internally
for signal calculations. it is based on the thesis
"Real-time Digital Simulation of Guitar Amplifiers as Audio Effects" by JAROMÍR MAČÁK
 (see https://www.vutbr.cz/www_base/zav_prace_soubor_verejne.php?file_id=60090)
Other useful informations can be found in the thesis
"Simulation Framework for Analog Audio Circuits based on Nodal DK Method" by Piero Rivera Benois
 (see https://www.researchgate.net/publication/263013830_Simulation_Framework_for_Analog_Audio_Circuits_based_on_Nodal_DK_Method)


I) Circuit creation

The simulated circuit is defined by a "netlist", which is easy to write manually (see circ.py).
Circuit schematics can also be drawn with gEDA Schematic Editor (gschem, part of gEDA).
    The gschem files (.sch) in the gschem-schematics directory use additional symbols
    which are in the subdirectory gschem-symbols. Before opening them with gschem
    please add a line
        (component-library "")
    to the file ~/.gEDA/gafrc (of course replace the <...> with the real path).


II) Software ecosystem

It is highly recommended to create a Python 2.7 virtual environment dedicated to Guitarix.
 (see https://packaging.python.org/guides/installing-using-pip-and-virtualenv/
  and https://virtualenvwrapper.readthedocs.io/en/latest/index.html)
This ensures any system update will not interfere with the Python packagesused by Guitarix and its tools.
Packages requirements are listed in the file python_venv which can be used to setup the virtual environment
    Debian/Ubuntu quickstart:
    - Install the virtualenvwrapper package and its eventual dependencies
    - add the following lines to your .bashrc
        export WORKON_HOME=$HOME/.virtualenvs
        export PROJECT_HOME=$HOME/Devel
        source /usr/share/virtualenvwrapper/virtualenvwrapper.sh
    - restart your shell and run
        mkvirtualenv -r python_venv guitarix
    Once the setup is complete, you can type 
        workon guitarix
    to switch to the dedicated Python virtual environment for Guitarix and
        deactivate
    to return to your default/system Python environment    

Additional dependencies:
- Faust 0.9.90
- for internally generated C++ module:
    - libeigen3-dev
    - libcminpack-dev
    - libsundials-serial-dev
- to generate symbolic output (e.g. Faust code):
    - maxima
- (at least on debian / ubuntu): package maxima-share (add-on packages)


III) Examples:

- in the DK directory, run "python simu.py", then select e.g. 11 (Transistor).
    You can disable C code generation by adding option -p (the calculation will be about a factor of 100 slower).
    You can add -c to perform all tests in one run.

- create a Guitarix module from the schematic gschem-schematics/BlueClipper.sch:
    run "python build-blueclipper.py" from the scripts directory.
    This script shows and automates the recommended workflow explained below.
    It generates the diode_table.h file, splits the circuit into input and output parts,
    adds the nonlinear function call between them and generates the Guitarix module
    with the nonlinear part included. So the processing is then
    linear IIR filter, nonlinear table response, linear filter.


IV) Workflow:

The Faust code generated by the DK simulator fetches only the linear behavior of a circuit.
The generated filter is an IIR filter (Infinity Impulse Response). We can only fetch
the nonlinear behavior when we generate C++ code (analog.py/Circuit.deploy())
but this code eats a lot more CPU then acceptable, hence it requires a lot of
handmade optimizations, as seen in the build_jcm800.py script.

So the recommended route is to generate the linear Faust filter and add
the nonlinear behavior as clipping table. Therefore the circuit is split into pieces.
For the case of the FuzzFaceJH1 for example, the P2 Volume pot is replaced by a 1000k resistor
and the output set above it, so the circuit runs on full level.
Then the MPSA18_table.h is generated from the trany_table-gen.py script and added into the source folder.

Then the process in the dsp file is replaced with p1.
For example, add a new line below the filter like this:
    clip = ffunction(float tranyclip(float), "MPSA18_table.h", "");

and put a new process line
    process = p1 : clip;

Now we have the linear filter followed by the nonlinear behavior simulated by the table response.
The Volume pot is missing though. There are two ways to implement this one.

One way is to declare it at the beginning of the dsp file
    declare volume_p "Volume";

were the string is the name of the Pot. The dsp2cc script will then add a volume control at the end of the process.

The other way is to generate the output circuit (after the split) and add it as p2 to the formerly generated code.
The process line will then look like this:
    process = p1 : clip : p2;

This is how the Gxplugins have been generated lately. Sometimes the circuit is split into multiple pieces
to achieve lower order IIR filters (they will be more stable then higher order ones)
which then are stitched together like the description above.

Once this is done, you can now generate the Guitarix module with the build_Faust script
from the tools folder or you can copy the Faust file over to buildlv2/ and generate
a LV2 plugin with the make_lv2_bundle.sh script.

When building a LV2 plugin you must copy over the generated table(s) to the generated gx_yourname.lv2/dsp/ folder.

example command line for the make_lv2_bundle.sh script:
    ./make_lv2_bundle.sh -p AdamuBass.dsp -n AdamuBassDistortion


V)TODO
Explain how to perform signal analysis (plot spectrums, response curves).
In the previous README:
    Look at the spectrum of the WahWah processing (uses the wahwah circuit netlist from circ.py):
    python simu.py --linearize WahWah --plot-spectrum --plot-variable=hotpotz
(does not work anymore, needs to be fixed)
