Skip to content
/ faust Public
forked from grame-cncm/faust

Fork of Faust, a functional programming language for signal processing and sound synthesis, where I add a throw/catch feature

License

Notifications You must be signed in to change notification settings

nuchi/faust

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Faust fork: throw/catch primitives

This is a fork of the Faust compiler (see below for original readme) which adds throw/catch primitives to the language. These can be used to transport signals to and from any destination within the program. The motivation is to allow for easily debugging signals deep in a nested program without having to use contortions to extract the signal.

I tried to address this problem with a much simpler solution entirely within the faust language, faust-tap-library, but this approach had limitations and I wasn't fully satisfied with it. Hence this fork, which adds the feature into the language itself.

Usage

throw("foo") is a box with 1 input and 0 outputs. catch("foo") is a box with 0 inputs and 1 output. If the names match, the signal will be transported from the first to the second, anywhere within the program.

Example:

a = _ : *(2) : (_ <: _, throw("foo")) : +(5);
process = a, catch("foo");

Block diagram: a

C++ output:

for (int i0 = 0; i0 < count; i0 = i0 + 1) {
    float fTemp0 = 2.0f * float(input0[i0]);
    output0[i0] = FAUSTFLOAT(fTemp0 + 5.0f);
    float fRec0 = fTemp0;
    output1[i0] = FAUSTFLOAT(fRec0);
}

The throw primitive doesn't need to be part of the output, just the catch, though it does need to be part of the whole signal. It can also appear after the catch, it doesn't have to be before.

Example:

b = _ : *(2) : (_ <: _, throw("foo")) : +(5);

// This has an error because throw("foo") is not part of the signal
// process = catch("foo");

// This is ok!
process = catch("foo"), (b : !);

Block diagram: b

C++ output:

for (int i0 = 0; i0 < count; i0 = i0 + 1) {
    float fRec0 = 2.0f * float(input0[i0]);
    output0[i0] = FAUSTFLOAT(fRec0);
}

They can even depend recursively on each other, as long as there are delays so that causality isn't violated.

A = (+ : throw("foo") : catch("bar")) ~ _;
B = (+ : throw("bar") : catch("foo")) ~ _;
process = A, B;

// error, causality violation:
// process = (catch("z") : throw("z")), catch("z");

Block diagram: c

C++ output:

for (int i0 = 0; i0 < count; i0 = i0 + 1) {
    fRec0[0] = float(input1[i0]) + fRec1[1];
    output0[i0] = FAUSTFLOAT(fRec0[0]);
    fRec1[0] = float(input0[i0]) + fRec0[1];
    output1[i0] = FAUSTFLOAT(fRec1[0]);
    fRec0[1] = fRec0[0];
    fRec1[1] = fRec1[0];
}

Throw and catch use the same variable interpolation and path mechanisms as labels for sliders and bargraphs and groups.

Example:

d = hgroup("foo", par(i, 5, throw("%i")));
process = d : par(i, 5, catch("h:foo/%j") with {j = (i + 1) % 5;});

Block diagram: d

C++ output:

for (int i0 = 0; i0 < count; i0 = i0 + 1) {
    float fRec0 = float(input1[i0]);
    output0[i0] = FAUSTFLOAT(fRec0);
    float fRec1 = float(input2[i0]);
    output1[i0] = FAUSTFLOAT(fRec1);
    float fRec2 = float(input3[i0]);
    output2[i0] = FAUSTFLOAT(fRec2);
    float fRec3 = float(input4[i0]);
    output3[i0] = FAUSTFLOAT(fRec3);
    float fRec4 = float(input0[i0]);
    output4[i0] = FAUSTFLOAT(fRec4);
}

Limitations

The vectorizing compiler is not supported (i.e. the -vec flag, or any other flag that sets it), nor the -lang ocpp flag. The impulse tests pass on the C++ backend for the -double flag, for the existing test cases. I haven't checked the other backends in depth, though I expect they'll pass as well. I haven't added any tests for the throw/catch feature. Contributions welcome.

On programs that don't use the throw/catch feature, this fork may produce slightly different code than the official compiler. As far as I've been able to check with the impulse tests, it's functionally the same, but the memory layout will often be different, and I don't know if that's for the better or for the worse as far as cache performance goes. Some instructions will also be generated in different order, though topological order will be the same. Again I don't know if performance is better or worse that way.

If you have two throws with the same name, only one of them will be used (arbitrarily). I haven't added a check for duplicate definitions. Contributions welcome, it should be straightforward.

