// -*- mode: adoc; -*-
// SPDX-License-Identifier: LAL-1.3 or CC-BY-SA-4.0

:lang: en

= User manual
Jean Pierre Cimalando, Christopher Arndt
v0.2.0
:toc:

[.Lead]
This documents describes usage of the
https://github.com/SpotlightKid/faustdoctor[*Faust Doctor*], a flexible
code generator for Faust source files. https://faust.grame.fr/[Faust], or
"Functional Audio Stream", is a programming language and compiler for signal
processing developed at http://www.grame.fr/[GRAME].

NOTE: If you encounter a problem with the software, please open an issue on the
project page: https://github.com/SpotlightKid/faustdoctor/issues

== Description

This is a code generator for Faust with a particularity: it offers advanced
control on the format of generated code.

Usually, the code output from the Faust compiler will be a single
implementation file written in C++ or another language, and it exposes some
methods to instantiate the object, control it, and access some of its
characteristics.

However, because such generated code is so monolithic, it is not always easy to
embed it as a part of a larger program, in a separate compilation model,
without violating the _DRY principle_ ("Don't repeat yourself"). These units
also offer some introspection abilities, whose model is dynamic rather than
static, which may be considered unpractical.

The novelty of this post-processor over Faust is to substitute the concept of
_architectures_, used to generate many flavors of programs, with _architecture
templates_ whose processing is backed by a
https://jinja.palletsprojects.com/[templating engine]. The concepts are quite
similiar, except templates allow to express it with greater power.

== Quick start

This needs the Faust compiler version 0.9.85 or greater, as well as faustdoctor
installed on the system.

The following is the minimal invocation of the program. The result is a pair of
files, a source and a header, ready to by included in a project.

....
faustdr -DIdentifier=MyEffect -a generic.cpp MyEffect.dsp > MyEffect.cpp
faustdr -DIdentifier=MyEffect -a generic.hpp MyEffect.dsp > MyEffect.hpp
....

These options are *required*:

* `-DIdentifier=MyEffect`: this defines the name of the class in generated
  source code.
* `-a generic.cpp`: this selects the architecture file to use. For most cases,
  `generic` is adequate; it is available under the `architectures` directory.

== Command-line options

The program may be invoked with the following options:

* `-a <architecture-file>`: selects the architecture file to use. This is a
  template file expressed in https://jinja.palletsprojects.com/[Jinja2] syntax.
* `-D<name=value>`: defines a variable in the environment of the template
  engine, to modify the behavior of the generation.
* `-X<faust-arg>`: passes the `faust-arg` argument to the Faust compiler. These
  arguments are passed to the compiler in the same order as they are specified.
  For example, if you want to enable double precision processing, pass
  `-X-double`.

WARNING: If you use `-X` options to generate multiple related files, such as
`.cpp` and `.hpp` files, make absolutely sure to pass the same `-X` flags in
every invocation of the program.

== Using the provided templates

The program comes with its own set of templates, which can be used directly or
adapted to particular needs. The templates are located under the
`architectures` folder of the software distribution.

The templates can be parameterized with `-D` options, which are explained in
their respective sections.

Refer to the `examples` directory for a few examples which use these templates.

=== The generic template

The `generic` template produces a class which is ready to include in other
source code for direct use.

The result offers the following abilities:

* a split generation into a header and an implementation file
* a direct introspection of the characteristics of the controls
* recognition of some custom metadata for widgets: `[symbol:]`, `[trigger]`, `[boolean]`, `[integer]`
* named getters and setters for the controls
* a simplified signature for the processing routine

