This documents describes usage of the Faust Doctor, a flexible code generator for Faust source files. Faust, or "Functional Audio Stream", is a programming language and compiler for signal processing developed at 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 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 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

Options

-DIdentifier=<id>

The name of the generated class which wraps the processing code of the Faust module. [String]

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

-DOversampling=<ratio>

The oversampling ratio, which is either of the following values: 1, 2, 4, 8, 16. [Integer]

Metadata

Creating architecture templates

The template files are expressed in 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 }