Below is the readme for the official Faust project.


Faust - Programming Language for Audio Applications and Plugins

Grame, Centre National de Creation Musicale: https://www.grame.fr

Build status: Ubuntu MacOS Windows

Introduction

Faust (Functional Audio Stream) is a functional programming language specifically designed for real-time signal processing and synthesis. A distinctive characteristic of Faust is that it is fully compiled.

The Faust compiler translates DSP specifications into very efficient code for various languages (C++, C, JAVA, LLVM IR, WebAssembly etc.) working at sample level. It targets high-performance signal processing applications, libraries, and audio plug-ins for a variety of audio platforms and standards. A same Faust specification can be used to easily generate various kinds of native standalone applications, iOS and Android apps, as well as Csound, LADSPA, Max/MSP, PD, Q, SuperCollider, VST, AU plugins, etc. (see the README in the /architecture folder for an exhaustive list).

While there are Faust contributors everywhere across the globe, Faust is mainly being developed at Grame, Centre National de Creation Musicale (https://www.grame.fr), its birthplace.

Versions and Branches

The Faust distribution can be downloaded on the Faust Github repository: https://github.com/grame-cncm/faust. Official release packages are also available here: https://github.com/grame-cncm/faust/releases.

In the following subsections, details about the branches of the repository are given.

master

master is the main Faust branch. It can compile in different languages: C, C++, JAVA, LLVM IR, WebAssembly etc. Thanks to its ability to generate LLVM IR and by using LLVM JIT, Faust is "embeddable" in any C++ program through a library called libfaust, which is needed by some sister projects of Faust such as FaustLive, FaucK, faustgen~, etc.

master-dev (Preferred Development Branch)

master-dev is the development sub-branch of master. It is used by Faust developers to commit their changes and can be considered as "the main development branch." The goal is to make sure that master is always functional. Merges between master-dev and master are carried out typically where doing a release.

More experimental branches are also available but are not documented here.

Overview of the Faust Distribution

This is an overview of the content of the top-level folders of the Faust distribution. Most of these folders contain their own README describing their content in more details.

architecture/          : the architecture files currently supported
build/                 : build tools and scripts (cmake based)
benchmark/             : tools to measure the impact of various compiler options
compiler/              : sources of the Faust compiler
debian/                : files for Debian installation
documentation/         : Faust developer's documentation
examples/              : Faust programs examples organized by categories
installer/             : various installers for Linux distribution
libraries/             : DSP libraries
syntax-highlighting/   : support for syntax highlighting for several editors
tests/                 : various tests
tools/                 : additional easy-to-use scripts (faust2...) to produce binaries and plugins
windows/               : Windows related resources

Libraries

Faust libraries are now in a separated project and included as a git submodule. The oboe project is also included as submodule in two different places: architecture/android/app/oboe and architecture/smartkeyboard/app/oboe. The faust2ck project is also included as submodule in tools/faust2ck. These submodules are synchronized from time to time in the main Faust repository using the following commands:

git submodule update --remote --merge
git add libraries tools/faust2ck architecture/android/app/oboe architecture/smartKeyboard/android/app/oboe
git commit -m "Faust updated to the latest version of the libraries, faust2ck, and oboe"
git push

Or to synchronize the libraries folder only:

git submodule update --remote --merge libraries
git add libraries 
git commit -m "Faust updated to the latest version of libraries."
git push

Or to synchronize the faust2ck folder only:

git submodule update --remote --merge tools/faust2ck
git add tools/faust2ck 
git commit -m "Faust updated to the latest version of faust2ck."
git push

Or to synchronize the py2max folder only:

git submodule update --remote --merge architecture/max-msp/py2max
git add architecture/max-msp/py2max 
git commit -m "Faust updated to the latest version of py2max."
git push

Compilation and Installation

Since release 2.5.18, Faust compilation and installation is based on CMake. For details about compilation, you should look at the Faust wiki pages or go directly to the simple tutorial to compile and install.

Using the Faust Examples

The /examples folder contains dozen of example Faust codes organized by categories. There are many options to use them.

Online Faust Editor

The Online Faust Editor is a zero-conf tool that provides all the compilation services, including binaries generation for all the supported platforms and architectures.

Online Faust IDE

The Online Faust IDE is a zero-conf tool that provides all the compilation services, including binaries generation for all the supported platforms and architectures, but also various utilities for signal processing development.

Faust Playground

Faust Playground is an online tool to compile and use Faust code directly in a web browser. To use a Faust example from the /examples folder, just drag-and-drop it in the work space and it should work right away!

FaustLive

FaustLive is a program that was designed to facilitate the prototyping of Faust codes. It embeds the LLVM on-the-fly compiler of Faust2 allowing you to very rapidly compile Faust codes on your computer. Binaries and installation packages of FaustLive are available for Linux, Windows and OSX.

faust2... Scripts and Programs

The faust2... scripts and programs are command line tools allowing to compile Faust codes to any of the supported Faust targets ("architectures"). They are placed on your system during the Faust installation process. The fastest way to get an exhaustive list of all of them is to open a terminal window, type faust2, and then press the Tab key for auto-completion. For example, to compile a Faust code as a JACK application with a Qt interface, run:

faust2jaqt yourCode.dsp

The most commonly used faust2 scripts are:

faust2alqt              : ALSA application with Qt UI
faust2ladspa            : LADSPA plug-in
faust2pdf               : pdf block diagram
faust2supercollider     : SuperCollider external
faust2alsa              : ALSA application with GTK UI
faust2faustvst          : VST plug-in
faust2lv2               : LV2 plug-in
faust2plot              : command line program to debug DSP (sample plotting, etc.)
faust2svg               : SVG block diagram
faust2alsaconsole       : ALSA command line program
faust2mathdoc           : automatic pdf mathematical documentation
faust2png               : png block diagram
faust2android           : Android app
faust2graph             : svg graph
faust2puredata          : PureData external
faust2api               : API generator
faust2msp               : MaxMSP 5 external and patch
faust2max6              : MaxMSP 6 (and later) external and patch
faust2ios               : iOS app
faust2ros               : ROS app
faust2au                : Audio Unit plugin
faust2rosgtk            : ROS app with GTK UI
faust2bela              : BELA program
faust2jack              : JACK application with GTK UI
faust2netjackconsole    : NetJack command line program
faust2rpialsaconsole    : Raspberry Pi ALSA command line program
faust2caqt              : CoreAudio application with Qt UI
faust2jackconsole       : JACK command line program
faust2netjackqt         : NetJack application with Qt UI
faust2rpinetjackconsole : Raspberry Pi JACK command line program
faust2caqtios           : iOS app with Qt UI
faust2octave            : Octave script
faust2csound            : CSOUND Opcode
faust2owl               : OWL Program
faust2sig               : SVG signal
faust2jaqt              : JACK application with Qt UI

Obviously, the corresponding dependencies for each of them must be installed on your system for compilation to be successful. For example, if you use faust2jaqt, JACK and Qt libraries must be installed.

Documentation and Resources

  • /documentation/faust-quick-reference.pdf contains the most up-to-date documentation of Faust.
  • /documentation/library.pdf contains the documentation of the Faust DSP libraries.
  • The Faust website contains useful resources around Faust.
  • The Faust online course or the Faust Hero in 2 Hours tutorial might be good starting points for beginners.
  • Julius Smith's website is an incredible resource on various topics around DSP and Faust.

Acknowledgements

Many persons have been contributing to the Faust project by providing code for the compiler, architecture files, libraries, examples, documentation, scripts, bug reports, ideas, etc.

I would like to thank them and especially: Fons Adriaensen, Tiziano Bole, Baktery Chanka, Thomas Charbonnel, Damien Cramet, Etienne Gaudrin, Albert Graef, Stefan Kersten, Victor Lazzarini, Matthieu Leberre, Mathieu Leroi, Kjetil Matheussen, Remy Muller, Sampo Savolainen, Nicolas Scaringella, Stephen Sinclair, Travis Skare, Julius Smith, as well as my colleagues at GRAME, in particular : Dominique Fober, Stephane Letz and Karim Barkati, and from the ASTREE project : Jerome Barthelemy (IRCAM), Alain Bonardi (IRCAM), Raffaele Ciavarella (IRCAM), Pierre Jouvelot (Ecole des Mines/ParisTech), Laurent Pottier (U. Saint-Etienne)

Questions and suggestions

If you have questions suggestions and comments, or if you want to contribute to the project, two mailing lists are available:

Yann Orlarey

About

Fork of Faust, a functional programming language for signal processing and sound synthesis, where I add a throw/catch feature

Resources

License

Stars

Watchers

Forks

Languages

  • C++ 45.7%
  • Faust 33.1%
  • Standard ML 4.2%
  • JavaScript 3.6%
  • C 3.3%
  • VHDL 2.3%
  • Other 7.8%