├── .gitignore
├── README.md
├── aanl.lib
├── all.lib
├── analyzers.lib
├── basics.lib
├── compressors.lib
├── delays.lib
├── demos.lib
├── doc
├── Makefile
├── docs
│ ├── about.md
│ ├── community.md
│ ├── contributing.md
│ ├── css
│ │ └── extra.css
│ ├── index.md
│ ├── organization.md
│ └── standardFunctions.md
├── library.pdf
├── mkdocs.yml
├── scripts
│ ├── faustlib2md.awk
│ └── makeindex.awk
└── theme
│ ├── base.html
│ ├── css
│ └── base.css
│ └── img
│ ├── faustCode.jpg
│ └── faustText.svg
├── docs
├── .nojekyll
├── 404.html
├── CNAME
├── about
│ └── index.html
├── community
│ └── index.html
├── contributing
│ └── index.html
├── css
│ ├── base.css
│ ├── bootstrap.min.css
│ ├── extra.css
│ └── font-awesome.min.css
├── fonts
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
├── img
│ ├── faustCode.jpg
│ ├── faustText.svg
│ ├── favicon.ico
│ └── grid.png
├── index.html
├── js
│ ├── base.js
│ ├── bootstrap.min.js
│ └── jquery-3.6.0.min.js
├── libs
│ ├── aanl
│ │ └── index.html
│ ├── analyzers
│ │ └── index.html
│ ├── basics
│ │ └── index.html
│ ├── compressors
│ │ └── index.html
│ ├── delays
│ │ └── index.html
│ ├── demos
│ │ └── index.html
│ ├── dx7
│ │ └── index.html
│ ├── envelopes
│ │ └── index.html
│ ├── fds
│ │ └── index.html
│ ├── filters
│ │ └── index.html
│ ├── hoa
│ │ └── index.html
│ ├── index.html
│ ├── interpolators
│ │ └── index.html
│ ├── linearalgebra
│ │ └── index.html
│ ├── maths
│ │ └── index.html
│ ├── mi
│ │ └── index.html
│ ├── misceffects
│ │ └── index.html
│ ├── noises
│ │ └── index.html
│ ├── oscillators
│ │ └── index.html
│ ├── phaflangers
│ │ └── index.html
│ ├── physmodels
│ │ └── index.html
│ ├── quantizers
│ │ └── index.html
│ ├── reducemaps
│ │ └── index.html
│ ├── reverbs
│ │ └── index.html
│ ├── routes
│ │ └── index.html
│ ├── signals
│ │ └── index.html
│ ├── soundfiles
│ │ └── index.html
│ ├── spats
│ │ └── index.html
│ ├── synths
│ │ └── index.html
│ ├── vaeffects
│ │ └── index.html
│ ├── version
│ │ └── index.html
│ ├── wdmodels
│ │ └── index.html
│ └── webaudio
│ │ └── index.html
├── organization
│ └── index.html
├── search
│ ├── lunr.js
│ ├── main.js
│ ├── search_index.json
│ └── worker.js
├── sitemap.xml
├── sitemap.xml.gz
└── standardFunctions
│ └── index.html
├── dx7.lib
├── dx7presets
├── README.md
├── brass.syx
├── dx7_brass.syx.lib
└── makelibs
├── embedded
└── platform.lib
├── envelopes.lib
├── fds.lib
├── filters.lib
├── hoa.lib
├── install
├── instruments.lib
├── interpolators.lib
├── licenses
└── stk-4.3.0.md
├── linearalgebra.lib
├── maths.lib
├── maxmsp.lib
├── mi.lib
├── misceffects.lib
├── modalmodels
├── carillonBell
│ ├── .gitignore
│ ├── build
│ ├── carillonBell.obj
│ ├── carillonBell.scad
│ ├── carillonBell.svg
│ └── description.md
├── churchBell
│ ├── .gitignore
│ ├── build
│ ├── churchBell.obj
│ ├── churchBell.scad
│ ├── churchBell.svg
│ └── description.md
├── englishBell
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── english.scad
│ ├── englishBell.obj
│ └── englishBell.svg
├── frenchBell
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── frenchBell.obj
│ ├── frenchBell.scad
│ └── frenchBell.svg
├── germanBell
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── germanBell.obj
│ ├── germanBell.scad
│ └── germanBell.svg
├── marimbaBar
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── marimbaBar.obj
│ ├── marimbaBar.scad
│ └── marimbaBar.svg
├── russianBell
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── russianBell.obj
│ ├── russianBell.scad
│ └── russianBell.svg
└── standardBell
│ ├── .gitignore
│ ├── build
│ ├── description.md
│ ├── standardBell.obj
│ ├── standardBell.scad
│ └── standardBell.svg
├── noises.lib
├── old
├── effect.lib
├── filter.lib
├── math.lib
├── music.lib
└── oscillator.lib
├── oscillators.lib
├── phaflangers.lib
├── physmodels.lib
├── platform.lib
├── quantizers.lib
├── reducemaps.lib
├── resources
├── .gitignore
├── Makefile
└── README.md
├── reverbs.lib
├── routes.lib
├── sf.lib
├── signals.lib
├── soundfiles.lib
├── spats.lib
├── stdfaust.lib
├── synths.lib
├── tonestacks.lib
├── tubes.lib
├── vaeffects.lib
├── version.lib
├── wdmodels.lib
└── webaudio.lib
/.gitignore:
--------------------------------------------------------------------------------
1 | doc/site
2 | doc/docs/libs
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Faust Libraries
2 |
3 | This repository contains the source code and the documentation of the DSP libraries of the [Faust Programming Language](https://faust.grame.fr).
4 |
5 | Here is the [online documentation](https://faustlibraries.grame.fr) of the Faust libraries (which also serves as a proper README for this repository).
6 |
7 | ### Prerequisites
8 | - you must have awk and [mkdocs](https://www.mkdocs.org/) installed.
9 | - you must have the Faust source code installed. You can get it from [github](https://github.com/grame-cncm/faust).
10 |
11 | ### WARNING: adding new files
12 |
13 | Be sure to add new files in the `doc/docs`, and **not** in the `docs` which is the folder generated by the build process.
14 |
15 | ### Building the documentation
16 |
17 | The build process is based on `make` located in the `doc` folder. Building the documentation site is based on [mkdocs](https://www.mkdocs.org/).
18 | To install the required components type:
19 |
20 | To generate all these files type:
21 | ~~~~~~~~~~~~~~~~
22 | $ make install
23 | ~~~~~~~~~~~~~~~~
24 |
25 | ### Testing and generating
26 |
27 | You can test the web site using the mkdoc embedded web server. This server also scan any change in the source directory and refresh the pages dynamically which is really convenient for the development process. To launch the server type:
28 | ~~~~~~~~~~~~~~~~
29 | $ make serve
30 | ~~~~~~~~~~~~~~~~
31 |
32 | When ready, you can generate the documentation web site. Type:
33 | ~~~~~~~~~~~~~~~~
34 | $ make build
35 | ~~~~~~~~~~~~~~~~
36 | The web site will be available from the `docs` folder at the root of the `faustlibraries` folder
37 |
38 | More details on the build process:
39 | ~~~~~~~~~~~~~~~~
40 | $ make help
41 | ~~~~~~~~~~~~~~~~
42 |
43 | ### Publishing
44 |
45 | The docs folder at root level contains all files that will be published. To make the current version publicly available:
46 | - add all the new files using `git add docs`
47 | - commit using `git commit -am "message"` (so new files and deleted files will be commited, except docs/CNAME file)
48 | - and push the commit
49 |
50 | ### WARNING!!
51 |
52 | - never delete the **docs/CNAME file** (which is mandatory for the final generated site to work)
53 | - in case it has been removed, restore it using `git checkout docs/CNAME`
54 |
--------------------------------------------------------------------------------
/all.lib:
--------------------------------------------------------------------------------
1 | //##################################### all.lib ##########################################
2 | // The purpose of this library is to give access to all the Faust standard libraries
3 | // from a single point.
4 | //########################################################################################
5 |
6 | import("aanl.lib");
7 | import("analyzers.lib");
8 | import("basics.lib");
9 | import("compressors.lib");
10 | import("delays.lib");
11 | import("demos.lib");
12 | import("dx7.lib");
13 | import("envelopes.lib");
14 | import("fds.lib");
15 | import("filters.lib");
16 | import("hoa.lib");
17 | import("interpolators.lib");
18 | import("linearalgebra.lib");
19 | import("maths.lib");
20 | import("mi.lib");
21 | import("misceffects.lib");
22 | import("oscillators.lib");
23 | import("noises.lib");
24 | import("phaflangers.lib");
25 | import("physmodels.lib");
26 | import("quantizers.lib");
27 | import("reducemaps.lib");
28 | import("reverbs.lib");
29 | import("routes.lib");
30 | import("signals.lib");
31 | import("soundfiles.lib");
32 | import("spats.lib");
33 | import("synths.lib");
34 | import("vaeffects.lib");
35 | import("version.lib");
36 | import("wdmodels.lib");
37 | import("webaudio.lib");
38 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 |
2 | MAKE ?= make
3 | AWK ?= gawk
4 |
5 | DOCDIR := docs
6 | SITEDIR := ../docs
7 | FAUSTLIBS ?= ../../faustlibraries
8 |
9 | SRC := $(shell cat $(FAUSTLIBS)/all.lib | grep import | sed -e 's/[^"]*"\(..*\.lib\).*/\1/')
10 | MD := $(SRC:%.lib=$(DOCDIR)/libs/%.md)
11 | LIST := $(SRC:%.lib=%)
12 |
13 | ####################################################################
14 | help:
15 | @echo "========================================================================"
16 | @echo " Faust Libraries Documentation"
17 | @echo "This Makefile is intended to generate the faust libraries documentation"
18 | @echo "========================================================================"
19 | @echo "Available targets are:"
20 | @echo " install : install the required components"
21 | @echo " build : build the web site"
22 | @echo " serve : launch the mkdoc server"
23 | @echo "Development specific targets are available:"
24 | @echo " md : build the md files"
25 | @echo " pdf : build the PDF documentation"
26 | @echo " index : build the index file"
27 | @echo " clean : removes the output of the md target"
28 | @echo " list : list libraries (ready to be included in mkdocs.yml menu)"
29 |
30 | test:
31 | @echo MD: $(MD)
32 |
33 | ####################################################################
34 | build:
35 | $(MAKE) md
36 | $(MAKE) index
37 | mkdocs build
38 | git checkout $(SITEDIR)/CNAME
39 |
40 | serve:
41 | @echo "you can browse the site at http://localhost:8000"
42 | mkdocs serve
43 |
44 | list:
45 | @echo $(foreach e, $(LIST), " - '" $e "': libs/"$e.md"\n")
46 |
47 | pdf:
48 | pandoc --pdf-engine=xelatex --toc docs/index.md docs/organization.md docs/standardFunctions.md docs/contributing.md docs/about.md docs/libs/*.md -o library.pdf
49 |
50 | clean:
51 | rm -f $(MD)
52 |
53 |
54 | ####################################################################
55 | # building md files
56 | md : $(DOCDIR)/libs $(MD)
57 |
58 | $(DOCDIR)/libs :
59 | mkdir $(DOCDIR)/libs
60 |
61 | $(DOCDIR)/libs/%.md:$(FAUSTLIBS)/%.lib
62 | @echo ========= building $<
63 | cat $< | $(AWK) -f scripts/faustlib2md.awk > $@
64 |
65 | ####################################################################
66 | # building index
67 | index: $(DOCDIR)/libs/index.md
68 | $(DOCDIR)/libs/index.md : $(MD)
69 | $(AWK) -f scripts/makeindex.awk $(MD) > $@
70 |
71 |
72 | ####################################################################
73 | $(FAUSTDIR):
74 | @echo "FAUSTLIBS not found ! ($(FAUSTLIBS))"
75 | @echo "you should either:"
76 | @echo " - set FAUSTLIBS to the faust projet location in this Makefile"
77 | @echo " - call $(MAKE) FAUSTLIBS=faust_projet_path"
78 | @false;
79 |
80 | ####################################################################
81 | install:
82 | pip install mkdocs==1.5.3
83 | pip install mkdocs-pdf-export-plugin
84 | pip install markdown-include
85 | pip install mkdocs-bootswatch
86 | pip install python-markdown-math
87 |
88 | uninstall:
89 | pip uninstall -y mkdocs-material
90 | pip uninstall -y pymdown-extensions
91 | pip uninstall -y markdown-blockdiag
92 | pip uninstall -y mkdocs-pdf-export-plugin
93 |
--------------------------------------------------------------------------------
/doc/docs/about.md:
--------------------------------------------------------------------------------
1 | # The Faust Project
2 |
3 | The Faust Project has started in 2002. It is actively developed by the [GRAME-CNCM Research Department](https://www.grame.fr/recherche).
4 |
5 | Many persons are contributing to the Faust project, by providing code for the
6 | compiler, architecture files, libraries, examples, documentation, scripts, bug
7 | reports, ideas, etc. We would like in particular to thank:
8 |
9 |
10 | Fons Adriaensen, Karim Barkati,
11 | Jérôme Barthélemy, Tim Blechmann,
12 | Tiziano Bole, Alain Bonardi,
13 | Thomas Charbonnel, Raffaele Ciavarella,
14 | Julien Colafrancesco, Damien Cramet,
15 | Sarah Denoux, Étienne Gaudrin,
16 | Olivier Guillerminet, Pierre Guillot,
17 | Albert Gräf, Pierre Jouvelot,
18 | Stefan Kersten, Victor Lazzarini,
19 | Matthieu Leberre, Mathieu Leroi,
20 | Fernando Lopez-Lezcano, Kjetil Matheussen,
21 | Hermann Meyer, Rémy Muller,
22 | Raphael Panis, Eliott Paris,
23 | Reza Payami, Laurent Pottier,
24 | Sampo Savolainen, Nicolas Scaringella,
25 | Anne Sedes, Priyanka Shekar,
26 | Stephen Sinclair, Travis Skare,
27 | Julius Smith, Mike Solomon,
28 | Michael Wilson, Bart Brouns, Dirk Roosenburg,
29 | Riccardo Russo.
30 |
31 |
32 | as well as our colleagues at [GRAME](http://grame.fr):
33 |
34 | - Dominique Fober
35 | - Christophe Lebreton
36 | - Stéphane Letz
37 | - Romain Michon
38 | - Yann Orlarey
39 |
40 | We would like also to thank for their financial support:
41 |
42 | - the [French Ministry of Culture](http://www.culture.gouv.fr/),
43 | - the [Auvergne-Rhône-Alpes Region](https://www.auvergnerhonealpes.fr/),
44 | - the [City of Lyon](https://www.lyon.fr/),
45 | - the [French National Research Agency (ANR)](http://www.agence-nationale-recherche.fr/).
46 |
--------------------------------------------------------------------------------
/doc/docs/community.md:
--------------------------------------------------------------------------------
1 | # Libraries from the community
2 |
3 | A lot of libraries have been developed by the community. They can be used when developing DSP programs:
4 |
5 | - when used in [Faust IDE](https://faustide.grame.fr), by adding them in the [project files](https://github.com/grame-cncm/faustide#project-files) section
6 | - when used in a local Faust installation on macOS or Linux, by adding them in the `/usr/share/faust`, or `/usr/local/share/faust` folders
7 |
8 | They are presented in the following sections.
9 |
10 | ## [abclib library](https://github.com/alainbonardi/abclib/)
11 |
12 | 20 years of research, teaching and creation in mixed music using Faust language.
13 |
14 | abclib library is released by the CICM / MUSIDANSE (Centre de Recherches Informatique et Création Musicale, Paris 8 University) and is the result of 20 years of research, teaching and creation in mixed music, expressed as a set of codes in Faust language. The main topics addressed are: spatial sound processing and synthesis using ambisonics, multi-channel sound processing, utility objects for mixed music.
15 |
16 | ## [Edge of Chaos](https://github.com/dariosanfilippo/edgeofchaos)
17 |
18 | This repository contains libraries including some essential building blocks for the implementation of musical complex adaptive systems in Faust programming.
19 |
20 | It includes a set of time-domain algorithms, some of which are original, for the processing of low-level and high-level information as well as the processing of sound using standard and non-conventional techniques. It also includes functions for the realisation of networks with different topologies, linear and nonlinear mapping strategies to render positive and negative feedback relationships, and different kinds of energy-preserving techniques for the stability of self-oscillating systems.
21 |
22 | ## [realfaust](https://github.com/dariosanfilippo/realfaust)
23 |
24 | This library contains a set of functions representing domain-limited versions of all Faust primitives and math functions that can potentially generate INF or NaN values. The goal of the library is to be able to implement DSP networks that, structurally, are free from INF and NaN values. Hence, the resulting programs should be rock-solid during real-time performance and virtually immune to crashes regardless of how mercilessly a network is modulated or how unstable a recursive system is made.
25 |
26 | ## [bitDSP-faust](https://github.com/rottingsounds/bitDSP-faust)
27 |
28 | BitDSP is a set of Faust library functions aimed to help explore and research artistic possibilities of bit-based algorithms. BitDSP currently includes implementations of bit-based functions ranging from simple bit operations over classic delta-sigma modulations to more experimental approaches like cellular automata, recursive Boolean networks, and linear feedback shift registers.
29 |
30 | A detailed overview of the functionality is in the [paper](https://ifc20.sciencesconf.org/332745/document) "Creative use of bit-stream DSP in Faust" presented at [IFC 2020](https://ifc20.sciencesconf.org/).
31 |
32 | ## [SEAM library](https://github.com/s-e-a-m/faust-libraries)
33 |
34 | Sustained Electro-Acoustic Music is a project inspired by [Alvise Vidolin and Nicola Bernardini](https://www.academia.edu/16348988/Sustainable_live_electro-acoustic_music). The SEAM libraries have been developed for this project.
35 |
36 | ## [Ambitools library](http://sekisushai.net/ambitools/)
37 |
38 | Ambitools is an implementation of several Ambisonic tools with the FAUST language. The code is designed to be scalable and flexible, offering tools working at various Ambisonic order and compiled for various architectures. The implementation of the spherical harmonics for an efficient computation is detailed. See the [Ambitools : Tools For Sound Field Synthesis With Higher Order Ambisonic - V1.0](https://hal.archives-ouvertes.fr/hal-03162948/document) paper.
39 |
40 | ## [Faust Tap Library](https://github.com/nuchi/faust-tap-library/)
41 | Tap a complicated expression to pull out specific outputs, without having to manually route those outputs, just like how named function parameters remove the need to manually route inputs.
42 |
43 | ## [MoreFilters library](https://codeberg.org/obsoleszenz/morefilters.lib)
44 |
45 | A Faust library implementing following highpass/lowpass filters using `fi.svf`:
46 |
47 | - Biquad
48 | - Butterworth (2nd, 4th, 6th, 8th order)
49 | - Bessel (2nd, 4th, 6th, 8th order)
50 | - Linkwitz Riley (4th, 8th, 12th and 16th order)
51 |
52 | ## [lsfaustlibraries](https://github.com/LucaSpanedda/lsfaustlibraries)
53 | Luca Spanedda's Faust libraries.
54 |
55 | ## Awesome library
56 | Feel free to contribute by [forking this project](https://docs.github.com/en/github/collaborating-with-pull-requests/working-with-forks) and [creating a pull request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request), or by mailing the library description [here](mailto:research@grame.fr).
57 |
58 | # Additional DSP resources
59 |
60 | Heres is a list of additional DSP resources.
61 |
62 | ## Granulation
63 |
64 | ### A list of projects related to granulation:
65 |
66 | - Dario Sanfilippo [Live concatenative granular processing](https://github.com/dariosanfilippo/concatenative_granulation) project
67 |
68 | - Mykle Hansen [Weather Organ](https://github.com/myklemykle/weather_organ) project
69 |
70 | - Jean-Louis Paquelin [Granola](https://github.com/jlp6k/faust-things) monophonic granular live feed processor
71 |
72 | - Mayank Sanganeria [granulator.dsp]( https://github.com/e7mac/faust-code/blob/master/granulator.dsp) project
73 |
74 | - Henrik von Coler [material on granulation](http://ringbuffer.org/faust/synthesis_algorithms/granular-faust-example/)
75 |
76 | ### Material in the [abclib library](https://github.com/alainbonardi/abclib/)
77 |
78 | - basic granulator in Faust [based on a delay line](https://github.com/alainbonardi/abclib/blob/master/faustCodes/library/mm.lib), with the `granulator` function
79 |
80 | - [spatial granulation in ambisonics](https://github.com/alainbonardi/abclib/blob/master/faustCodes/library/abc.lib) in `abc_2d_fx_grain_ui` and `abc_2d_syn_grain_ui` functions
81 |
82 | - [multichannel granulation](https://github.com/alainbonardi/abclib/blob/master/faustCodes/library/abc.lib) in `abc_multigrain_ui` function
83 |
--------------------------------------------------------------------------------
/doc/docs/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | In general, libraries are organised in a *stacked manner*: the base ones define functions or constants without any dependancies, and additional ones are gradually built on top of simpler ones, layer by layer. **Dependency loops must be avoided as much as possible**. The *resources* folder contains tools to build and visualise the libraries dependencies graphs.
4 |
5 | If you wish to add a function to any of these libraries or if you plan to add a new library, make sure that you observe the following conventions:
6 |
7 | ## New Functions
8 |
9 | * All functions must be preceded by a markdown documentation header respecting the following format (open the source code of any of the libraries for an example):
10 |
11 | ```
12 | //-----------------functionName--------------------
13 | // Description
14 | //
15 | // #### Usage
16 | //
17 | // ```
18 | // Usage Example
19 | // ```
20 | //
21 | // Where:
22 | //
23 | // * argument1: argument 1 description
24 | //-------------------------------------------------
25 | ```
26 |
27 | * Every time a new function is added, the documentation should be updated simply by running `make doclib`.
28 | * The environment system (e.g. `os.osc`) should be used when calling a function declared in another library (see the section on [Library Import](#library-import)).
29 | * Try to reuse existing functions as much as possible.
30 | * The `Usage` line must show the *input/output shape* (the number of inputs and outputs) of the function, like `gen: _` for a mono generator, `_ : filter : _` for a mono effect, etc.
31 | * Some functions use parameters that are [constant numerical expressions](https://faustdoc.grame.fr/manual/syntax/#constant-numerical-expressions). The convention is to label them in *capital letters* and document them preferably to be *constant numerical expressions* (or *known at compile time* in existing libraries).
32 | * Functions with several parameters should better be written by putting the *more constant parameters* (like control, setup...) at the beginning of the parameter list, and *audio signals to be processed* at the end. This allows to do partial-application. So prefer the following `clip(low, high, x) = min(max(x, low), high);` form where `clip(-1, 1)` partially applied version can be used later on in different contexts, better than `clip(x, low, high) = min(max(x, low), high);` version.
33 |
34 |
35 | ## New Libraries
36 |
37 | * Any new "standard" library should be declared in `stdfaust.lib` with its own environment (2 letters - see `stdfaust.lib`).
38 | * Any new "standard" library must be added to `generateDoc`.
39 | * Functions must be organized by sections.
40 | * Any new library should at least `declare` a `name` and a `version`.
41 | * Any new library has to use a prefix declared in the header section with the following kind of syntax: `Its official prefix is 'qu'` (look at an existing library to follow the exact syntax).
42 | * Be sure to add the appropriate kind of `ma = library("maths.lib");` import library line, for each external library function used in the new library (for instance `ma.foo` that would be used somewhre in the code).
43 | * The comment based markdown documentation of each library must respect the following format (open the source code of any of the libraries for an example):
44 |
45 | ```
46 | //############### libraryName ##################
47 | // Description
48 | //
49 | // * Section Name 1
50 | // * Section Name 2
51 | // * ...
52 | //
53 | // It should be used using the `[...]` environment:
54 | //
55 | // ```
56 | // [...] = library("libraryName");
57 | // process = [...].functionCall;
58 | // ```
59 | //
60 | // Another option is to import `stdfaust.lib` which already contains the `[...]`
61 | // environment:
62 | //
63 | // ```
64 | // import("stdfaust.lib");
65 | // process = [...].functionCall;
66 | // ```
67 | //##############################################
68 |
69 | //================= Section Name ===============
70 | // Description
71 | //==============================================
72 | ```
73 |
74 | ## Coding Conventions
75 |
76 | In order to have a uniformized library system, we established the following conventions (that hopefully will be followed by others when making modifications to them).
77 |
78 | ### Function Naming
79 |
80 | [WIP]
81 |
82 | JOS proposal: using terms used in the field of digital signal processing, as follows:
83 |
84 | * `impulse`: ...,0,1,0,...
85 | * `pulse`: ...,0,1,1,0,... or longer
86 | * `impulse_train`
87 | * `pulse_train`
88 | * `gate` = pulse controlled externally (e.g., by NoteOn,NoteOff)
89 | * `trigger` = impulse controlled externally (gate - gate' > 0) == gate rising edge
90 |
91 | [/WIP]
92 |
93 | ### Variable Argument List
94 |
95 | Strictly speaking, there are no lists in Faust. But list operations [can be simulated](https://faustdoc.grame.fr/manual/faq/#pattern-matching-and-lists) (in part) using the parallel binary composition operation `,` and pattern matching.
96 |
97 | Thus functions expecting a variable number of arguments can use this mechanism, like a `foo` function that would be used this way: `foo((a,b,c,d))`. See [fi.iir](https://faustlibraries.grame.fr/libs/filters/#fiiir) and [fi.fir](https://faustlibraries.grame.fr/libs/filters/#fifir) examples.
98 |
99 |
100 | ### Documentation
101 |
102 | * All the functions that we want to be "public" are documented.
103 | * We used the `faust2md` "standards" for each library: `//###` for main title (library name - equivalent to `#` in markdown), `//===` for section declarations (equivalent to `##` in markdown) and `//---` for function declarations (equivalent to `####` in markdown - see `basics.lib` for an example).
104 | * Sections in function documentation should be declared as `####` markdown title.
105 | * Each function documentation provides a "Usage" section (see `basics.lib`).
106 | * The full documentation can be generated using the doc/Makefile script. Use `make help` to see all possible commands. If you plan to create a pull-request, *do not commit the full generated code* but only the modified .lib files.
107 | * Each function can have `declare author "name";`, `declare copyright "XXX";` and `declare licence "YYY";` declarations.
108 | * Each library has a `declare version "xx.yy.zz";` [semantic version](https://semver.org) number to be raised each time a modification is done. The global `version` number in `version.lib` also has to be adapted according to the change.
109 |
110 | ### Library Import
111 |
112 | To prevent cross-references between libraries, we generalized the use of the `library("")` system for function calls in all the libraries. This means that everytime a function declared in another library is called, the environment corresponding to this library needs to be called too. To make things easier, a `stdfaust.lib` library was created and is imported by all the libraries:
113 |
114 | ```
115 | aa = library("aanl.lib");
116 | sf = library("all.lib");
117 | an = library("analyzers.lib");
118 | ba = library("basics.lib");
119 | co = library("compressors.lib");
120 | de = library("delays.lib");
121 | dm = library("demos.lib");
122 | dx = library("dx7.lib");
123 | en = library("envelopes.lib");
124 | fd = library("fds.lib");
125 | fi = library("filters.lib");
126 | ho = library("hoa.lib");
127 | it = library("interpolators.lib");
128 | la = library("linearalgebra.lib");
129 | ma = library("maths.lib");
130 | mi = library("mi.lib");
131 | ef = library("misceffects.lib");
132 | os = library("oscillators.lib");
133 | no = library("noises.lib");
134 | pf = library("phaflangers.lib");
135 | pm = library("physmodels.lib");
136 | qu = library("quantizers.lib");
137 | rm = library("reducemaps.lib");
138 | re = library("reverbs.lib");
139 | ro = library("routes.lib");
140 | si = library("signals.lib");
141 | so = library("soundfiles.lib");
142 | sp = library("spats.lib");
143 | sy = library("synths.lib");
144 | ve = library("vaeffects.lib");
145 | vl = library("version.lib");
146 | wa = library("webaudio.lib");
147 | wd = library("wdmodels.lib");
148 | ```
149 |
150 | For example, if we wanted to use the `smooth` function which is now declared in `signals.lib`, we would do the following:
151 |
152 | ```
153 | import("stdfaust.lib");
154 |
155 | process = si.smooth(0.999);
156 | ```
157 |
158 | This standard is only used within the libraries: nothing prevents coders to still import `signals.lib` directly and call `smooth` without `ro.`, etc. It means symbols and function names defined within a library **have to be unique to not collide with symbols of any other libraries**.
159 |
160 | ### "Demo" Functions
161 |
162 | "Demo" functions are placed in `demos.lib` and have a built-in user interface (UI). Their name ends with the `_demo` suffix. Each of these function have a `.dsp` file associated to them in the `/examples` folder.
163 |
164 | Any function containing UI elements should be placed in this library and respect these standards.
165 |
166 | ### "Standard" Functions
167 |
168 | "Standard" functions are here to simplify the life of new (or not so new) Faust coders. They are declared in `/libraries/doc/standardFunctions.md` and allow to point programmers to preferred functions to carry out a specific task. For example, there are many different types of lowpass filters declared in `filters.lib` and only one of them is considered to be standard, etc.
169 |
170 | ## Testing the library
171 |
172 | Before preparing a pull-request, the new library must be carefully tested:
173 |
174 | - all functions defined in the library must be tested by preparing a DSP test program
175 | - the compatibilty library `all.lib` imports all libraries in a same namespace, so check functions names collisions using the following test program:
176 |
177 | ```
178 | import("all.lib");
179 | process = _;
180 | ```
181 |
182 | ## Library deployment
183 |
184 | For GRAME maintainers:
185 |
186 | - regenerate the PDF documentation using `make pdf` target in the `doc` folder
187 | - update the library submodule in [faust](https://github.com/grame-cncm/faust), recompile and deploy WebAssembly libfaust in [fausteditor](https://github.com/grame-cncm/fausteditor), [faustplayground](https://github.com/grame-cncm/faustplayground) and [faustide](https://github.com/grame-cncm/faustide)
188 | - update the library submodule in [faustlive](https://github.com/grame-cncm/faustlive)
189 | - update the library list in this [fausteditor](https://github.com/grame-cncm/fausteditor/blob/master/src/faustlive.js) page as well as the [snippets](https://github.com/grame-cncm/fausteditor/blob/master/src/codemirror/mode/faust/faustsnippets.js) (using the `faust2atomsnippets` tool).
190 | - update the library list in this [faustide](https://github.com/grame-cncm/faustide/blob/master/src/documentation.ts) page.
191 | - update the library list in the [faustgen~](https://github.com/grame-cncm/faust/blob/master-dev/embedded/faustgen/src/faustgen%7E.cpp) code
192 | - update the [Faust Syntax Highlighting Files](https://github.com/grame-cncm/faust/tree/master-dev/syntax-highlighting)
193 | - make an update PR for [vscode-faust](https://github.com/hellbent/vscode-faust) project
194 |
195 |
--------------------------------------------------------------------------------
/doc/docs/css/extra.css:
--------------------------------------------------------------------------------
1 |
2 | code {
3 | color: #C7254E;
4 | background: #F9F2F4;
5 | }
6 |
7 |
8 | .hljs {
9 | color: #C7254E;
10 | background: #F9F2F4;
11 | }
12 |
--------------------------------------------------------------------------------
/doc/docs/index.md:
--------------------------------------------------------------------------------
1 | # Faust Libraries
2 |
3 | The Faust libraries implement hundreds of DSP functions for audio processing and synthesis. They are organized by types in a set of `.lib` files (e.g., `envelopes.lib`, `filters.lib`, etc.). Librairies use [semantic versioning](https://semver.org), so may evolve in a manner where newer versions break compatibility with older ones. The recommended way to solve this issue is to keep *self-contained versions of the DSP code* (that is the DSP program with all needed libraries) as explained in [Goals of the Mathdoc](https://faustdoc.grame.fr/manual/mathdoc/#goals-of-the-mathdoc).
4 |
5 | This website serves as the main documentation of the [Faust libraries](https://github.com/grame-cncm/faustlibraries). The main Faust website can be found at the following URL:
6 |
7 |
';
33 | }
34 |
35 | function displayResults (results) {
36 | var search_results = document.getElementById("mkdocs-search-results");
37 | while (search_results.firstChild) {
38 | search_results.removeChild(search_results.firstChild);
39 | }
40 | if (results.length > 0){
41 | for (var i=0; i < results.length; i++){
42 | var result = results[i];
43 | var html = formatResult(result.location, result.title, result.summary);
44 | search_results.insertAdjacentHTML('beforeend', html);
45 | }
46 | } else {
47 | var noResultsText = search_results.getAttribute('data-no-results-text');
48 | if (!noResultsText) {
49 | noResultsText = "No results found";
50 | }
51 | search_results.insertAdjacentHTML('beforeend', '
' + noResultsText + '
');
52 | }
53 | }
54 |
55 | function doSearch () {
56 | var query = document.getElementById('mkdocs-search-query').value;
57 | if (query.length > min_search_length) {
58 | if (!window.Worker) {
59 | displayResults(search(query));
60 | } else {
61 | searchWorker.postMessage({query: query});
62 | }
63 | } else {
64 | // Clear results for short queries
65 | displayResults([]);
66 | }
67 | }
68 |
69 | function initSearch () {
70 | var search_input = document.getElementById('mkdocs-search-query');
71 | if (search_input) {
72 | search_input.addEventListener("keyup", doSearch);
73 | }
74 | var term = getSearchTermFromLocation();
75 | if (term) {
76 | search_input.value = term;
77 | doSearch();
78 | }
79 | }
80 |
81 | function onWorkerMessage (e) {
82 | if (e.data.allowSearch) {
83 | initSearch();
84 | } else if (e.data.results) {
85 | var results = e.data.results;
86 | displayResults(results);
87 | } else if (e.data.config) {
88 | min_search_length = e.data.config.min_search_length-1;
89 | }
90 | }
91 |
92 | if (!window.Worker) {
93 | console.log('Web Worker API not supported');
94 | // load index in main thread
95 | $.getScript(joinUrl(base_url, "search/worker.js")).done(function () {
96 | console.log('Loaded worker');
97 | init();
98 | window.postMessage = function (msg) {
99 | onWorkerMessage({data: msg});
100 | };
101 | }).fail(function (jqxhr, settings, exception) {
102 | console.error('Could not load worker.js');
103 | });
104 | } else {
105 | // Wrap search in a web worker
106 | var searchWorker = new Worker(joinUrl(base_url, "search/worker.js"));
107 | searchWorker.postMessage({init: true});
108 | searchWorker.onmessage = onWorkerMessage;
109 | }
110 |
--------------------------------------------------------------------------------
/docs/search/worker.js:
--------------------------------------------------------------------------------
1 | var base_path = 'function' === typeof importScripts ? '.' : '/search/';
2 | var allowSearch = false;
3 | var index;
4 | var documents = {};
5 | var lang = ['en'];
6 | var data;
7 |
8 | function getScript(script, callback) {
9 | console.log('Loading script: ' + script);
10 | $.getScript(base_path + script).done(function () {
11 | callback();
12 | }).fail(function (jqxhr, settings, exception) {
13 | console.log('Error: ' + exception);
14 | });
15 | }
16 |
17 | function getScriptsInOrder(scripts, callback) {
18 | if (scripts.length === 0) {
19 | callback();
20 | return;
21 | }
22 | getScript(scripts[0], function() {
23 | getScriptsInOrder(scripts.slice(1), callback);
24 | });
25 | }
26 |
27 | function loadScripts(urls, callback) {
28 | if( 'function' === typeof importScripts ) {
29 | importScripts.apply(null, urls);
30 | callback();
31 | } else {
32 | getScriptsInOrder(urls, callback);
33 | }
34 | }
35 |
36 | function onJSONLoaded () {
37 | data = JSON.parse(this.responseText);
38 | var scriptsToLoad = ['lunr.js'];
39 | if (data.config && data.config.lang && data.config.lang.length) {
40 | lang = data.config.lang;
41 | }
42 | if (lang.length > 1 || lang[0] !== "en") {
43 | scriptsToLoad.push('lunr.stemmer.support.js');
44 | if (lang.length > 1) {
45 | scriptsToLoad.push('lunr.multi.js');
46 | }
47 | if (lang.includes("ja") || lang.includes("jp")) {
48 | scriptsToLoad.push('tinyseg.js');
49 | }
50 | for (var i=0; i < lang.length; i++) {
51 | if (lang[i] != 'en') {
52 | scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
53 | }
54 | }
55 | }
56 | loadScripts(scriptsToLoad, onScriptsLoaded);
57 | }
58 |
59 | function onScriptsLoaded () {
60 | console.log('All search scripts loaded, building Lunr index...');
61 | if (data.config && data.config.separator && data.config.separator.length) {
62 | lunr.tokenizer.separator = new RegExp(data.config.separator);
63 | }
64 |
65 | if (data.index) {
66 | index = lunr.Index.load(data.index);
67 | data.docs.forEach(function (doc) {
68 | documents[doc.location] = doc;
69 | });
70 | console.log('Lunr pre-built index loaded, search ready');
71 | } else {
72 | index = lunr(function () {
73 | if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
74 | this.use(lunr[lang[0]]);
75 | } else if (lang.length > 1) {
76 | this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
77 | }
78 | this.field('title');
79 | this.field('text');
80 | this.ref('location');
81 |
82 | for (var i=0; i < data.docs.length; i++) {
83 | var doc = data.docs[i];
84 | this.add(doc);
85 | documents[doc.location] = doc;
86 | }
87 | });
88 | console.log('Lunr index built, search ready');
89 | }
90 | allowSearch = true;
91 | postMessage({config: data.config});
92 | postMessage({allowSearch: allowSearch});
93 | }
94 |
95 | function init () {
96 | var oReq = new XMLHttpRequest();
97 | oReq.addEventListener("load", onJSONLoaded);
98 | var index_path = base_path + '/search_index.json';
99 | if( 'function' === typeof importScripts ){
100 | index_path = 'search_index.json';
101 | }
102 | oReq.open("GET", index_path);
103 | oReq.send();
104 | }
105 |
106 | function search (query) {
107 | if (!allowSearch) {
108 | console.error('Assets for search still loading');
109 | return;
110 | }
111 |
112 | var resultDocuments = [];
113 | var results = index.search(query);
114 | for (var i=0; i < results.length; i++){
115 | var result = results[i];
116 | doc = documents[result.ref];
117 | doc.summary = doc.text.substring(0, 200);
118 | resultDocuments.push(doc);
119 | }
120 | return resultDocuments;
121 | }
122 |
123 | if( 'function' === typeof importScripts ) {
124 | onmessage = function (e) {
125 | if (e.data.init) {
126 | init();
127 | } else if (e.data.query) {
128 | postMessage({ results: search(e.data.query) });
129 | } else {
130 | console.error("Worker - Unrecognized message: " + e);
131 | }
132 | };
133 | }
134 |
--------------------------------------------------------------------------------
/docs/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/docs/sitemap.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grame-cncm/faustlibraries/d8bf3b73a1d051885792ed868bb0c3cba5052519/docs/sitemap.xml.gz
--------------------------------------------------------------------------------
/dx7presets/README.md:
--------------------------------------------------------------------------------
1 | # DX7 Preset File Libraries
2 |
3 | This folder contains DX7 preset libraries generated using `dx72faust`
4 | (see `tools/dx72faust`) from Yamaha DX7 preset files (`.syx`). To re-generate
5 | all the libraries from the `.syx` files contained in this folder, just run:
6 |
7 | ```
8 | makelibs
9 | ```
10 |
--------------------------------------------------------------------------------
/dx7presets/brass.syx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grame-cncm/faustlibraries/d8bf3b73a1d051885792ed868bb0c3cba5052519/dx7presets/brass.syx
--------------------------------------------------------------------------------
/dx7presets/makelibs:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | for file in *.syx
4 | do
5 | dx72faust "$file"
6 | done
7 |
--------------------------------------------------------------------------------
/embedded/platform.lib:
--------------------------------------------------------------------------------
1 | //#################################### platform.lib ########################################
2 | // A library to handle platform specific library code in Faust.
3 | //########################################################################################
4 |
5 | /************************************************************************
6 | ************************************************************************
7 | FAUST library file
8 | Copyright (C) 2020 GRAME, Centre National de Creation Musicale
9 | ----------------------------------------------------------------------
10 | This program is free software; you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as
12 | published by the Free Software Foundation; either version 2.1 of the
13 | License, or (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public
21 | License along with the GNU C Library; if not, write to the Free
22 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 | 02111-1307 USA.
24 |
25 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
26 | larger FAUST program which directly or indirectly imports this library
27 | file and still distribute the compiled code generated by the FAUST
28 | compiler, or a modified version of this compiled code, under your own
29 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
30 | grants you the right to freely choose the license for the resulting
31 | compiled code. In particular the resulting compiled code has no obligation
32 | to be LGPL or GPL. For example you are free to choose a commercial or
33 | closed source license or any other license if you decide so.
34 | ************************************************************************
35 | ************************************************************************/
36 |
37 | declare name "Embedded Platform Library";
38 | declare version "0.1";
39 |
40 | //---------------------------------`(pl.)SR`---------------------------------------
41 | // Current sampling rate. Constant during program execution.
42 | //-----------------------------------------------------------------------------
43 | SR = 48000;
44 |
45 | //---------------------------------`(pl.)BS`---------------------------------------
46 | // Current block-size. Can change during the execution.
47 | //-----------------------------------------------------------------------------
48 | BS = fvariable(int count, );
49 |
50 | //---------------------------------`(pl.)tablesize`---------------------------------------
51 | // Oscillator table size
52 | //-----------------------------------------------------------------------------
53 | tablesize = 1 << 8;
54 |
--------------------------------------------------------------------------------
/install:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | cp *.lib old/*.lib `faust --dspdir`
4 |
--------------------------------------------------------------------------------
/instruments.lib:
--------------------------------------------------------------------------------
1 | //instruments.lib - Faust function of various types useful for building physical model instruments
2 |
3 | no = library("noises.lib");
4 | en = library("envelopes.lib");
5 | ma = library("maths.lib");
6 | ba = library("basics.lib");
7 | de = library("delays.lib");
8 | si = library("signals.lib");
9 | fi = library("filters.lib");
10 | os = library("oscillators.lib");
11 | re = library("reverbs.lib");
12 |
13 | declare name "Faust-STK Tools Library";
14 | declare author "Romain Michon (rmichon@ccrma.stanford.edu)";
15 | declare copyright "Romain Michon";
16 | declare version "1.0.0";
17 | declare licence "STK-4.3"; // Synthesis Tool Kit 4.3 (MIT style license);
18 |
19 |
20 | //========================= ENVELOPE GENERATORS ===============================
21 |
22 | //----------------------- VIBRATO ENVELOPE ----------------------------
23 | // 4 phases envelope to control vibrato gain
24 | //
25 | // USAGE:
26 | // _ : *(envVibrato(b,a,s,r,t)) : _
27 | // where
28 | // b = beginning duration (silence) in seconds
29 | // a = attack duration in seconds
30 | // s = sustain as a percentage of the amplitude to be modified
31 | // r = release duration in seconds
32 | // t = trigger signal
33 |
34 | envVibrato(b,a,s,r,t) = env ~ (_,_,_) : (!,!,_) // the 3 'state' signals are fed back
35 | with {
36 | env(p2,cnt,y) =
37 | (t>0) & (p2|(y>=1)),
38 | (cnt + 1)*(t>0), // counter for the first step "b"
39 | (y + p1*p3*u*(s/100) - p4*w*y)*((p4==0)|(y>=eps)) // y = envelop signal
40 | //*(y>=eps) // cut off tails to prevent denormals
41 | with {
42 | p1 = (p2==0) & (t>0) & (y<1) & (cnt>(b*ma.SR)); // p1 = attack phase
43 | p3 = 1-(cnt<(nb)); // p3 = beginning phase
44 | p4 = (t<=0) & (y>0); // p4 = release phase
45 | // #samples in attack, release, must be >0
46 | nb = ma.SR*b+(b==0.0) ; na = ma.SR*a+(a==0.0); nr = ma.SR*r+(r==0.0);
47 | // attack and (-60dB) release rates
48 | z = s+(s==0.0)*ba.db2linear(-60);
49 | u = 1/na; w = 1-1/pow(z*ba.db2linear(60), 1/nr);
50 | // values below this threshold are considered zero in the release phase
51 | eps = ba.db2linear(-120);
52 | };
53 | };
54 |
55 | //----------------------- ASYMPT60 ----------------------------
56 | // Envelope generator which asymptotically approaches a target value.
57 | //
58 | // USAGE:
59 | // asympT60(value,trgt,T60,trig) : _
60 | // where
61 | // value = starting value
62 | // trgt = target value
63 | // T60 = ramping time
64 | // trig = trigger signal
65 |
66 | asympT60(value,trgt,T60,trig) = (_*factor + constant)~_
67 | with {
68 | cntSample = *(trig) + 1~_ : -(1);
69 | attDur = float(2);
70 | cndFirst = ((cntSample < attDur) & (trig > 0));
71 | target = value*cndFirst + trgt*(cndFirst < 1);
72 | factorAtt = exp(-7/attDur);
73 | factorT60 = exp(-7/(T60*float(ma.SR)));
74 | factor = factorAtt*((cntSample < attDur) & (trig > 0)) +
75 | ((cntSample >= attDur) | (trig < 1))*factorT60;
76 | constant = (1 - factor)*target;
77 | };
78 |
79 | //========================= TABLES ===============================
80 |
81 | //----------------------- CLIPPING FUNCTION ----------------------------
82 | // Positive and negative clipping functions.
83 | //
84 | // USAGE:
85 | // _ : saturationPos : _
86 | // _ : saturationNeg : _
87 | // _ : saturationPos : saturationNeg : _
88 |
89 | saturationPos(x) = x <: (_>1),(_<=1 : *(x)) :> +;
90 | saturationNeg(x) = x <: (_<-1),(_>=-1 : *(x)) :> *(-1) + _;
91 |
92 | //----------------------- BOW TABLE ----------------------------
93 | // Simple bow table.
94 | //
95 | // USAGE:
96 | // index : bow(offset,slope) : _
97 | // where
98 | // 0 <= index <= 1
99 |
100 | bow(offset,slope) = pow(abs(sample) + 0.75, -4) : saturationPos
101 | with {
102 | sample(y) = (y + offset)*slope;
103 | };
104 |
105 | //----------------------- REED TABLE ----------------------------
106 | // Simple reed table to be used with waveguide models of clarinet, saxophone, etc.
107 | //
108 | // USAGE:
109 | // _ : reed(offset,slope) : _
110 | // where
111 | // offset = offset between 0 and 1
112 | // slope = slope between 0 and 1
113 | // REFERENCE:
114 | //
115 |
116 | reed(offset,slope) = reedTable : saturationPos : saturationNeg
117 | with {
118 | reedTable = offset + (slope*_);
119 | };
120 |
121 | //========================= FILTERS ===============================
122 |
123 | //----------------------- ONE POLE ----------------------------
124 |
125 | onePole(b0,a1,x) = (b0*x - a1*_)~_;
126 |
127 | //----------------------- ONE POLE SWEPT ----------------------------
128 |
129 | onePoleSwep(a1,x) = (1 + a1)*x - a1*x';
130 |
131 | //----------------------- POLE ZERO ----------------------------
132 |
133 | poleZero(b0,b1,a1,x) = (b0*x + b1*x' - a1*_)~_;
134 |
135 | //----------------------- ONE ZEROS ----------------------------
136 | // Simple One zero and One zero recursive filters
137 | //
138 | // USAGE:
139 | // _ : oneZero0(b0,b1) : _
140 | // _ : oneZero1(b0,b1) : _
141 | // REFERENCE:
142 | //
143 |
144 | oneZero0(b0,b1,x) = (*(b1) + x*b0)~_;
145 | oneZero1(b0,b1,x) = (x'*b1 + x*b0);
146 |
147 | //----------------------- BANDPASS FILTER WITH CONSTANT UNITY PEAK GAIN BASED ON A BIQUAD ----------------------------
148 |
149 | bandPass(resonance,radius) = fi.TF2(b0,b1,b2,a1,a2)
150 | with {
151 | a2 = radius*radius;
152 | a1 = -2*radius*cos(ma.PI*2*resonance/ma.SR);
153 | b0 = 0.5-0.5*a2;
154 | b1 = 0;
155 | b2 = -b0;
156 | };
157 |
158 | //----------------------- BANDPASS FILTER BASED ON A BIQUAD ----------------------------
159 | // Band pass filter using a biquad (TF2 is declared in filter.lib)
160 | //
161 | // USAGE:
162 | // _ : bandPassH(resonance,radius) : _
163 | // where
164 | // resonance = center frequency
165 | // radius = radius
166 |
167 | bandPassH(resonance,radius) = fi.TF2(b0,b1,b2,a1,a2)
168 | with {
169 | a2 = radius*radius;
170 | a1 = -2*radius*cos(ma.PI*2*resonance/ma.SR);
171 | b0 = 1;
172 | b1 = 0;
173 | b2 = 0;
174 | };
175 |
176 | //----------------------- FLUE JET NON-LINEAR FUNCTION ----------------------------
177 | // Jet Table: flue jet non-linear function, computed by a polynomial calculation
178 |
179 | jetTable(x) = x <: _*(_*_-1) : saturationPos : saturationNeg;
180 |
181 | //----------------------- NON LINEAR MODULATOR ----------------------------
182 | // nonLinearModulator adapts the function allpassnn from filter.lib for using it with waveguide instruments (see the corresponding DAFx paper: (Faust-STK: a Set of Linear and Nonlinear Physical Models for the Faust Programming Language) for more details).
183 | //
184 | // USAGE:
185 | // _ : nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) : _
186 | // where
187 | // nonlinearity = nonlinearity coefficient between 0 and 1
188 | // env = input to connect any kind of envelope
189 | // freq = current tone frequency
190 | // typeMod = if 0: theta is modulated by the incoming signal;
191 | // if 1: theta is modulated by the averaged incoming signal;
192 | // if 2: theta is modulated by the squared incoming signal;
193 | // if 3: theta is modulated by a sine wave of frequency freqMod;
194 | // if 4: theta is modulated by a sine wave of frequency freq;
195 | // freqMod = frequency of the sine wave modulation
196 | // order = order of the filter
197 |
198 | nonLinearModulator(nonlinearity,env,freq,typeMod,freqMod,order) =
199 | //theta is modulated by a sine wave
200 | _ <: nonLinearFilterOsc*(typeMod >= 3),
201 | //theta is modulated by the incoming signal
202 | (_ <: nonLinearFilterSig*nonlinearity,_*(1 - nonlinearity) :> +)*(typeMod < 3)
203 | :> +
204 | with {
205 | //which frequency to use for the sine wave oscillator?
206 | freqOscMod = (typeMod == 4)*freq + (typeMod != 4)*freqMod;
207 |
208 | //the incoming signal is scaled and the envelope is applied
209 | tsignorm(x) = nonlinearity*ma.PI*x*env;
210 | tsigsquared(x) = nonlinearity*ma.PI*x*x*env; //incoming signal is squared
211 | tsigav(x) = nonlinearity*ma.PI*((x + x')/2)*env; //incoming signal is averaged with its previous sample
212 |
213 | //select which version of the incoming signal of theta to use
214 | tsig(x) = tsignorm(x)*(typeMod == 0) + tsigav(x)*(typeMod == 1)
215 | + tsigsquared(x)*(typeMod == 2);
216 |
217 | //theta is modulated by a sine wave generator
218 | tosc = nonlinearity*ma.PI*os.osc(freqOscMod)*env;
219 |
220 | //incoming signal is sent to the nonlinear passive allpass ladder filter
221 | nonLinearFilterSig(x) = x <: fi.allpassnn(order,(par(i,order,tsig(x))));
222 | nonLinearFilterOsc = _ <: fi.allpassnn(order,(par(i,order,tosc)));
223 | };
224 |
225 | //========================= TOOLS ===============================
226 |
227 | //----------------------- STEREOIZER ----------------------------
228 | // This function takes a mono input signal and spacialize it in stereo
229 | // in function of the period duration of the tone being played.
230 | //
231 | // USAGE:
232 | // _ : stereo(periodDuration) : _,_
233 | // where
234 | // periodDuration = period duration of the tone being played in number of samples
235 | // REFERENCE:
236 | //
237 |
238 | stereoizer(periodDuration) = _ <: _,widthdelay : stereopanner
239 | with {
240 | W = hslider("v:Spat/spatial width", 0.5, 0, 1, 0.01);
241 | A = hslider("v:Spat/pan angle", 0.6, 0, 1, 0.01);
242 | widthdelay = de.delay(4096,W*periodDuration/2);
243 | stereopanner = _,_ : *(1.0-A), *(A);
244 | };
245 |
246 | //----------------------- INSTRREVERB ----------------------------
247 | // GUI for zita_rev1_stereo from reverbs.lib
248 | //
249 | // USAGE:
250 | // _,_ : instrRerveb
251 |
252 | instrReverb = _,_ <: *(reverbGain),*(reverbGain),*(1 - reverbGain),*(1 - reverbGain) :
253 | re.zita_rev1_stereo(rdel,f1,f2,t60dc,t60m,fsmax),_,_ <: _,!,_,!,!,_,!,_ : +,+
254 | with {
255 | reverbGain = hslider("v:Reverb/reverbGain",0.137,0,1,0.01) : si.smoo;
256 | roomSize = hslider("v:Reverb/roomSize",0.72,0.01,2,0.01);
257 | rdel = 20;
258 | f1 = 200;
259 | f2 = 6000;
260 | t60dc = roomSize*3;
261 | t60m = roomSize*2;
262 | fsmax = 48000;
263 | };
264 |
--------------------------------------------------------------------------------
/licenses/stk-4.3.0.md:
--------------------------------------------------------------------------------
1 | # STK 4.3.0 License
2 |
3 | The Synthesis ToolKit in C++ (STK) is a set of open source audio
4 | signal processing and algorithmic synthesis classes written in the
5 | C++ programming language. STK was designed to facilitate rapid
6 | development of music synthesis and audio processing software, with
7 | an emphasis on cross-platform functionality, realtime control,
8 | ease of use, and educational example code. STK currently runs
9 | with realtime support (audio and MIDI) on Linux, Macintosh OS X,
10 | and Windows computer platforms. Generic, non-realtime support has
11 | been tested under NeXTStep, Sun, and other platforms and should
12 | work with any standard C++ compiler.
13 |
14 | STK WWW site: http://ccrma.stanford.edu/software/stk/
15 |
16 | The Synthesis ToolKit in C++ (STK)
17 | Copyright (c) 1995--2017 Perry R. Cook and Gary P. Scavone
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining
20 | a copy of this software and associated documentation files (the
21 | "Software"), to deal in the Software without restriction, including
22 | without limitation the rights to use, copy, modify, merge, publish,
23 | distribute, sublicense, and/or sell copies of the Software, and to
24 | permit persons to whom the Software is furnished to do so, subject to
25 | the following conditions:
26 |
27 | The above copyright notice and this permission notice shall be
28 | included in all copies or substantial portions of the Software.
29 |
30 | Any person wishing to distribute modifications to the Software is
31 | asked to send the modifications to the original developer so that they
32 | can be incorporated into the canonical version. This is, however, not
33 | a binding provision of this license.
34 |
35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
39 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
40 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
41 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/linearalgebra.lib:
--------------------------------------------------------------------------------
1 | //######################## linearalgebra.lib ######################################
2 | // A library of linear algebra functions. Its official prefix is `la`.
3 | //
4 | // This library adds some new linear algebra functions:
5 | //
6 | // `determinant`
7 | //
8 | // `minor`
9 | //
10 | // `inverse`
11 | //
12 | // `transpose2`
13 | //
14 | // `matMul` matrix multiplication
15 | //
16 | // `identity`
17 | //
18 | // `diag`
19 | //
20 | // How does it work? An `NxM` matrix can be flattened into a bus `si.bus(N*M)`. These buses can be passed to functions as long as `N` and sometimes `M` (if the matrix need not be square) are passed too.
21 | //
22 | // #### Some things to think about going forward
23 | //
24 | // ##### Implications for ML in Faust
25 | //
26 | // Next step of making a "Dense"/"Linear" layer from machine learning.
27 | // Where in the libraries should `ReLU` go?
28 | // What about 3D tensors instead of 2D matrices? Image convolutions take place on 3D tensors shaped `HxWxC`.
29 | //
30 | // #####Design of matMul
31 | //
32 | // Currently the design is `matMul(J, K, L, M, leftHandMat, rightHandMat)` where `leftHandMat` is `JxK` and `rightHandMat` is `LxM`.
33 | //
34 | // It would also be neat to have `matMul(J, K, rightHandMat, L, M, leftHandMat)`.
35 | //
36 | // Then a "packed" matrix could be consistently stored as a combination of a 2-channel "header" `N, M` and the values `si.bus(N*M)`.
37 | //
38 | // This would ultimately enable `result = packedLeftHand : matMul(packedRightHand);` for the equivalent numpy code: `result = packedLeftHand @ packedRightHand;`.
39 | //
40 | // #### References
41 | // *
42 | //#################################################################################
43 |
44 | /************************************************************************
45 | ************************************************************************
46 | FAUST library file
47 | Copyright (C) 2003-2024 GRAME, Centre National de Creation Musicale
48 | ----------------------------------------------------------------------
49 | This program is free software; you can redistribute it and/or modify
50 | it under the terms of the GNU Lesser General Public License as
51 | published by the Free Software Foundation; either version 2.1 of the
52 | License, or (at your option) any later version.
53 |
54 | This program is distributed in the hope that it will be useful,
55 | but WITHOUT ANY WARRANTY; without even the implied warranty of
56 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57 | GNU Lesser General Public License for more details.
58 |
59 | You should have received a copy of the GNU Lesser General Public
60 | License along with the GNU C Library; if not, write to the Free
61 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
62 | 02111-1307 USA.
63 |
64 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
65 | larger FAUST program which directly or indirectly imports this library
66 | file and still distribute the compiled code generated by the FAUST
67 | compiler, or a modified version of this compiled code, under your own
68 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
69 | grants you the right to freely choose the license for the resulting
70 | compiled code. In particular the resulting compiled code has no obligation
71 | to be LGPL or GPL. For example you are free to choose a commercial or
72 | closed source license or any other license if you decide so.
73 | ************************************************************************
74 | ************************************************************************/
75 |
76 | ba = library("basics.lib");
77 | si = library("signals.lib");
78 | ro = library("routes.lib");
79 |
80 | declare name "Faust Linear Algebra Library";
81 | declare version "0.1.0";
82 |
83 |
84 | //-----------`(la.)determinant`-------------------------
85 | // Calculates the determinant of a bus that represents
86 | // an `NxN` matrix.
87 | //
88 | // #### Usage
89 | // ```
90 | // si.bus(N*N) : determinant(N) : _
91 | // ```
92 | //
93 | // Where:
94 | //
95 | // * `N`: the size of each axis of the matrix.
96 | //------------------------------------------------------
97 | determinant(1) = _;
98 | determinant(2) = det2x2
99 | with {
100 | det2x2(a, b, c, d) = a * d - b * c;
101 | };
102 | determinant(N) = si.bus(N*N) <: sum(i, N, ((-1)^i) * ba.selector(i, N*N) * minor(N, 0, i));
103 | declare determinant author "David Braun";
104 | declare determinant copyright "MIT License";
105 |
106 |
107 | //-----------`(la.)minor`----------------------------------------------------
108 | // An utility for finding the matrix minor when inverting a matrix.
109 | // It returns the determinant of the submatrix formed by deleting the row at
110 | // index `ROW` and column at index `COL`.
111 | // The following implementation doesn't work but looks simple.
112 | // ```
113 | // minor(N, ROW, COL) = par(r, N, par(c, N, select2((ROW==r)||(COL==c),_,!))) : determinant(N-1);
114 | // ```
115 | //
116 | // #### Usage
117 | // ```
118 | // si.bus(N*N) : minor(N, ROW, COL) : _
119 | // ```
120 | //
121 | // Where:
122 | //
123 | // * `N`: the size of each axis of the matrix.
124 | // * `ROW`: the selected position on 0th dimension of the matrix (`0 <= ROW < N`)
125 | // * `COL`: the selected position on the 1st dimension of the matrix (`0 <= COL < N`)
126 | //
127 | // #### References
128 | // *
129 | //----------------------------------------------------------------------------
130 | minor(N, ROW, COL) = par(i, ROW, deleteColumn), deleteRow, par(i, N-1-ROW, deleteColumn) : determinant(N-1)
131 | with {
132 | deleteColumn = si.bus(COL), !, si.bus(N-1-COL);
133 | deleteRow = par(i, N, !);
134 | };
135 | declare minor author "David Braun";
136 | declare minor copyright "MIT License";
137 |
138 |
139 | //-----------`(la.)inverse`---------------------------------------------
140 | // Inverts a matrix. The incoming bus represents an `NxN` matrix.
141 | // Note, this is an unsafe operation since not all matrices are invertible.
142 | //
143 | // #### Usage
144 | // ```
145 | // si.bus(N*N) : inverse(N) : si.bus(N*N)
146 | // ```
147 | //
148 | // Where:
149 | //
150 | // * `N`: the size of each axis of the matrix.
151 | //---------------------------------------------------------------------
152 | inverse(1) = 1/_;
153 | inverse(2) = inverse2x2
154 | with {
155 | inverse2x2(a, b, c, d) = si.vecOp(((d, -b, -c, a), detBus), /)
156 | with {
157 | detBus = (a*d-b*c) <: si.bus(4);
158 | };
159 | };
160 | inverse(N) = si.bus(N*N) <: si.vecOp((adjugate(N), detBus), /)
161 | with {
162 | detBus = determinant(N) <: si.bus(N*N);
163 | adjugate(N) = si.bus(N*N) <: par(i, N * N, cofactorTranspose(N, i));
164 | cofactorTranspose(N, i) = (-1)^(ROW + COL) * minor(N, ROW, COL)
165 | with {
166 | ROW = floor(i / N);
167 | COL = i % N;
168 | };
169 | };
170 | declare inverse author "David Braun";
171 | declare inverse copyright "MIT License";
172 |
173 |
174 | //--------------`(la.)transpose2`-----------------------------------
175 | // Transposes an `NxM` matrix stored in row-major order, resulting
176 | // in an `MxN` matrix stored in row-major order.
177 | //
178 | // #### Usage
179 | // ```
180 | // si.bus(N*M) : transpose2(N, M) : si.bus(M*N)
181 | // ```
182 | //
183 | // Where:
184 | //
185 | // * `N`: the number of rows in the input matrix
186 | // * `M`: the number of columns in the input matrix
187 | //-----------------------------------------------------------------
188 | transpose2(N, M) = ro.interleave(M,N);
189 | declare transpose2 author "David Braun";
190 | declare transpose2 copyright "MIT License";
191 |
192 |
193 | //--------------`(la.)matMul`---------------------------------------------
194 | // Multiply a `JxK` matrix (mat1) and an `LxM` matrix (mat2) to produce a `JxM` matrix.
195 | // Note that `K==L`.
196 | // Both matrices should use row-major order.
197 | // In terms of numpy, this function is `mat1 @ mat2`.
198 | //
199 | // #### Usage
200 | // ```
201 | // matMul(J, K, L, M, si.bus(J*K), si.bus(L*M)) : si.bus(J*M)
202 | // ```
203 | //
204 | // Where:
205 | //
206 | // * `J`: the number of rows in `mat1`
207 | // * `K`: the number of columns in `mat1`
208 | // * `L`: the number of rows in `mat2`
209 | // * `M`: the number of columns in `mat2`
210 | //-----------------------------------------------------------------
211 | matMul(J, K, L, M) = si.bus(J*K), transpose2(L, M) <: par(j, J, par(m, M,
212 | si.dot(K, (ba.selectbus(K, J, j)), (ba.selectbus(L, M, m)))
213 | ));
214 | declare matMul author "David Braun";
215 | declare matMul copyright "MIT License";
216 |
217 |
218 | //---------------`(la.)identity`-------------------------
219 | // Creates an `NxN` identity matrix.
220 | //
221 | // #### Usage
222 | // ```
223 | // identity(N) : si.bus(N*N)
224 | // ```
225 | //
226 | // Where:
227 | //
228 | // * `N`: The size of each axis of the identity matrix.
229 | //-------------------------------------------------------
230 | identity(N) = par(i, N, par(j, N, i == j));
231 | declare identity author "David Braun";
232 | declare identity copyright "MIT License";
233 |
234 |
235 | //---------------`(la.)diag`-------------------------------
236 | // Creates a diagonal matrix of size `NxN` with specified
237 | // values along the diagonal.
238 | //
239 | // #### Usage
240 | // ```
241 | // si.bus(N) : diag(N) : si.bus(N*N)
242 | // ```
243 | //
244 | // Where:
245 | //
246 | // * `N`: The size of each axis of the matrix.
247 | //---------------------------------------------------------
248 | diag(N) = route(N, N*N, par(i,N, (i+1, (N+1)*i+1)));
249 | declare diag author "David Braun";
250 | declare diag copyright "MIT License";
251 |
--------------------------------------------------------------------------------
/maxmsp.lib:
--------------------------------------------------------------------------------
1 | //#################################### maxmsp.lib ########################################
2 | // MaxMSP compatibility Library.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 |
9 |
10 | /************************************************************************
11 | ************************************************************************
12 | FAUST library file
13 | Copyright (C) 2019-2020 GRAME, Centre National de Creation Musicale
14 | ---------------------------------------------------------------------
15 | This program is free software; you can redistribute it and/or modify
16 | it under the terms of the GNU Lesser General Public License as
17 | published by the Free Software Foundation; either version 2.1 of the
18 | License, or (at your option) any later version.
19 |
20 | This program is distributed in the hope that it will be useful,
21 | but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | GNU Lesser General Public License for more details.
24 |
25 | You should have received a copy of the GNU Lesser General Public
26 | License along with the GNU C Library; if not, write to the Free
27 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 | 02111-1307 USA.
29 |
30 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
31 | larger FAUST program which directly or indirectly imports this library
32 | file and still distribute the compiled code generated by the FAUST
33 | compiler, or a modified version of this compiled code, under your own
34 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
35 | grants you the right to freely choose the license for the resulting
36 | compiled code. In particular the resulting compiled code has no obligation
37 | to be LGPL or GPL. For example you are free to choose a commerci
38 | ************************************************************************
39 | ************************************************************************/
40 |
41 | ba = library("basics.lib");
42 | ma = library("maths.lib");
43 |
44 | declare name "MaxMSP compatibility Library";
45 | declare author "GRAME";
46 | declare copyright "GRAME";
47 | declare version "1.1.0";
48 | declare license "LGPL with exception";
49 |
50 | atodb = db2lin;
51 |
52 | //-------------------------------------------------------------------------
53 | //
54 | // Implementation of MaxMSP filtercoeff
55 | //
56 | // from : Cookbook formulae for audio EQ biquad filter coefficients
57 | // by : Robert Bristow-Johnson
58 | // URL :
59 | //
60 | //-------------------------------------------------------------------------
61 |
62 | filtercoeff(f0, dBgain, Q) = environment
63 | {
64 | //----------------------------------------
65 | // biquad coeffs for various filters
66 | // usage : filtercoeff(f0, dBgain, Q).LPF
67 | //----------------------------------------
68 |
69 | LPF = rbjcoef(a0, a1, a2, b0, b1, b2)
70 | with {
71 | b0 = (1 - cos(w0))/2;
72 | b1 = 1 - cos(w0);
73 | b2 = (1 - cos(w0))/2;
74 | a0 = 1 + alpha;
75 | a1 = -2*cos(w0);
76 | a2 = 1 - alpha;
77 | };
78 |
79 | HPF = rbjcoef(a0, a1, a2, b0, b1, b2)
80 | with {
81 | b0 = (1 + cos(w0))/2;
82 | b1 = -1 - cos(w0);
83 | b2 = (1 + cos(w0))/2;
84 | a0 = 1 + alpha;
85 | a1 = -2*cos(w0);
86 | a2 = 1 - alpha;
87 | };
88 |
89 | BPF = rbjcoef(a0, a1, a2, b0, b1, b2) // constant 0 dB peak gain
90 | with {
91 | b0 = alpha;
92 | b1 = 0;
93 | b2 = -alpha;
94 | a0 = 1 + alpha;
95 | a1 = -2*cos(w0);
96 | a2 = 1 - alpha;
97 | };
98 |
99 | notch = rbjcoef(a0, a1, a2, b0, b1, b2)
100 | with {
101 | b0 = 1;
102 | b1 = -2*cos(w0);
103 | b2 = 1;
104 | a0 = 1 + alpha;
105 | a1 = -2*cos(w0);
106 | a2 = 1 - alpha;
107 | };
108 |
109 | APF = rbjcoef(a0, a1, a2, b0, b1, b2)
110 | with {
111 | b0 = 1 - alpha;
112 | b1 = -2*cos(w0);
113 | b2 = 1 + alpha;
114 | a0 = 1 + alpha;
115 | a1 = -2*cos(w0);
116 | a2 = 1 - alpha;
117 | };
118 |
119 | peakingEQ = rbjcoef(a0, a1, a2, b0, b1, b2)
120 | with {
121 | b0 = 1 + alpha*A;
122 | b1 = -2*cos(w0);
123 | b2 = 1 - alpha*A;
124 | a0 = 1 + alpha/A;
125 | a1 = -2*cos(w0);
126 | a2 = 1 - alpha/A;
127 | };
128 |
129 | peakNotch = rbjcoef(a0, a1, a2, b0, b1, b2)
130 | with {
131 | b0 = 1 + alpha*G;
132 | b1 = -2*cos(w0);
133 | b2 = 1 - alpha*G;
134 | a0 = 1 + alpha/G;
135 | a1 = -2*cos(w0);
136 | a2 = 1 - alpha/G;
137 | };
138 |
139 | lowShelf = rbjcoef(a0, a1, a2, b0, b1, b2)
140 | with {
141 | b0 = A*((A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha);
142 | b1 = 2*A*((A-1) - (A+1)*cos(w0));
143 | b2 = A*((A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha);
144 | a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
145 | a1 = -2*((A-1) + (A+1)*cos(w0));
146 | a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
147 | };
148 |
149 | highShelf = rbjcoef(a0, a1, a2, b0, b1, b2)
150 | with {
151 | b0 = A*((A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha);
152 | b1 = -2*A*((A-1) + (A+1)*cos(w0));
153 | b2 = A*((A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha);
154 | a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
155 | a1 = 2*((A-1) - (A+1)*cos(w0));
156 | a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
157 | };
158 |
159 | // --------------------- implementation ------------------------------
160 |
161 | // convert rbj coeffs to biquad coeffs
162 | rbjcoef(a0,a1,a2,b0,b1,b2) = (b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
163 |
164 | // common values
165 | alpha = sin(w0)/(2*max(0.001,Q));
166 | w0 = 2*ma.PI*max(0,f0)/Fs;
167 | Fs = ma.SR;
168 | A = 10^(dBgain/40); // (for peaking and shelving EQ filters only)
169 | G = sqrt(max(0.00001, dBgain)); // When gain is a linear values (i.e. not in dB)
170 | };
171 |
172 |
173 | //-------------------------------------------------------------------------
174 | // Implementation of MaxMSP biquad~
175 | // y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2] - b1 * y[n-1] - b2 * y[n-2]
176 | //-------------------------------------------------------------------------
177 |
178 | biquad(x,a0,a1,a2,b1,b2) = x : + ~ ((-1)*conv2(b1, b2)) : conv3(a0, a1, a2)
179 | with {
180 | conv2(c0,c1,x) = c0*x+c1*x';
181 | conv3(c0,c1,c2,x) = c0*x+c1*x'+c2*x'';
182 | };
183 |
184 | //-------------------------------------------------------------------------
185 | //
186 | // Filters using filtercoeff and biquad
187 | //
188 | //-------------------------------------------------------------------------
189 |
190 | // Low Pass Filter
191 | LPF(x, f0, gain, Q)= x , filtercoeff(f0,gain,Q).LPF : biquad;
192 |
193 | // High Pass Filter
194 | HPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).HPF : biquad;
195 |
196 | // Band Pass Filter
197 | BPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).BPF : biquad;
198 |
199 | // notch Filter
200 | notch(x, f0, gain, Q)= x , filtercoeff(f0,gain,Q).notch : biquad;
201 |
202 | // All Pass Filter
203 | APF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).APF : biquad;
204 |
205 | // ????
206 | peakingEQ(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakingEQ : biquad;
207 |
208 | // Max peakNotch is like peakingEQ but with a linear gain
209 | peakNotch(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakNotch : biquad;
210 |
211 | // ????
212 | lowShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).lowShelf : biquad;
213 |
214 | // ????
215 | highShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).highShelf : biquad;
216 |
217 |
218 | //-------------------------------------------------------------------------
219 | // Implementation of Max/MSP line~. Generate signal ramp or envelop
220 | //
221 | // USAGE : line(value, time)
222 | // value : the desired output value
223 | // time : the interpolation time to reach this value (in milliseconds)
224 | //
225 | // NOTE : the interpolation process is restarted every time the desired
226 | // output value changes. The interpolation time is sampled only then.
227 | //-------------------------------------------------------------------------
228 |
229 | line(value, time) = state~(_,_):!,_
230 | with {
231 | state(t, c) = nt,nc
232 | with {
233 | nt = ba.if(value != value', samples, t-1);
234 | nc = ba.if(nt > 0, c + (value - c)/nt, value);
235 | samples = time*ma.SR/1000.0;
236 | };
237 | };
238 |
--------------------------------------------------------------------------------
/modalmodels/carillonBell/.gitignore:
--------------------------------------------------------------------------------
1 | carillonBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/carillonBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile carillonBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 3500 3632 3629 3490 3550 3487 3484 --debug --material 1.05E11 0.33 8600 --name carillonBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/carillonBell/carillonBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/carillonBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied Acoustics 2, 1987.
4 |
5 | Model height is 301 mm.
6 |
7 | To turn `carillonBell.obj` into a Faust physical model (`carillonBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/churchBell/.gitignore:
--------------------------------------------------------------------------------
1 | churchBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/churchBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile churchBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 5248 5243 5239 5235 5296 5228 5001 --debug --material 1.05E11 0.33 8600 --name churchBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/churchBell/churchBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/churchBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied Acoustics 2, 1987.
4 |
5 | Model height is 301 mm.
6 |
7 | To turn `churchBell.obj` into a Faust physical model (`churchBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/englishBell/.gitignore:
--------------------------------------------------------------------------------
1 | englishBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/englishBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile englishBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 7840 5752 776 7759 7682 7827 7823 --debug --material 1.05E11 0.33 8600 --name englishBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/englishBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after D. Bartocha and . Baron, Influence of Tin Bronze Melting and Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry Engineering, 2016.
4 |
5 | Model height is 1 meter.
6 |
7 | To turn `englishBell.obj` into a Faust physical model (`englishBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/englishBell/englishBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/frenchBell/.gitignore:
--------------------------------------------------------------------------------
1 | frenchBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/frenchBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile frenchBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 4566 4716 4710 4708 4551 4534 4378 --debug --material 1.05E11 0.33 8600 --name frenchBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/frenchBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after D. Bartocha and . Baron, Influence of Tin Bronze Melting and Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry Engineering, 2016.
4 |
5 | Model height is 1 meter.
6 |
7 | To turn `frenchBell.obj` into a Faust physical model (`frenchBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/frenchBell/frenchBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/germanBell/.gitignore:
--------------------------------------------------------------------------------
1 | germanBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/germanBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile germanBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 1946 1864 1781 1705 1614 1468 1912 --debug --material 1.05E11 0.33 8600 --name germanBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/germanBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after D. Bartocha and . Baron, Influence of Tin Bronze Melting and Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry Engineering, 2016.
4 |
5 | Model height is 1 meter.
6 |
7 | To turn `germanBell.obj` into a Faust physical model (`germanBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/germanBell/germanBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/marimbaBar/.gitignore:
--------------------------------------------------------------------------------
1 | marimbaBarModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/marimbaBar/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile marimbaBar.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 15000 --expos 2831 3208 3624 3975 4403 --debug --freqcontrol --material 1.3E9 0.33 720 --name marimbaBarModel
4 |
--------------------------------------------------------------------------------
/modalmodels/marimbaBar/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Model is 440mm*50mm (C2 bar).
4 |
5 | To turn `marimbaBar.obj` into a Faust physical model (marimbaBarModel.lib), just run `./build`.
6 |
--------------------------------------------------------------------------------
/modalmodels/marimbaBar/marimbaBar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/russianBell/.gitignore:
--------------------------------------------------------------------------------
1 | russianBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/russianBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile russianBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 4905 4748 4743 4737 4674 4885 4810 --debug --material 1.05E11 0.33 8600 --name russianBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/russianBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after D. Bartocha and . Baron, Influence of Tin Bronze Melting and Pouring Parameters on Its Properties and Bell' Tone, Archives of Foundry Engineering, 2016.
4 |
5 | Model height is 2 meters.
6 |
7 | To turn `russianBell.obj` into a Faust physical model (`russianBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/russianBell/russianBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/modalmodels/standardBell/.gitignore:
--------------------------------------------------------------------------------
1 | standardBellModel.lib
2 |
--------------------------------------------------------------------------------
/modalmodels/standardBell/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mesh2faust --infile standardBell.obj --nsynthmodes 50 --nfemmodes 200 --maxmode 10000 --expos 6236 6232 6066 6224 6291 6219 6142 --debug --material 1.05E11 0.33 8600 --name standardBellModel
4 |
--------------------------------------------------------------------------------
/modalmodels/standardBell/description.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Modeled after T. Rossing and R. Perrin, Vibrations of Bells, Applied Acoustics 2, 1987.
4 |
5 | Model height is 1.8 meters.
6 |
7 | To turn `standardBell.obj` into a Faust physical model (`standardBellModel.lib`), just run `./build`.
8 |
--------------------------------------------------------------------------------
/modalmodels/standardBell/standardBell.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/phaflangers.lib:
--------------------------------------------------------------------------------
1 | //#################################### phaflangers.lib ########################################
2 | // A library of phasor and flanger effects. Its official prefix is `pf`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 | ma = library("maths.lib");
9 | de = library("delays.lib");
10 | fi = library("filters.lib");
11 | os = library("oscillators.lib");
12 | pf = library("phaflangers.lib");
13 |
14 | declare name "Faust Phaser and Flanger Library";
15 | declare version "1.1.0";
16 |
17 | //########################################################################################
18 | /************************************************************************
19 | FAUST library file, JOS section
20 |
21 | Except where noted otherwise, The Faust functions below in this
22 | section are Copyright (C) 2003-2017 by Julius O. Smith III
23 | ([jos](http://ccrma.stanford.edu/~jos/)), and released under the
24 | (MIT-style) [STK-4.3](#stk-4.3-license) license.
25 |
26 | All MarkDown comments in this section are Copyright 2016-2017 by Romain
27 | Michon and Julius O. Smith III, and are released under the
28 | [CCA4I](https://creativecommons.org/licenses/by/4.0/) license (TODO: if/when Romain agrees!)
29 |
30 | ************************************************************************/
31 |
32 | //=============================Functions Reference========================================
33 | //========================================================================================
34 |
35 | //---------------`(pf.)flanger_mono`-------------
36 | // Mono flanging effect.
37 | //
38 | // #### Usage:
39 | //
40 | // ```
41 | // _ : flanger_mono(dmax,curdel,depth,fb,invert) : _
42 | // ```
43 | //
44 | // Where:
45 | //
46 | // * `dmax`: maximum delay-line length (power of 2) - 10 ms typical
47 | // * `curdel`: current dynamic delay (not to exceed dmax)
48 | // * `depth`: effect strength between 0 and 1 (1 typical)
49 | // * `fb`: feedback gain between 0 and 1 (0 typical)
50 | // * `invert`: 0 for normal, 1 to invert sign of flanging sum
51 | //
52 | // #### Reference
53 | //
54 | //
55 | //------------------------------------------------------------
56 | flanger_mono(dmax,curdel,depth,fb,invert)
57 | = _ <: _, (- : de.fdelay(dmax,curdel)) ~ *(fb) : _,
58 | *(select2(invert,depth,0-depth))
59 | : + : *(0.5);
60 |
61 | //---------------`(pf.)flanger_stereo`-------------
62 | // Stereo flanging effect.
63 | // `flanger_stereo` is a standard Faust function.
64 | //
65 | // #### Usage:
66 | //
67 | // ```
68 | // _,_ : flanger_stereo(dmax,curdel1,curdel2,depth,fb,invert) : _,_
69 | // ```
70 | //
71 | // Where:
72 | //
73 | // * `dmax`: maximum delay-line length (power of 2) - 10 ms typical
74 | // * `curdel1`: current dynamic delay for the left channel (not to exceed dmax)
75 | // * `curdel2`: current dynamic delay for the right channel (not to exceed dmax)
76 | // * `depth`: effect strength between 0 and 1 (1 typical)
77 | // * `fb`: feedback gain between 0 and 1 (0 typical)
78 | // * `invert`: 0 for normal, 1 to invert sign of flanging sum
79 | //
80 | // #### Reference
81 | //
82 | //
83 | //------------------------------------------------------------
84 | flanger_stereo(dmax,curdel1,curdel2,depth,fb,invert)
85 | = flanger_mono(dmax,curdel1,depth,fb,invert),
86 | flanger_mono(dmax,curdel2,depth,fb,invert);
87 |
88 |
89 | vibrato2_mono(sections,phase01,fb,width,frqmin,fratio,frqmax,speed) =
90 | (+ : seq(i,sections,ap2p(R,th(i)))) ~ *(fb)
91 | with {
92 | //tf2 = component("filters.lib").tf2;
93 | // second-order resonant digital allpass given pole radius and angle:
94 | ap2p(R,th) = fi.tf2(a2,a1,1,a1,a2) with {
95 | a2 = R^2;
96 | a1 = -2*R*cos(th);
97 | };
98 | R = exp(-pi*width/ma.SR);
99 | cososc = os.oscrc; // oscillators.lib
100 | sinosc = os.oscrs; // oscillators.lib
101 | osc = cososc(speed) * phase01 + sinosc(speed) * (1-phase01);
102 | lfo = (1-osc)/2; // in [0,1]
103 | pi = 4*atan(1);
104 | thmin = 2*pi*frqmin/ma.SR;
105 | thmax = 2*pi*frqmax/ma.SR;
106 | th1 = thmin + (thmax-thmin)*lfo;
107 | th(i) = (fratio^(i+1))*th1;
108 | };
109 |
110 |
111 | //-------`(pf.)phaser2_mono`-----------------
112 | // Mono phasing effect.
113 | //
114 | // #### Phaser
115 | //
116 | // ```
117 | // _ : phaser2_mono(Notches,phase,width,frqmin,fratio,frqmax,speed,depth,fb,invert) : _
118 | // ```
119 | //
120 | // Where:
121 | //
122 | // * `Notches`: number of spectral notches (MACRO ARGUMENT - not a signal)
123 | // * `phase`: phase of the oscillator (0-1)
124 | // * `width`: approximate width of spectral notches in Hz
125 | // * `frqmin`: approximate minimum frequency of first spectral notch in Hz
126 | // * `fratio`: ratio of adjacent notch frequencies
127 | // * `frqmax`: approximate maximum frequency of first spectral notch in Hz
128 | // * `speed`: LFO frequency in Hz (rate of periodic notch sweep cycles)
129 | // * `depth`: effect strength between 0 and 1 (1 typical) (aka "intensity")
130 | // when depth=2, "vibrato mode" is obtained (pure allpass chain)
131 | // * `fb`: feedback gain between -1 and 1 (0 typical)
132 | // * `invert`: 0 for normal, 1 to invert sign of flanging sum
133 | //
134 | // Reference:
135 | //
136 | // *
137 | // *
138 | // * 'An Allpass Approach to Digital Phasing and Flanging', Julius O. Smith III,
139 | // Proc. Int. Computer Music Conf. (ICMC-84), pp. 103-109, Paris, 1984.
140 | // * CCRMA Tech. Report STAN-M-21:
141 | //------------------------------------------------------------
142 | phaser2_mono(Notches,phase01,width,frqmin,fratio,frqmax,speed,depth,fb,invert) =
143 | _ <: *(g1) + g2mi*vibrato2_mono(Notches,phase01,fb,width,frqmin,fratio,frqmax,speed)
144 | with { // depth=0 => direct-signal only
145 | g1 = 1-depth/2; // depth=1 => phaser mode (equal sum of direct and allpass-chain)
146 | g2 = depth/2; // depth=2 => vibrato mode (allpass-chain signal only)
147 | g2mi = select2(invert,g2,-g2); // inversion negates the allpass-chain signal
148 | };
149 |
150 |
151 | //-------`(pf.)phaser2_stereo`-------
152 | // Stereo phasing effect.
153 | // `phaser2_stereo` is a standard Faust function.
154 | //
155 | // #### Phaser
156 | //
157 | // ```
158 | // _,_ : phaser2_stereo(Notches,width,frqmin,fratio,frqmax,speed,depth,fb,invert) : _,_
159 | // ```
160 | //
161 | // Where:
162 | //
163 | // * `Notches`: number of spectral notches (MACRO ARGUMENT - not a signal)
164 | // * `width`: approximate width of spectral notches in Hz
165 | // * `frqmin`: approximate minimum frequency of first spectral notch in Hz
166 | // * `fratio`: ratio of adjacent notch frequencies
167 | // * `frqmax`: approximate maximum frequency of first spectral notch in Hz
168 | // * `speed`: LFO frequency in Hz (rate of periodic notch sweep cycles)
169 | // * `depth`: effect strength between 0 and 1 (1 typical) (aka "intensity")
170 | // when depth=2, "vibrato mode" is obtained (pure allpass chain)
171 | // * `fb`: feedback gain between -1 and 1 (0 typical)
172 | // * `invert`: 0 for normal, 1 to invert sign of flanging sum
173 | //
174 | // Reference:
175 | //
176 | // *
177 | // *
178 | // * 'An Allpass Approach to Digital Phasing and Flanging', Julius O. Smith III,
179 | // Proc. Int. Computer Music Conf. (ICMC-84), pp. 103-109, Paris, 1984.
180 | // * CCRMA Tech. Report STAN-M-21:
181 | //------------------------------------------------------------
182 | phaser2_stereo(Notches,width,frqmin,fratio,frqmax,speed,depth,fb,invert)
183 | = phaser2_mono(Notches,0,width,frqmin,fratio,frqmax,speed,depth,fb,invert),
184 | phaser2_mono(Notches,1,width,frqmin,fratio,frqmax,speed,depth,fb,invert);
185 |
186 | // end jos section
187 | /************************************************************************
188 | ************************************************************************
189 | FAUST library file, GRAME section
190 |
191 | Except where noted otherwise, Copyright (C) 2003-2017 by GRAME,
192 | Centre National de Creation Musicale.
193 | ----------------------------------------------------------------------
194 | GRAME LICENSE
195 |
196 | This program is free software; you can redistribute it and/or modify
197 | it under the terms of the GNU Lesser General Public License as
198 | published by the Free Software Foundation; either version 2.1 of the
199 | License, or (at your option) any later version.
200 |
201 | This program is distributed in the hope that it will be useful,
202 | but WITHOUT ANY WARRANTY; without even the implied warranty of
203 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
204 | GNU Lesser General Public License for more details.
205 |
206 | You should have received a copy of the GNU Lesser General Public
207 | License along with the GNU C Library; if not, write to the Free
208 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
209 | 02111-1307 USA.
210 |
211 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
212 | larger FAUST program which directly or indirectly imports this library
213 | file and still distribute the compiled code generated by the FAUST
214 | compiler, or a modified version of this compiled code, under your own
215 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
216 | grants you the right to freely choose the license for the resulting
217 | compiled code. In particular the resulting compiled code has no obligation
218 | to be LGPL or GPL. For example you are free to choose a commercial or
219 | closed source license or any other license if you decide so.
220 | ************************************************************************
221 | ************************************************************************/
222 |
223 | // TODO: Add GRAME functions here
224 |
225 | //########################################################################################
226 | /************************************************************************
227 | FAUST library file, further contributions section
228 |
229 | All contributions below should indicate both the contributor and terms
230 | of license. If no such indication is found, "git blame" will say who
231 | last edited each line, and that person can be emailed to inquire about
232 | license disposition, if their license choice is not already indicated
233 | elsewhere among the libraries. It is expected that all software will be
234 | released under LGPL, STK-4.3, MIT, BSD, or a similar FOSS license.
235 | ************************************************************************/
236 |
--------------------------------------------------------------------------------
/platform.lib:
--------------------------------------------------------------------------------
1 | //#################################### platform.lib ########################################
2 | // A library to handle platform specific code in Faust. Its official prefix is `pl`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 | // It can be reimplemented to globally change the SR and the tablesize definitions
8 |
9 |
10 | /************************************************************************
11 | ************************************************************************
12 | FAUST library file
13 | Copyright (C) 2020 GRAME, Centre National de Creation Musicale
14 | ----------------------------------------------------------------------
15 | This program is free software; you can redistribute it and/or modify
16 | it under the terms of the GNU Lesser General Public License as
17 | published by the Free Software Foundation; either version 2.1 of the
18 | License, or (at your option) any later version.
19 |
20 | This program is distributed in the hope that it will be useful,
21 | but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | GNU Lesser General Public License for more details.
24 |
25 | You should have received a copy of the GNU Lesser General Public
26 | License along with the GNU C Library; if not, write to the Free
27 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 | 02111-1307 USA.
29 |
30 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
31 | larger FAUST program which directly or indirectly imports this library
32 | file and still distribute the compiled code generated by the FAUST
33 | compiler, or a modified version of this compiled code, under your own
34 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
35 | grants you the right to freely choose the license for the resulting
36 | compiled code. In particular the resulting compiled code has no obligation
37 | to be LGPL or GPL. For example you are free to choose a commercial or
38 | closed source license or any other license if you decide so.
39 | ************************************************************************
40 | ************************************************************************/
41 |
42 | declare name "Generic Platform Library";
43 | declare version "1.3.0";
44 |
45 | //---------------------------------`(pl.)SR`-----------------------------------
46 | // Current sampling rate (between 1 and 192000Hz). Constant during
47 | // program execution. Setting this value to a constant will allow the
48 | // compiler to optimize the code by computing constant expressions at
49 | // compile time, and can be valuable for performance, especially on
50 | // embedded systems.
51 | //-----------------------------------------------------------------------------
52 | SR = min(192000.0, max(1.0, fconstant(int fSamplingFreq, )));
53 |
54 | //---------------------------------`(pl.)BS`---------------------------------------
55 | // Current block-size (between 1 and 16384 frames). Can change during the execution.
56 | //-----------------------------------------------------------------------------
57 | BS = min(16384.0, max(1.0, fvariable(int count, )));
58 |
59 | //---------------------------------`(pl.)tablesize`----------------------------
60 | // Oscillator table size. This value is used to define the size of the
61 | // table used by the oscillators. It is usually a power of 2 and can be lowered
62 | // to save memory. The default value is 65536.
63 | //-----------------------------------------------------------------------------
64 | tablesize = 1 << 16;
65 |
--------------------------------------------------------------------------------
/quantizers.lib:
--------------------------------------------------------------------------------
1 | //##################################### quantizers.lib ########################################
2 | // Faust Frequency Quantization Library. Its official prefix is `qu`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 | ba = library("basics.lib");
9 | it = library("interpolators.lib");
10 |
11 | declare name "Faust Frequency Quantization Library";
12 | declare version "1.1.1";
13 |
14 | //=============================Functions Reference========================================
15 | //========================================================================================
16 |
17 | /************************************************************************
18 | ************************************************************************
19 | This is free and unencumbered software released into the public domain.
20 |
21 | Anyone is free to copy, modify, publish, use, compile, sell, or
22 | distribute this software, either in source code form or as a compiled
23 | binary, for any purpose, commercial or non-commercial, and by any
24 | means.
25 |
26 | In jurisdictions that recognize copyright laws, the author or authors
27 | of this software dedicate any and all copyright interest in the
28 | software to the public domain. We make this dedication for the benefit
29 | of the public at large and to the detriment of our heirs and
30 | successors. We intend this dedication to be an overt act of
31 | relinquishment in perpetuity of all present and future rights to this
32 | software under copyright law.
33 |
34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
38 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
39 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 | OTHER DEALINGS IN THE SOFTWARE.
41 |
42 | For more information, please refer to
43 | ************************************************************************
44 | ************************************************************************/
45 |
46 | MinFreq = 10;
47 | MaxFreq = 20000;
48 | TableSize = 1024;
49 |
50 | qLog(x) = ba.tabulate(1,log(_),TableSize,MinFreq,MaxFreq,x).cub;
51 | qSmooth(x) = ba.tabulate(1,0.5*atan(_*20-10)/1.4711+0.5,TableSize,0,1,x).cub;
52 |
53 |
54 | //-------`(qu.)quantize`----------
55 | // Configurable frequency quantization tool. Output only the frequencies that are part of the specified scale.
56 | // Works for positive audio frequencies.
57 | //
58 | // #### Usage
59 | //
60 | // ```
61 | // _ : quantize(rf,nl) : _
62 | // ```
63 | // Where :
64 | //
65 | // * `rf` : frequency of the root note of the scale
66 | // * `nl` : list of the ratio of the frequencies of each note in relation to the root frequency
67 | //------------------------
68 | quantize(rf,nl) = _<: octave,_ <: _,!,noteRatio(nN) : rf*_*_
69 | with{
70 | octave = (qLog(_)-log(rf))/log(2) <: select2(_<0, 1<((_/oct)/rf))*(noteRatio(n-1,oct));
75 | };
76 |
77 |
78 | //-------`(qu.)quantizeSmoothed`----------
79 | // Configurable frequency quantization tool. Output frequencies that are closer to the frequencies of the specified scale notes.
80 | // Works for positive audio frequencies.
81 | //
82 | //
83 | // #### Usage
84 | //
85 | // ```
86 | // _ : quantizeSmoothed(rf,nl) : _
87 | // nl = (1,1.2,1.4,1.7);
88 | // ```
89 | // Where :
90 | //
91 | // * `rf` : frequency of the root note of the scale
92 | // * `nl` : list of the ratio of the frequencies of each note in relation to the root frequency
93 | //------------------------
94 | quantizeSmoothed(rf,nl) = _<: octave,_ <: _,!,noteRatio(nN) : rf*_*_
95 | with{
96 | octave = (qLog(_)-log(rf))/log(2)<: select3((_>0)+(_>=0),
97 | (1/(1<((_/oct)/rf))*(noteRatio(n-1,oct));
105 |
106 | findValue(n,oct) = _<: (n
14 | //#############################################################################
15 |
16 | /************************************************************************
17 | ************************************************************************
18 | FAUST library file
19 | Copyright (C) 2023 Yann Orlarey
20 | Copyright (C) 2010-2023 GRAME, Centre National de Creation Musicale
21 | ---------------------------------------------------------------------
22 | This program is free software; you can redistribute it and/or modify
23 | it under the terms of the GNU Lesser General Public License as
24 | published by the Free Software Foundation; either version 2.1 of the
25 | License, or (at your option) any later version.
26 |
27 | This program is distributed in the hope that it will be useful,
28 | but WITHOUT ANY WARRANTY; without even the implied warranty of
29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 | GNU Lesser General Public License for more details.
31 |
32 | You should have received a copy of the GNU Lesser General Public
33 | License along with the GNU C Library; if not, write to the Free
34 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
35 | 02111-1307 USA.
36 |
37 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
38 | larger FAUST program which directly or indirectly imports this library
39 | file and still distribute the compiled code generated by the FAUST
40 | compiler, or a modified version of this compiled code, under your own
41 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
42 | grants you the right to freely choose the license for the resulting
43 | compiled code. In particular the resulting compiled code has no obligation
44 | to be LGPL or GPL. For example you are free to choose a commercial or
45 | closed source license or any other license if you decide so.
46 | ************************************************************************
47 | ************************************************************************/
48 |
49 | ba = library("basics.lib");
50 |
51 | declare name "Reduce Library";
52 | declare author "Yann Orlarey";
53 | declare copyright "Grame and Yann Orlarey";
54 | declare version "1.2.0";
55 | declare license "LGPL with exception";
56 |
57 |
58 |
59 | //----------------------------`(rm.)parReduce`--------------------------------
60 | // `parReduce(op,N)` combines a set of `N` parallel signals into a single one
61 | // using a binary operation `op`.
62 | //
63 | // With `parReduce`, this reduction process simultaneously occurs on each half
64 | // of the incoming signals. In other words, `parReduce(max,256)` is equivalent
65 | // to `parReduce(max,128),parReduce(max,128) : max`.
66 | //
67 | // To be used with `parReduce`, binary operation `op` must be associative.
68 | // Additionally, the concept of a binary operation extends to operations
69 | // that have `2*n` inputs and `n` outputs. For example, complex signals can be
70 | // simulated using two signals for the real and imaginary parts. In
71 | // such case, a binary operation would have 4 inputs and 2 outputs.
72 | //
73 | // Please note also that `parReduce` is faster than `topReduce` or `botReduce`
74 | // for large number of signals. It is therefore the recommended operation
75 | // whenever `op` is associative.
76 | //
77 | // #### Usage
78 | //
79 | // ```
80 | // _,...,_ : parReduce(op, N) : _
81 | // ```
82 | //
83 | // Where:
84 | //
85 | // * `op`: is a binary operation
86 | // * `N`: is the number of incomming signals (`N>0`). We use a capital letter
87 | // here to indicate that the number of incomming signals must be constant and
88 | // known at compile time.
89 | //-----------------------------------------------------------------------------
90 |
91 | parReduce(op,1) = par(i,outputs(op),_);
92 | parReduce(op,2) = op;
93 | parReduce(op,N) = parReduce(op,int(N/2)), parReduce(op,N-int(N/2)) : op;
94 |
95 |
96 |
97 |
98 | //----------------------------`(rm.)topReduce`--------------------------------
99 | // `topReduce(op,N)` involves combining a set of `N` parallel signals into a
100 | // single one using a binary operation `op`. With `topReduce`, the reduction
101 | // process starts from the top two incoming signals, down to the bottom. In
102 | // other words, `topReduce(max,256)` is equivalent to `topReduce(max,255),_ : max`.
103 | //
104 | // Contrary to `parReduce`, the binary operation `op` doesn't have to be
105 | // associative here. Like with `parReduce` the concept of a binary operation can be
106 | // extended to operations that have 2*n inputs and n outputs. For example,
107 | // complex signals can be simulated using two signals representing the real and
108 | // imaginary parts. In such cases, a binary operation would have 4 inputs and 2
109 | // outputs.
110 | //
111 | // #### Usage
112 | //
113 | // ```
114 | // _,...,_ : topReduce(op, N) : _
115 | // ```
116 | //
117 | // Where:
118 | //
119 | // * `op`: is a binary operation
120 | // * `N`: is the number of incomming signals (`N>0`). We use a capital letter
121 | // here to indicate that the number of incomming signals must be constant and
122 | // known at compile time.
123 | //-----------------------------------------------------------------------------
124 |
125 | topReduce(op,1) = par(i,outputs(op),_);
126 | topReduce(op,2) = op;
127 | topReduce(op,N) = topReduce(op,N-1), par(i,outputs(op),_) : op;
128 |
129 |
130 |
131 | //----------------------------`(rm.)botReduce`--------------------------------
132 | // `botReduce(op,N)` combines a set of `N` parallel signals into a single one
133 | // using a binary operation `op`. With `botReduce`, the reduction process starts
134 | // from the bottom two incoming signals, up to the top. In other words,
135 | // `botReduce(max,256)` is equivalent to `_,botReduce(max,255): max`.
136 | //
137 | // Contrary to `parReduce`, the binary operation `op` doesn't have to be
138 | // associative here. Like with `parReduce` the concept of a binary operation can be
139 | // extended to operations that have 2*n inputs and n outputs. For example,
140 | // complex signals can be simulated using two signals representing the real and
141 | // imaginary parts. In such cases, a binary operation would have 4 inputs and 2
142 | // outputs.
143 | //
144 | // #### Usage
145 | //
146 | // ```
147 | // _,...,_ : botReduce(op, N) : _
148 | // ```
149 | //
150 | // Where:
151 | //
152 | // * op: is a binary operation
153 | // * N: is the number of incomming signals (`N>0`). We use a capital letter
154 | // here to indicate that the number of incomming signals must be constant and
155 | // known at compile time.
156 | //-----------------------------------------------------------------------------
157 |
158 | botReduce(op,1) = par(i,outputs(op),_);
159 | botReduce(op,2) = op;
160 | botReduce(op,n) = par(i,outputs(op),_), botReduce(op,n-1) : op;
161 |
162 |
163 | //--------------------------------`(rm.)reduce`--------------------------------
164 | // Reduce a block of `n` consecutive samples of the incomming signal using a
165 | // binary operation `op`. For example: `reduce(max,128)` will compute the
166 | // maximun value of each block of 128 samples. Please note that the resulting
167 | // value, while computed continuously, will be constant for the duration of a
168 | // block. A new value is only produced at the end of a block. Note also that
169 | // blocks should be of at least one sample (n>0).
170 | //
171 | // #### Usage
172 | //
173 | // ```
174 | // _ : reduce(op, n) : _
175 | // ```
176 | //
177 | // Where:
178 | //
179 | // * `op`: is a binary operation
180 | // * `n`: is the number of consecutive samples in a block.
181 | //-----------------------------------------------------------------------------
182 |
183 | reduce(op, n, x) = compute ~ (_,_,_) : (!,!,_)
184 | with {
185 | compute(acc, count, val) =
186 | ba.if(count $@
22 | echo "margin=0.05;\n" >> $@
23 | egrep "=[ \t]*library|^import" $(LIBS) | sed -e 's/^\.\.\///' \
24 | | sed -e 's/:.*=[ \t]*library("/ -> /' | sed -e 's/:import("/ -> /' \
25 | | sed -e 's/"..*/;/' |sed -e 's/\.lib//g' | sed -e 's/\//_/g' >> $@
26 | echo "}" >> $@
27 |
28 | internal_deps.pdf: internal_deps.dot
29 |
30 | internal_deps.dot:
31 | echo "digraph impl { " > $@
32 | echo "margin=0.05;\n" >> $@
33 | egrep "=[ \t]*library|^import" $(INTERNAL_LIBS) | sed -e 's/^\.\.\///' \
34 | | sed -e 's/:.*=[ \t]*library("/ -> /' | sed -e 's/:import("/ -> /' \
35 | | sed -e 's/"..*/;/' |sed -e 's/\.lib//g' | sed -e 's/\//_/g' >> $@
36 | echo "}" >> $@
37 |
38 | clean:
39 | rm -f deps.pdf deps.dot internal_deps.pdf internal_deps.dot
40 |
41 | test:
42 | echo $(LIBS)
43 |
44 | %.pdf: %.dot
45 | dot -Tpdf -o $@ $<
46 |
47 |
--------------------------------------------------------------------------------
/resources/README.md:
--------------------------------------------------------------------------------
1 | # Faust Libraries
2 |
3 | This folder contains tools to analyse the libraries. For the time being, it computes only the dependencies between the libraries.
4 |
5 | ### Usage:
6 | ~~~~~~~~~~~~~
7 | make
8 | ~~~~~~~~~~~~~
9 | on output, you should find a pdf file containing a graph of the dependencies.
10 |
11 | or
12 | ~~~~~~~~~~~~~
13 | make help
14 | ~~~~~~~~~~~~~
15 |
16 | ### Note
17 |
18 | You must have `dot` installed to run `make`
19 |
--------------------------------------------------------------------------------
/routes.lib:
--------------------------------------------------------------------------------
1 | //#################################### routes.lib ########################################
2 | // A library to handle signal routing in Faust. Its official prefix is `ro`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 | /************************************************************************
9 | ************************************************************************
10 | FAUST library file
11 | Copyright (C) 2003-2019 GRAME, Centre National de Creation Musicale
12 | ----------------------------------------------------------------------
13 | This program is free software; you can redistribute it and/or modify
14 | it under the terms of the GNU Lesser General Public License as
15 | published by the Free Software Foundation; either version 2.1 of the
16 | License, or (at your option) any later version.
17 |
18 | This program is distributed in the hope that it will be useful,
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | GNU Lesser General Public License for more details.
22 |
23 | You should have received a copy of the GNU Lesser General Public
24 | License along with the GNU C Library; if not, write to the Free
25 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 | 02111-1307 USA.
27 |
28 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
29 | larger FAUST program which directly or indirectly imports this library
30 | file and still distribute the compiled code generated by the FAUST
31 | compiler, or a modified version of this compiled code, under your own
32 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
33 | grants you the right to freely choose the license for the resulting
34 | compiled code. In particular the resulting compiled code has no obligation
35 | to be LGPL or GPL. For example you are free to choose a commercial or
36 | closed source license or any other license if you decide so.
37 | ************************************************************************
38 | ************************************************************************/
39 |
40 | ba = library("basics.lib");
41 | si = library("signals.lib");
42 | sp = library("spats.lib");
43 |
44 | declare name "Faust Signal Routing Library";
45 | declare version "1.2.0";
46 |
47 | //=============================Functions Reference========================================
48 | //========================================================================================
49 |
50 | //--------------------------------`(ro.)cross`-----------------------------------
51 | // Cross N signals: `(x1,x2,..,xn) -> (xn,..,x2,x1)`.
52 | // `cross` is a standard Faust function.
53 | //
54 | // #### Usage
55 | //
56 | // ```
57 | // cross(N)
58 | // _,_,_ : cross(3) : _,_,_
59 | // ```
60 | //
61 | // Where:
62 | //
63 | // * `N`: number of signals (int, as a constant numerical expression)
64 | //
65 | // #### Note
66 | //
67 | // Special case: `cross2`:
68 | //
69 | // ```
70 | // cross2 = _,cross(2),_;
71 | // ```
72 | //-----------------------------------------------------------------------------
73 | // cross n cables : (x1,x2,..,xn) -> (xn,..,x2,x1)
74 | cross(N) = route(N, N, par(i, N, (i+1, N-i)));
75 | cross2 = _,cross(2),_; // for compatibility with some old misceffects.lib functions
76 |
77 |
78 | //--------------`(ro.)crossnn`--------------
79 | // Cross two `bus(N)`s.
80 | //
81 | // #### Usage
82 | //
83 | // ```
84 | // (si.bus(2*N)) : crossnn(N) : (si.bus(2*N))
85 | // ```
86 | //
87 | // Where:
88 | //
89 | // * `N`: the number of signals in the `bus` (int, as a constant numerical expression)
90 | //--------------------------------------
91 | crossnn(N) = crossNM(N,N);
92 |
93 |
94 | //--------------`(ro.)crossn1`--------------
95 | // Cross `bus(N)` and `bus(1)`.
96 | //
97 | // #### Usage
98 | //
99 | // ```
100 | // (si.bus(N),_) : crossn1(N) : (_,si.bus(N))
101 | // ```
102 | //
103 | // Where:
104 | //
105 | // * `N`: the number of signals in the first `bus` (int, as a constant numerical expression)
106 | //--------------------------------------
107 | crossn1(N) = crossNM(N,1);
108 |
109 |
110 | //--------------`(ro.)cross1n`--------------
111 | // Cross `bus(1)` and `bus(N)`.
112 | //
113 | // #### Usage
114 | //
115 | // ```
116 | // (_,si.bus(N)) : crossn1(N) : (si.bus(N),_)
117 | // ```
118 | //
119 | // Where:
120 | //
121 | // * `N`: the number of signals in the second `bus` (int, as a constant numerical expression)
122 | //--------------------------------------
123 | cross1n(N) = crossNM(1,N);
124 |
125 |
126 | //--------------`(ro.)crossNM`--------------
127 | // Cross `bus(N)` and `bus(M)`.
128 | //
129 | // #### Usage
130 | //
131 | // ```
132 | // (si.bus(N),si.bus(M)) : crossNM(N,M) : (si.bus(M),si.bus(N))
133 | // ```
134 | //
135 | // Where:
136 | //
137 | // * `N`: the number of signals in the first `bus` (int, as a constant numerical expression)
138 | // * `M`: the number of signals in the second `bus` (int, as a constant numerical expression)
139 | //--------------------------------------
140 | crossNM(N,M) = route(N+M, N+M, par(i, N+M, i+1, ((i+M)%(N+M))+1));
141 |
142 |
143 | //--------------------------`(ro.)interleave`------------------------------
144 | // Interleave R x C cables from column order to row order.
145 | // input : x(0), x(1), x(2) ..., x(row*col-1)
146 | // output: x(0+0*row), x(0+1*row), x(0+2*row), ..., x(1+0*row), x(1+1*row), x(1+2*row), ...
147 | //
148 | // #### Usage
149 | //
150 | // ```
151 | // si.bus(R*C) : interleave(R,C) : si.bus(R*C)
152 | // ```
153 | //
154 | // Where:
155 | //
156 | // * `R`: the number of row (int, as a constant numerical expression)
157 | // * `C`: the number of column (int, as a constant numerical expression)
158 | //-----------------------------------------------------------------------------
159 | interleave(1,2) = _,_;
160 | interleave(R,C) = route(R*C, R*C, par(i, R*C, (i+1, (i%R)*C + int(i/R) + 1)));
161 |
162 | //-------------------------------`(ro.)butterfly`--------------------------------
163 | // Addition (first half) then substraction (second half) of interleaved signals.
164 | //
165 | // #### Usage
166 | //
167 | // ```
168 | // si.bus(N) : butterfly(N) : si.bus(N)
169 | // ```
170 | //
171 | // Where:
172 | //
173 | // * `N`: size of the butterfly (N is int, even and as a constant numerical expression)
174 | //-----------------------------------------------------------------------------
175 | butterfly(2) = si.bus(2) <: +,-;
176 | butterfly(N) = si.bus(N) <: interleave(N/2,2), interleave(N/2,2) : par(i, N/2, +), par(i, N/2, -);
177 |
178 |
179 | //------------------------------`(ro.)hadamard`----------------------------------
180 | // Hadamard matrix function of size `N = 2^k`.
181 | //
182 | // #### Usage
183 | //
184 | // ```
185 | // si.bus(N) : hadamard(N) : si.bus(N)
186 | // ```
187 | //
188 | // Where:
189 | //
190 | // * `N`: `2^k`, size of the matrix (int, as a constant numerical expression)
191 | //
192 | //-----------------------------------------------------------------------------
193 | declare hadamard author "Remy Muller, revised by Romain Michon";
194 | hadamard(2) = butterfly(2);
195 | hadamard(N) = butterfly(N) : (hadamard(N/2), hadamard(N/2));
196 |
197 |
198 | //---------------`(ro.)recursivize`-------------
199 | // Create a recursion from two arbitrary processors `p` and `q`.
200 | //
201 | // #### Usage
202 | //
203 | // ```
204 | // _,_ : recursivize(p,q) : _,_
205 | //
206 | // ```
207 | //
208 | // Where:
209 | //
210 | // * `p`: the forward arbitrary processor
211 | // * `q`: the feedback arbitrary processor
212 | //----------------------------------------
213 | recursivize(p,q) = (_,_,_,_ :> sp.stereoize(p)) ~ sp.stereoize(q);
214 |
215 |
216 | //--------------------`(ro.)bubbleSort`-----------------------------------------
217 | //
218 | // Sort a set of N parallel signals in ascending order on-the-fly through
219 | // the Bubble Sort algorithm.
220 | //
221 | // Mechanism: having a set of N parallel signals indexed from 0 to N - 1,
222 | // compare the first pair of signals and swap them if sig[0] > sig[1];
223 | // repeat the pair comparison for the signals sig[1] and sig[2], then again
224 | // recursively until reaching the signals sig[N - 2] and sig[N - 1]; by the end,
225 | // the largest element in the set will be placed last; repeat the process for
226 | // the remaining N - 1 signals until there is a single pair left.
227 | //
228 | // Note that this implementation will always perform the worst-case
229 | // computation, O(n^2).
230 | //
231 | // Even though the Bubble Sort algorithm is one of the least efficient ones,
232 | // it is a useful example of how automatic sorting can be implemented at the
233 | // signal level.
234 | //
235 | // #### Usage
236 | //
237 | // ```
238 | // si.bus(N) : bubbleSort(N) : si.bus(N)
239 | //
240 | // ```
241 | //
242 | // Where:
243 | //
244 | // * `N`: the number of signals to be sorted (must be an int >= 0, as a constant numerical expression)
245 | //
246 | // #### Reference
247 | //
248 | //------------------------------------------------------------------------------
249 | declare bubbleSort author "Dario Sanfilippo";
250 | declare bubbleSort copyright "Copyright (C) 2021 Dario Sanfilippo
251 | ";
252 | declare bubbleSort license "MIT License";
253 | bubbleSort(0) = 0 : !;
254 | bubbleSort(1) = _;
255 | bubbleSort(N) = seq(i, N - 1, pairSortN(N - i), bus(i))
256 | with {
257 | bus(0) = 0 : !;
258 | bus(N) = si.bus(N);
259 | pairSort = bus(2) <: select2(>), select2(<);
260 | pairSortN(N) = seq(i, N - 1, bus(i), pairSort, bus(N - i - 2));
261 | };
262 |
--------------------------------------------------------------------------------
/sf.lib:
--------------------------------------------------------------------------------
1 | /*
2 | sf.lib - aliases all prefixes to sf = all.lib, so that both old and new prefixes can be mixed.
3 |
4 | USAGE:
5 |
6 | import("sf.lib"); // use either standard prefixes or the one prefix "sf"
7 |
8 | The Faust team is committed to unique names for standard Faust
9 | functions, allowing them to all be in the same namespace.
10 | Therefore, only two namespaces are needed: (1) the highest-level
11 | scope (no prefix), and (2) the Standard Faust scope, using prefix 'sf'.
12 | */
13 |
14 | sf = library("all.lib"); // "Standard Faust" prefix
15 |
16 | //--- use old library prefixes using old libraries ---
17 | /*
18 | ml = library("old/music.lib");
19 | fl = library("old/filter.lib");
20 | ol = library("old/oscillator.lib");
21 | el = library("old/effect.lib");
22 | */
23 | //--- use old library prefixes using new libraries ---
24 | ol = sf;
25 | fl = sf;
26 | ml = sf;
27 | el = sf;
28 | //--- new library prefixes ---
29 | an = sf;
30 | ba = sf;
31 | co = sf;
32 | de = sf;
33 | dm = sf;
34 | dx = sf;
35 | ef = sf;
36 | en = sf;
37 | fd = sf;
38 | fi = sf;
39 | ho = sf;
40 | ma = sf;
41 | os = sf;
42 | no = sf;
43 | pf = sf;
44 | pm = sf;
45 | re = sf;
46 | ro = sf;
47 | sp = sf;
48 | si = sf;
49 | so = sf;
50 | sy = sf;
51 | ve = sf;
52 | wa = sf;
53 | //-----
54 |
--------------------------------------------------------------------------------
/soundfiles.lib:
--------------------------------------------------------------------------------
1 | //#################################### soundfiles.lib ########################################
2 | // A library to handle soundfiles in Faust. Its official prefix is `so`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 | /************************************************************************
9 | ************************************************************************
10 | FAUST library file
11 | Copyright (C) 2018-2020 GRAME, Centre National de Creation Musicale
12 | ----------------------------------------------------------------------
13 | This program is free software; you can redistribute it and/or modify
14 | it under the terms of the GNU Lesser General Public License as
15 | published by the Free Software Foundation; either version 2.1 of the
16 | License, or (at your option) any later version.
17 |
18 | This program is distributed in the hope that it will be useful,
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | GNU Lesser General Public License for more details.
22 |
23 | You should have received a copy of the GNU Lesser General Public
24 | License along with the GNU C Library; if not, write to the Free
25 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 | 02111-1307 USA.
27 |
28 | EXCEPTION TO THE LGPL LICENSE : As a special exception, you may create a
29 | larger FAUST program which directly or indirectly imports this library
30 | file and still distribute the compiled code generated by the FAUST
31 | compiler, or a modified version of this compiled code, under your own
32 | copyright and license. This EXCEPTION TO THE LGPL LICENSE explicitly
33 | grants you the right to freely choose the license for the resulting
34 | compiled code. In particular the resulting compiled code has no obligation
35 | to be LGPL or GPL. For example you are free to choose a commercial or
36 | closed source license or any other license if you decide so.
37 | ************************************************************************
38 | ************************************************************************/
39 |
40 | ba = library("basics.lib");
41 | ma = library("maths.lib");
42 | si = library("signals.lib");
43 | ro = library("routes.lib");
44 | it = library("interpolators.lib");
45 |
46 | declare name "Faust Soundfile Library";
47 | declare version "1.7.0";
48 |
49 | //=======================================================================
50 | // Utility functions added in a 'super' environment (to test the idea...)
51 | //=======================================================================
52 |
53 | super = environment {
54 |
55 | length(sf, part) = (part, 0) : sf : (_,si.block(outputs(sf)-1));
56 | srate(sf, part) = (part, 0) : sf : (!,_,si.block(outputs(sf)-2)) : float;
57 | outs(sf, level) = sf : si.block(2), bus(outputs(sf)-2) with { bus(n) = par(i,n,*(level)); };
58 |
59 | // Plays a soundfile
60 | // 'reader' in a function of type \(sf,part).(body) whih produces the (possibly fractional) read index
61 | player(sf, part, reader, level) = (part, it.int_part(reader(sf, part))) : outs(sf, level);
62 |
63 | // Plays a soundfile with configurable interpolation
64 | player_interp(sf, part, reader, level, selector) = it.interpolator_select(gen, idv, selector)
65 | with {
66 | // Adapts the (sf, part, reader) parameters as 'idv' and 'gen' types for the generic interpolator
67 | idv = reader(sf, part);
68 | gen(idx) = (part, idx) : outs(sf, level);
69 | };
70 |
71 | // Plays a soundfile with configurable interpolation and a reference frequence 'ref'
72 | play_interp(sf, part, ref, freq, level, gate, selector) = player_interp(sf, part, reader, level, selector)
73 | with {
74 | reader(sf, part) = it.raise(gate, step, length(sf, part)) with { step = freq/ref*srate(sf, part)/ma.SR; };
75 | };
76 |
77 | // Generic version
78 | loop_speed_level(sf, part, speed, level) = player(sf, part, reader, level)
79 | with {
80 | // A 'reader' which loops the sound with 'speed' and 'level' control
81 | reader(sf, part) = it.raise_modulo(1, step, length(sf, part)) with { step = speed*srate(sf, part)/ma.SR; };
82 | };
83 |
84 | // Defines 'loop_speed' as a specialized version of loop_speed_level with level = 1
85 | loop_speed(sf, part, speed) = loop_speed_level(sf, part, speed, 1);
86 |
87 | // Defines 'loop_speed' as a specialized version of loop_speed_level with speed = 1 and level = 1
88 | loop(sf, part) = loop_speed_level(sf, part, 1, 1);
89 |
90 |
91 | }; // End of environment
92 |
93 | //=============================Functions Reference========================================
94 | //========================================================================================
95 |
96 | //--------------------------------`(so.)loop`-----------------------------------
97 | // Play a soundfile in a loop taking into account its sampling rate.
98 | // `loop` is a standard Faust function.
99 | //
100 | // #### Usage
101 | //
102 | // ```
103 | // loop(sf, part) : si.bus(outputs(sf))
104 | // ```
105 | //
106 | // Where:
107 | //
108 | // * `sf`: the soundfile
109 | // * `part`: the part in the soundfile list of sounds
110 | //
111 | //-----------------------------------------------------------------------------
112 |
113 | loop(sf, part) = super.loop(sf, part);
114 |
115 | //--------------------------------`(so.)loop_speed`-----------------------------------
116 | // Play a soundfile in a loop taking into account its sampling rate, with speed control.
117 | // `loop_speed` is a standard Faust function.
118 | //
119 | // #### Usage
120 | //
121 | // ```
122 | // loop_speed(sf, part, speed) : si.bus(outputs(sf))
123 | // ```
124 | //
125 | // Where:
126 | //
127 | // * `sf`: the soundfile
128 | // * `part`: the part in the soundfile list of sounds
129 | // * `speed`: the speed between 0 and n
130 | //
131 | //-----------------------------------------------------------------------------
132 |
133 | loop_speed(sf, part, speed) = super.loop_speed(sf, part, speed);
134 |
135 | //--------------------------------`(so.)loop_speed_level`-----------------------------------
136 | // Play a soundfile in a loop taking into account its sampling rate, with speed and level controls.
137 | // `loop_speed_level` is a standard Faust function.
138 | //
139 | // #### Usage
140 | //
141 | // ```
142 | // loop_speed_level(sf, part, speed, level) : si.bus(outputs(sf))
143 | // ```
144 | //
145 | // Where:
146 | //
147 | // * `sf`: the soundfile
148 | // * `part`: the part in the soundfile list of sounds
149 | // * `speed`: the speed between 0 and n
150 | // * `level`: the volume between 0 and n
151 | //
152 | //-----------------------------------------------------------------------------
153 |
154 | loop_speed_level(sf, part, speed, level) = super.loop_speed_level(sf, part, speed, level);
155 |
156 | //====================================================
157 | // Environment to handle a given sound in a soundfile
158 | //====================================================
159 |
160 | sound(sf, part) = environment {
161 |
162 | // Looping the sound
163 | loop = super.loop(sf, part);
164 | loop_speed(speed) = super.loop_speed(sf, part, speed);
165 | loop_speed_level(speed, level) = super.loop_speed_level(sf, part, speed, level);
166 |
167 | // Play once
168 | play(level, gate) = super.player(sf, part, reader, level)
169 | with {
170 | reader(sf, part) = it.raise(gate, super.srate(sf, part)/ma.SR, super.length(sf, part));
171 | };
172 |
173 | // Play once in reverse
174 | play_rev(level, gate) = super.player(sf, part, reader, level)
175 | with {
176 | reader(sf, part) = it.decrease(gate, super.srate(sf, part)/ma.SR, super.length(sf, part));
177 | };
178 |
179 | // Play sound once with configurable interpolation and freq control (using a 'ref' value)
180 | play_interp(ref, freq, level, gate, selector) = super.play_interp(sf, part, ref, freq, level, gate, selector);
181 |
182 | // Play sound once and alternate between normal play and reverse play
183 | //play_alt(level, gate, ctrl) = super.player(sf, part, alt2(ramp1, ramp2, ctrl), level)
184 | play_alt(level, gate, ctrl) = super.player(sf, part, altN(lramp, ctrl), level)
185 | with {
186 | // High-order function which alternate between 2 'readers' depending of the 'ctrl' signal
187 | alt2(r1, r2, ctrl) = \(sf, part).(ba.selectmulti(ma.SR/100, lr, ctrl) with { lr = r1(sf, part), r2(sf, part); });
188 |
189 | altN(lrs, ctrl) = \(sf, part).(ba.selectmulti(ma.SR/100, mapper(lrs), ctrl)
190 | with {
191 | mapper((xs, xxs)) = xs(sf, part), mapper(xxs);
192 | mapper(xs) = xs(sf, part);
193 | });
194 |
195 | step = super.srate(sf, part)/ma.SR;
196 |
197 | ramp1(sf, part) = it.raise(gate, step, super.length(sf, part));
198 | ramp2(sf, part) = it.decrease(gate, step, super.length(sf, part));
199 |
200 | lramp = (ramp1, ramp2, ramp2, ramp2, ramp1);
201 | };
202 |
203 | }; // End of environment
204 |
205 | /*
206 | // Using the `sound` environment allocated with a given `sf` and `part`
207 |
208 | import("soundfiles.lib");
209 |
210 | s1 = soundfile("[url:{'piano-C5.ogg';'piano-G5.ogg';'piano-C6.ogg';'piano-G6.ogg'}]",2);
211 | sample1 = so.sound(s1, 0);
212 | sample2 = so.sound(s1, 1);
213 | sample3 = so.sound(s1, 2);
214 |
215 | // Plays the sound in various ways
216 | sample1.loop;
217 | sample1.loop_speed(0.5);
218 | sample1.loop_speed_level(0.5, 0.5);
219 |
220 | sample2.play(0.5, button("gate"));
221 | sample2.play_rev(0.5, button("gate"));
222 | sample2.play_alt(0.5, button("gate"), checkbox("alt"));
223 |
224 | sample3.play_interp(440.0, 600.0, 0.5, button("gate"), it.linear);
225 | sample3.play_interp(440.0, 800.0, en.ar(0.1, 0.8, button("gate")), button("gate"), it.cubic);
226 |
227 | play = button("gate");
228 | sample3.play_interp(440.0,
229 | hslider("freq", 200, 200, 880, 0.01),
230 | hslider("gain", 0.5, 0, 1, 0.01)*en.ar(0.1, 0.8, play),
231 | play,
232 | nentry("interp", 0, 0, 3, 1));
233 |
234 | */
235 |
--------------------------------------------------------------------------------
/stdfaust.lib:
--------------------------------------------------------------------------------
1 | //################################ stdfaust.lib ##########################################
2 | // The purpose of this library is to give access to all the Faust standard libraries
3 | // through a series of environments.
4 | //########################################################################################
5 |
6 | aa = library("aanl.lib");
7 | sf = library("all.lib");
8 | an = library("analyzers.lib");
9 | ba = library("basics.lib");
10 | co = library("compressors.lib");
11 | de = library("delays.lib");
12 | dm = library("demos.lib");
13 | dx = library("dx7.lib");
14 | en = library("envelopes.lib");
15 | fd = library("fds.lib");
16 | fi = library("filters.lib");
17 | ho = library("hoa.lib");
18 | it = library("interpolators.lib");
19 | la = library("linearalgebra.lib");
20 | ma = library("maths.lib");
21 | mi = library("mi.lib");
22 | ef = library("misceffects.lib");
23 | os = library("oscillators.lib");
24 | no = library("noises.lib");
25 | pf = library("phaflangers.lib");
26 | pl = library("platform.lib");
27 | pm = library("physmodels.lib");
28 | qu = library("quantizers.lib");
29 | rm = library("reducemaps.lib");
30 | re = library("reverbs.lib");
31 | ro = library("routes.lib");
32 | sp = library("spats.lib");
33 | si = library("signals.lib");
34 | so = library("soundfiles.lib");
35 | sy = library("synths.lib");
36 | ve = library("vaeffects.lib");
37 | vl = library("version.lib");
38 | wa = library("webaudio.lib");
39 | wd = library("wdmodels.lib");
40 |
--------------------------------------------------------------------------------
/version.lib:
--------------------------------------------------------------------------------
1 | //################################ version.lib ##########################################
2 | // Semantic versioning for the Faust libraries. Its official prefix is `vl`.
3 | //
4 | // #### References
5 | // *
6 | //########################################################################################
7 |
8 | //---------------------------`(vl.)version`---------------------------
9 | // Return the version number of the Faust standard libraries as a MAJOR, MINOR, PATCH versioning triplet.
10 | //
11 | // #### Usage
12 | //
13 | // ```
14 | // version : _,_,_
15 | // ```
16 | //
17 | //------------------------------------------------------------
18 | version = 2, // MAJOR version when we make incompatible API changes,
19 | 56, // MINOR version when we add functionality in a backwards compatible manner,
20 | 0; // PATCH version when we make backwards compatible bug fixes or code improvements.
21 |
22 |
23 |
--------------------------------------------------------------------------------