[#generic-options]
==== Options

`-DIdentifier=<id>`::
The name of the generated class which wraps the processing code of the Faust
module. *[String]*

[#generic-metadata]
==== Metadata

`Widget.meta.symbol`::
The C-style identifier which names the control in the generated code, and its
getter/setter pair. *[String]* +
The name is also adequate for use with the `lv2:symbol` property of the LV2
plugin specification.

`Widget.meta.trigger`::
This indicates that the widget works like a trigger, similarly to the `button`
widget. *[Boolean]* +
Setting this property on `hslider` or `vslider` allows to define the value
domain.

`Widget.meta.boolean`::
This indicates that the widget works like a boolean, similarly to the
`checkbox` widget. *[Boolean]* +
Setting this property on `hslider` or `vslider` allows to define the value
domain and the initial value.

`Widget.meta.integer`::
This indicates that the widget is valued on an integer scale. *[Boolean]*

=== The oversampled template

The `oversampled` template produces a class which operates exactly like
`generic` from user perspective,except it implements transparent oversampling
by a fixed factor.

The source code of the Faust module should be adapted to take in consideration
the oversampling ratio, as defined by this Faust statement: `OS = fconstant(int
gOversampling, <math.h>);`

It accepts all options recognized by the `generic` template, as well as
additional ones as documented below.

==== Options

See also <<generic-options,Generic template options>>.

`-DOversampling=<ratio>`::
The oversampling ratio, which is either of the following values:
`1`, `2`, `4`, `8`, `16`. *[Integer]*

==== Metadata

See also <<generic-metadata,Generic template metadata>>.

== Creating architecture templates

The template files are expressed in https://jinja.palletsprojects.com/[Jinja2]
syntax.

These files are mostly comprised of static text, and particular tags inside of
it which are interpreted by the templating engine,

* `+{{...}}+` blocks are known as *expressions*, they substitute with the
  evaluation of their content.
* `+{%...%}+` blocks are known as *statements*, they can express control flow
  such as iterations and conditionals.
* `+{#...#}+` blocks are known as *comments*, they are ignored.

Refer to the documentation of the templating engine for details.

To get a better idea, examine existing templates from the `architectures`
folder.

=== Template variable reference

A set of variables are made available to the template, describing the Faust
source which is compiled.

`name`::
The name of the Faust module. *[String]*

`author`::
The author of the Faust module. *[String]*

`copyright`::
The copyright of the Faust module. *[String]*

`license`::
The license of the Faust module. *[String]*

`version`::
The version of the Faust module. *[String]*

`classname`::
The name of the class generated by this Faust module. *[String]*

`filename`::
The name of the Faust source file, without any leading path components. *[String]*

`inputs`::
The number of signal inputs. *[Integer]*

`outputs`::
The number of signal outputs. *[Integer]*

`meta`::
A dictionary containing all the file-level metadata. *[Object]* +
In Faust source code, this is the information provided by `declare` statements
at the top-level.

`active`::
A list of all the active controls for this Faust module. *[List of Widget]* +
Active controls are input parameters, represented by buttons, sliders or knobs.

`passive`::
A list of all the passive controls for this Faust module. *[List of Widget]* +
Passive controls are output parameters, usually used for display or analysis
purposes.

`classcode`::
The source code of the class generated by the Faust compiler, in raw and
minimal form. *[String]*

==== The Widget object

`Widget.type`::
The type of the widget. *[String]* +
This is one of the following values:

* actives: `button`, `checkbox`, `vslider`, `hslider`, `nentry`
* passives: `vbargraph`, `hbargraph`

`Widget.label`::
The display name of the widget. *[String]*

`Widget.varname`::
The identifier of the instance variable which holds the value of the widget. *[String]*

`Widget.init`::
The default value of the widget. *[Number]*

`Widget.min`::
The minimum value of the widget. *[Number]*

`Widget.max`::
The maximum value of the widget. *[Number]*

`Widget.step`::
The step value, or resolution of the widget. *[Number]*

`Widget.unit`::
The unit of the values accepted by the widget. *[String]*

`Widget.scale`::
The scale of the widget. *[String]* +
The standard scale values in Faust are the following: `linear`, `log`, `exp`

`Widget.tooltip`::
A short description text which is adequate for tooltip popup window. *[String]*

`Widget.meta`::
A dictionary containing all the widget-level metadata. *[Object]* +
In Faust source code, this is the information provided in the widget name
argument using `[key]` or `[key:value]` notation.

=== Template function reference

Some functions are available to assist with the task of source code generation.

`cstr(str)`::
Convert a string to a quoted string literal in C syntax. *[String] → [String]*

`cid(str)`::
Convert a string to an identifier which is valid in C syntax. *[String] → [String]*

== The C++ specifics

The implementation details of the C++ output may be modified, by defining some
macros preceding the expansion of the Faust-generated code produced by
`{{classcode}}`.

By default, it produces identical behavior to the original Faust code.

This is a description of the macros available.

`FAUSTDR_PRIVATE`::
A substitution for the `private` language keyword. *[default: private]* +
It permits to access a control variable defined by `Widget.var` directly,
instead of retrieving a pointer by other dynamic means.
----
#define FAUSTDR_PRIVATE public
----

`FAUSTDR_PROTECTED`::
A substitution for the `protected` language keyword. *[default: protected]*
----
#define FAUSTDR_PROTECTED public
----

`FAUSTDR_VIRTUAL`::
A substitution for the `virtual` language keyword. *[default: virtual]* +
If the `virtual` keywords generated by Faust are undesired, set this to _empty_.
----
#define FAUSTDR_VIRTUAL
----

`FAUSTDR_BEGIN_NAMESPACE`::
An optional namespace opening definition. *[default: _empty_]* +
If the Faust code must be generated inside a namespace, set this definition as
desired. The anonymous namespace may be used.
----
#define FAUSTDR_BEGIN_NAMESPACE namespace {
----

`FAUSTDR_END_NAMESPACE`::
An optional namespace closing definition. *[default: _empty_]* +
If the Faust code must be generated inside a namespace, set this definition to
match with `FAUSTDR_BEGIN_NAMESPACE`.
----
#define FAUSTDR_END_NAMESPACE }
----
