FAUST (programming language): Difference between revisions

Content deleted Content added
Rmichon (talk | contribs)
No edit summary
Add category
 
(43 intermediate revisions by 32 users not shown)
Line 1:
{{Short description|Audio programming language}}
{{Colloquial|date=September 2012}}
{{redirect|FAUST|other uses|Faust (disambiguation){{!}}Faust}}
{{More footnotes needed|date=March 2015}}
{{Infobox software
| name = FAUST
| developer = GRAME, Centre National de Création Musicale
| author = Yann Orlarey, Dominique Fober, Stéphane Letz
| released = {{releasestart date|2002}}
| latest release version = 02.960.673<ref>[https://github.com/grame-cncm/faust/releases Releases · grame-cncm/faust · GitHub]</ref>
| latest release date = {{releasestart date|20142023|0506|1914}}
| operating system = [[Linux]], [[Mac OS X]], [[Microsoft Windows|Windows]], [[Unix]]
| genre = Functional programming language for audio signal processing
| repo = {{URL|https://github.com/grame-cncm/faust/}}
| programming language = [[C++]]
| programming language = [[C++]]
| license = [[GNU General Public License|GPL]]
| license = [[GNU General Public License|GPL]]
| website = http://faust.grame.fr/
| website = {{URL|faust.grame.fr}}
}}
{{Portal|Free and open-source software}}
'''FAUST''' (Functional AUdio STream) is a [[___domain-specific language|___domain-specific]] [[purely functional programming|purely functional]] [[programming language]] for implementing [[signal processing]] [[algorithms]] in the form of [[Library (computing)|libraries]], [[audio plug-ins]], or standalone applications. A FAUST program denotes a signal processor: a mathematical function that is applied to some input signal and then fed out.
 
==Overview==
'''FAUST''' (Functional AUdio STream) is a [[programming language]] that provides a purely functional approach to [[signal processing]] while offering a high level of performance. FAUST aims at being complementary to existing audio languages by offering a viable and efficient alternative to [[C (programming language)|C]]/[[C++]] to develop signal processing [[library (computing)|libraries]], [[audio plug-in]]s or standalone applications.
The FAUST [[programming model]] combines a [[functional programming]] approach with a [[block diagram]] syntax:
The language is based on a simple and well defined formal semantics. A FAUST program denotes a signal processor, a mathematical function that transforms input signals into output signals.
* The functional programming approach provides a natural framework for [[signal processing]]. Digital signals are modeled as [[Sequence|discrete functions]] of time, signal processors as [[Higher-order function|second order functions]] that operate on them, and FAUST's block diagram ''composition operators'', used to combine signal processors together, as third order functions, etc.
 
* Block diagrams, even if purely textual as in FAUST, promote a modular approach to signal processing that complies with sound engineers' and audio developers' habits.
== Overview ==
A FAUST program doesn't describe a sound or a group of sounds, but a [[Digital signal processing|signal processor]]. The program source is organized as a set of ''definitions'' with at least the definition of the keyword <code>process</code> (the equivalent of <code>main</code> in C):
The FAUST programming model combines a ''functional programming approach'' with a ''block-diagram syntax'':
<syntaxhighlight lang=haskell>
* The functional programming approach provides a natural framework for signal processing. Digital signals are modeled as discrete functions of time, signal processors as second order functions that operate on them, and FAUST’s block-diagram ''composition operators'', used to combine signal processors together, as third order functions, etc. .
* Block-diagrams, even if purely textual like in FAUST, promote a modular approach of signal processing that suits very well the sound engineers’ and audio developers’ habits, while providing a powerful and expressive syntax.
A FAUST program doesn’t describe a sound or a group of sounds, but a ''signal processor'', something that transforms input signals and produces output signals. The program source is organized as a set of ''definitions'' with at least the definition of the keyword process (the equivalent of main in C):
<source lang=cpp>
process = ...;
</syntaxhighlight>
</source>
 
The FAUST [[compiler]] translates FAUST programscode into equivalenta [[C++]] programs[[Object-oriented takingprogramming|object]], carewhich ofmay generatingthen the most efficient code. The result can generally competeinterface with, andother sometimes even outperform, [[C++]] code writtento produce bya seasonedfull programmersprogram.
 
The generated code works at the sample level. It is therefore suited to implement low-level [[Digital signal processing|DSP]] functions like [[Infinite impulse response|recursive filters]]. Moreover theThe code canmay also be easily[[Embedded software|embedded]]. It is self-contained and does not depend on any DSP library or [[runtime system]]. It has a very deterministic behaviourbehavior and a constant memory footprintsize.
 
The semanticsemantics of FAUST is driven to be simple and well -defined. This is not just of academic interest. It allows the FAUST compiler to be ''semantically driven''. Instead of compiling a program literally, it compiles the mathematical function it denotes. This feature is useful for example tomay promote componentscomponent reuse while preserving optimal performance. Moreover, having access to the exact semantics of a FAUST program can simplify preservation issues.
 
FAUST is a textual language but nevertheless block- diagram oriented. It actually combines two approaches: [[functional programming]] and algebraic [[block-diagrams. Thediagram]]s, keywhich ideaare isconstructed to view block-diagram construction asvia [[function composition]]. For that, FAUST relies on a ''block- diagram algebra'' of five composition operations.
 
==SimpleExample examplescode==
Let’sFAUST startprograms withdefine somea really<code>process</code> simplefunction one-linethat examplesoperates ofon FAUSTincoming programdata. HereThis is aanalogous to the <code>main</code> function in most programming languages. The following is firstan example that produces silence:
<sourcesyntaxhighlight lang=cpp"haskell">
process = 0;
</syntaxhighlight>
</source>
The second example is a little bit more sophisticated and copies the input signal to the output signal. It involves the <code>_ (underscore)</code> primitive that denotes the [[identity function]] onfor signals (that is a simple audio cable for a sound engineer):
<sourcesyntaxhighlight lang=cpp"haskell">
process = _;
</syntaxhighlight>
</source>
Another very simple example is the conversion ofsums a two-channel stereo signal into a one-channel mono signal using the <code>+</code> primitive that adds two signals together:
<sourcesyntaxhighlight lang=cpp"haskell">
process = +;
</syntaxhighlight>
</source>
[[File:Faust-simple-block-diagram.jpg|thumb|Block- diagrams generated by Faust from some simple programs]]
Most FAUST primitives are analogous to their C counterpart on numbers, but lifted to signals. For example, the FAUST primitive <code>sin</code> operates on a signal X by applying the [[C (programming language)|C]] function <code>sin</code> to each sample X([t) of X. In other words sin transforms an input signal X into an output signal Y such that Y (t) = sin(X(t))]. All C numerical functions have their counterpart in FAUST.
Some [[signal processing]] primitives are specific to FAUST. For example, the delay operator <code>@</code> takes two input signals: X (the signal to be delayed) and D (the delay to be applied), and produces an output signal Y such that Y (t) = X(t − D(t)).
 
==Block- diagram composition==
Contrary to [[Max (software)|Max-like]] [[visual programming languages]] where the user does manual connections, FAUST primitives are assembled in [[block diagramsdiagram]]s by using a set of high-level block diagram composition operations. You can think of these[[Function composition operators as a generalization of the mathematical function |composition]] operatoroperations.
 
[[File:Faust-simple-block-diagrams.jpg|thumb|upright=1.75|Simple examples of block- diagram composition]]
 
{| class="wikitable"
|+ The block- diagram ''composition operators'' used in FAUST
| f~g || Recursive composition (precedence 4)
|-
Line 69 ⟶ 71:
|}
 
Let’sUsing saythe thatsequential wecomposition wantoperator to connect<code>:</code> the output of <code>+</code> can be routed to the input of <code>abs in order</code> to compute the [[absolute value]] of the output signal. This connection can be done using the sequential composition operator ':' (colon):
<sourcesyntaxhighlight lang=cpp"haskell">
process = + : abs;
</syntaxhighlight>
</source>
Here is an example of parallel composition (a stereo cable) using the operator '<code>,'</code> (comma)operator that puts in parallelarranges its left and right expressions: in parallel. This is analogous to a stereo cable.
<sourcesyntaxhighlight lang=cpp"haskell">
process = _,_;
</syntaxhighlight>
</source>
These operators can be combined arbitrarily combined. ForThe examplefollowing tocode multiplymultiplies thean input signal bywith 0.5 one can write:
<sourcesyntaxhighlight lang=cpp"haskell">
process = _,0.5 : *;
</syntaxhighlight>
</source>
The above may be rewritten in [[currying|curried]] form:
Taking advantage of some syntactic sugar the above example can be rewritten (using what functional programmers know as curryfication):
<sourcesyntaxhighlight lang=cpp"haskell">
process = *(0.5);
</syntaxhighlight>
</source>
The recursive composition operator '<code>~'</code> can be used to create block- diagrams with cycles (that include an implicit one-sample delay). Here is thean example of an integrator that takes an input signal X and computes an output signal Y such that Y (t) = X(t) + Y(t−1):
<sourcesyntaxhighlight lang=cpphaskell>
process = + ~ _;
</syntaxhighlight>
</source>
 
==Generating full applications==
==Full applications generation==
Thanks toUsing specific ''architecture files'', a single FAUST program can be used to produce code for a variety of platforms and plug-in formats. These architecture files act as wrappers and describe the interactions with the host audio and GUI system. Currently{{As of|2021}}, more than 1030 architectures are supported and new ones canmay be easilyimplemented by addedanyone.
 
[[File:Faust-mixer-jackqt.jpg|thumb|Screenshot of mixer.dsp (available in the FAUST distribution) using the jack-qt architecture]]
Line 97 ⟶ 99:
{| class="wikitable"
|+ Some architecture files available for FAUST
! File
| alsa-gtk.cpp || ALSA application + GTK
! Architecture
|-
| alsa-qtgtk.cpp || ALSA application + QT4[[GTK]]
|-
| alsa-qt.cpp || ALSA application + [[Qt (software)|Qt]] 4
|-
| android.cpp || Android applications
Line 105 ⟶ 110:
| au.cpp || Audio Unit plug-in
|-
| ca-qt.cpp || CoreAudio application + QT4Qt 4
|-
| ios-coreaudio.cpp || iPhone and iPad applications
Line 111 ⟶ 116:
| jack-gtk.cpp || JACK application + GTK
|-
| jack-qt.cpp || JACK application + QT4Qt 4
|-
| ladspa.cpp || LADSPA plug-in
Line 117 ⟶ 122:
| max-msp.cpp || Max MSP plug-in
|-
| pd.cpp || PuredataPure Data plug-in
|-
| q.cpp || Q language plug-in
|-
| supercollider.cpp || SupercolliderSuperCollider plug-in
|-
| vst.cpp || VST plug-in
Line 130 ⟶ 135:
|}
 
==Generating block diagrams==
==Block-diagram generation==
A useful option makes it possible to generatesgenerate the block diagram representation of the program as one or more SVG graphic files.
 
It is interesting to note the difference between the block diagram and the generated C++ code.
AsIt alreadyis useful to note the difference between the block diagram and the generated C++ code. As saidstated, the key idea here is not to compile the block diagram literally, but the mathematical function it denotes. Modern C/C++ compilers tooalso don’tdon't compile programs literally. But because of the complex semanticsemantics of C/C++ (due to side effects, pointer aliasing, etc.) they can’tcan't go very far in that direction. This is a distinctivedistinct advantage of a purely functional language: it allows compilers to do very advanced optimisations.
 
==Arrows-like semantics==
The Faust semantics is almost the same as that of [[Haskell (programming language)|Haskell's]] [[Arrow (computer science)|Arrows]] type class.
However, the Arrow type class is not bound to signal processors.
 
{| class="wikitable"
|+ Equivalences between FAUST and Arrow combinators
| <code>f~g</code> || {{code|2=haskell|1=loop ((\(a,b) -> (b,a)) ^>> f >>> id &&& (delay>>>g))}} where <code>delay</code> is not a method of the <code>Arrow</code> type class, but is specific to signal processing arrows
|-
| <code>f,g</code> || <code>f***g</code>
|-
| <code>f:g</code> || <code>f>>>g</code>
|-
| <code>f<:g</code> || <code>f>>^h>>>g</code> with appropriate function <code>h</code> (or <code>&&&</code> in special cases)
|-
| <code>f:>g</code> || <code>f>>^h>>>g</code> with appropriate function <code>h</code>
|}
 
The Arrow combinators are more restrictive than their FAUST counterparts, e.g., the nesting of parallel composition is preserved, and inputs of the operands of <code>&&&</code> must match exactly.
 
==References==
{{Reflist}}
{{Refbegin}}
* {{cite journal
| first1 = Romain
| last1 = Michon
Line 148 ⟶ 172:
| pages = 199–204
| year = 2011
}}
| ref = harv}}
* {{cite journal
 
*{{cite journal
| first1 = Dominique
| last1 = Fober
Line 162 ⟶ 185:
| pages = 213–216
| year = 2011
}}
| ref = harv}}
* {{cite journal
 
*{{cite journal
| first1 = Julius O. III
| last1 = Smith
Line 174 ⟶ 196:
| pages = 361–364
| year = 2011
}}
| ref = harv}}
* {{cite journal
 
|first1=Pierre
*{{cite journal
|last1=Jouvelot
|first1 = Pierre
|first2=Yann
|last1 = Jouvelot
|last2=Orlarey
|first2 = Yann
|title=Dependent Vector Types for Data Structuring in Multirate Faust
|last2 = Orlarey
|journal=Computer Languages, Systems & Structures
|title = Dependent Vector Types for Data Structuring in Multirate Faust
|url=http://faust.grame.fr/images/faust-doc/papers/faust-elsevier2011.pdf
|journal = Computer Languages, Systems and Structures - Elsevier
|year=2011
|url = http://faust.grame.fr/images/faust-doc/papers/faust-elsevier2011.pdf
|volume=37
|year = 2011
|issue=3
|ref = harv}}
|pages=113–131
 
|doi=10.1016/j.cl.2011.03.001
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
* {{Cite web
| first = Julius O.
Line 193 ⟶ 217:
| url = https://ccrma.stanford.edu/~jos/spf/aspf.pdf
| year = 2011
}}
| ref = harv }}
* {{cite journal
 
|first3=Dominique
*{{cite journal
|last3=Fober
| first3 = Dominique
|first1=Yann
| last3 = Fober
|last1=Orlarey
| first1 = Yann
|first2=Stéphane
| last1 = Orlarey
|last2=Letz
| first2 = Stéphane
|title=Automatic Parallelization of Audio Applications with Faust
| last2 = Letz
|journal=Proceedings of the Congrès Français d'Acoustique
| title = Automatic Parallelization of Audio Applications with Faust
|url=http://faust.grame.fr/images/faust-doc/papers/faust-CFA-2010.pdf
| journal = Proceedings of the Congrès Français d'Acoustique
|year=2010
| url = http://faust.grame.fr/images/faust-doc/papers/faust-CFA-2010.pdf
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| year = 2010
* {{cite journal
| ref = harv}}
 
*{{cite journal
| first3 = Dominique
| last3 = Fober
Line 219 ⟶ 241:
| url = http://lac.linuxaudio.org/2010/papers/17.pdf
| year = 2010
}}
| ref = harv}}
 
* {{cite journal
| first = Albert
Line 229 ⟶ 250:
| page = 117
| year = 2010
}}
| ref = harv}}
* {{cite journal
 
|first1=Jérôme
* {{cite journal
|last1=Barthélemy
| first1 = Jérôme
|first2=Alain
| last1 = Barthélemy
|last2=Bonardi
| first2 = Alain
|first3=Yann
| last2 = Bonardi
|last3=Orlarey
| first3 = Yann
|first4=Serge
| last3 = Orlarey
|last4=Lemouton
| first4 = Serge
|first5=Raffaele
| last4 = Lemouton
|last5=Ciavarella
| first5 = Raffaele
|first6=Karim
| last5 = Ciavarella
|last6=Barkati
| first6 = Karim
|title=First Steps Towards an Organology of Virtual Instruments in Computer Music
| last6 = Barkati
|journal=Proceedings of the 2010 International Computer Music Conference (ICMA-2010)
| title = First Steps Towards an Organology of Virtual Instruments in Computer Music
|url=http://faust.grame.fr/images/faust-doc/papers/astree-icmc2010.pdf
| journal = Proceedings of the 2010 International Computer Music Conference (ICMA-2010)
|pages=369–372
| url = http://faust.grame.fr/images/faust-doc/papers/astree-icmc2010.pdf
|year=2010
| pages = 369–372
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| year = 2010
| ref = harv}}
 
* {{cite journal
| first1 = Pierre
Line 257 ⟶ 276:
| last2 = Orlarey
| title = Depandant Vector Types for Multirate Faust
| journal = Proceedings of the 7th Sound anand Music Computing Conference (SMC-2010)
| url = http://smcnetwork.org/files/proceedings/2010/51.pdf
| pages = 345–352
| year = 2010
| access-date = 2011-10-11
| ref = harv}}
| archive-url = https://web.archive.org/web/20120407043121/http://smcnetwork.org/files/proceedings/2010/51.pdf
 
| archive-date = 2012-04-07
* {{cite journal
| first3url-status = Dominiquedead
}}
| last3 = Fober
* {{cite journal
| first1 = Yann
|first3=Dominique
| last1 = Orlarey
|last3=Fober
| first2 = Stéphane
|first1=Yann
| last2 = Letz
|last1=Orlarey
| title = Adding Automatic Parallelization to Faust
|first2=Stéphane
| journal = Proceedings of the Linux Audio Conference (LAC-2009)
|last2=Letz
| url = http://faust.grame.fr/test/images/faust-doc/papers/faustLAC09.pdf
|title=Adding Automatic Parallelization to Faust
| year = 2009
|journal=Proceedings of the Linux Audio Conference (LAC-2009)
| ref = harv}}
|url=http://faust.grame.fr/test/images/faust-doc/papers/faustLAC09.pdf
 
|year=2009
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
* {{cite book
| first1 = Pierre
Line 285 ⟶ 306:
| url = http://faust.grame.fr/images/faust-doc/papers/multirate-faust.pdf
| year = 2009
}}{{Dead link|date=December 2019 |bot=InternetArchiveBot |fix-attempted=yes }}
| ref = harv}}
 
* {{cite journal
| first2 = Dominique
Line 297 ⟶ 317:
| url = http://smc2009.smcnetwork.org/programme/pdfs/232.pdf
| year = 2009
| archive-date = 2012-04-25
| ref = harv}}
| access-date = 2011-10-11
 
| archive-url = https://web.archive.org/web/20120425061241/http://smc2009.smcnetwork.org/programme/pdfs/232.pdf
| url-status = dead
}}
* {{cite book
| first2 = Dominique
Line 312 ⟶ 335:
| isbn = 978-2-7521-0054-2
| year = 2009
}}{{Dead link|date=December 2019 |bot=InternetArchiveBot |fix-attempted=yes }}
| ref = harv}}
* {{cite journal
 
|first3=Dominique
* {{cite journal
|last3=Fober
| first3 = Dominique
|first1=Yann
| last3 = Fober
|last1=Orlarey
| first1 = Yann
|first2=Stéphane
| last1 = Orlarey
|last2=Letz
| first2 = Stéphane
|title=Multicore Technologies in Jack and Faust
| last2 = Letz
|journal=Proceedings of the 2010 International Computer Music Conference (ICMC-2008)
| title = Multicore Technologies in Jack and Faust
|url=http://faust.grame.fr/images/faust-doc/papers/jack-faust-multicore.pdf
| journal = Proceedings of the 2010 International Computer Music Conference (ICMC-2008)
|year=2008
| url = http://faust.grame.fr/images/faust-doc/papers/jack-faust-multicore.pdf
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| year = 2008
| ref = harv}}
 
* {{cite journal
| first = Albert
Line 335 ⟶ 356:
| page = 24
| year = 2007
}}
| ref = harv }}
 
* {{Cite book
| first = Julius O.
| last = Smith III
| title = Introduction to Digital Filters: With Audio Applications
| chapter = Appendix K. Digital Filtering in Faust and PD
| publisher = W3K Publishing
| year = 2007
| isbn = 978-0-9745607-1-7
| chapter-url = httphttps://books.google.com/books?id=pC1iCQUAsHEC&pg=PA417
| pages = 417-417–?
}}
 
* {{cite journal
| first1 = Albert
Line 359 ⟶ 379:
| url = http://lac.zkm.de/2006/papers/lac2006_orlarey_et_al.pdf
| year = 2006
}}
| ref = harv}}
 
* {{cite journal
| first1 = Robert
Line 372 ⟶ 391:
| url = http://www.dafx.ca/proceedings/papers/p_287.pdf
| year = 2006
}}
| ref = harv}}
 
* {{Cite book
| first1 = Yann
Line 386 ⟶ 404:
| publisher = Computer Music Association
| url = http://quod.lib.umich.edu/cgi/t/text/text-idx?c=icmc;idno=bbp2372.2005.*
| chapterurlchapter-url = http://quod.lib.umich.edu/i/icmc/bbp2372.2005.054?view=image
| year = 2005
| page = 286
}}
 
* {{cite book
| first2 = Dominique
Line 402 ⟶ 419:
| url = http://faust.grame.fr/images/faust-doc/papers/faust-soft-computing.pdf
| year = 2004
}}{{Dead link|date=December 2019 |bot=InternetArchiveBot |fix-attempted=yes }}
| ref = harv}}
* {{cite journal
 
|first1=Nicolas
* {{cite journal
|last1=Scaringella
| first1 = Nicolas
|first3=Dominique
| last1 = Scaringella
|last3=Fober
| first3 = Dominique
|first2=Yann
| last3 = Fober
|last2=Orlarey
| first2 = Yann
|title=Automatic Vectorization in Faust
| last2 = Orlarey
|journal=Journée de l'Informatique Musicale (JIM-2003)
| title = Automatic Vectorization in Faust
|url=http://faust.grame.fr/images/faust-doc/papers/JIM2003vect.pdf
| journal = Journée de l'Informatique Musicale (JIM-2003)
|year=2003
| url = http://faust.grame.fr/images/faust-doc/papers/JIM2003vect.pdf
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| year = 2003
* {{cite journal
| ref = harv}}
|first3=Stéphane
 
|last3=Letz
* {{cite journal
|first2=Dominique
| first3 = Stéphane
|last2=Fober
| last3 = Letz
|first1=Yann
| first2 = Dominique
|last1=Orlarey
| last2 = Fober
|title=An Algebraic Approach to Block Diagram Constructions
| first1 = Yann
|journal=Journée de l'Informatique Musicale (JIM-2002)
| last1 = Orlarey
|url=http://faust.grame.fr/images/faust-doc/papers/faust-jim2002.pdf
| title = An Algebraic Approach to Block Diagram Constructions
|year=2002
| journal = Journée de l'Informatique Musicale (JIM-2002)
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| url = http://faust.grame.fr/images/faust-doc/papers/faust-jim2002.pdf
* {{cite journal
| year = 2002
|first3=Stéphane
| ref = harv}}
|last3=Letz
 
|first2=Dominique
* {{cite journal
|last2=Fober
| first3 = Stéphane
|first1=Yann
| last3 = Letz
|last1=Orlarey
| first2 = Dominique
|title=An Algebra for Block Diagram Languages
| last2 = Fober
|journal=Proceedings of International Computer Music Conference (ICMA-2002)
| first1 = Yann
|url=http://faust.grame.fr/images/faust-doc/papers/faust-icmc2002.pdf
| last1 = Orlarey
|year=2002
| title = An Algebra for Block Diagram Languages
}}{{dead link|date=December 2016 |bot=InternetArchiveBot |fix-attempted=yes }}
| journal = Proceedings of International Computer Music Conference (ICMA-2002)
| url = http://faust.grame.fr/images/faust-doc/papers/faust-icmc2002.pdf
| year = 2002
| ref = harv}}
{{Refend}}
 
==External links==
{{Commons category|FAUST (programming language)}}
* [http://faust.grame.fr/ FAUST home page]: Online compiler, support, documentation, news, etc.
* {{Official website|faust.grame.fr}}, online compiler, support, documentation, news, etc.
* [http://faudiostream.sourceforge.net/ FAUST on SourceForge]: Faust repository and mailing lists
* {{GitHub|grame-cncm/faust}}
 
[[Category:Audio programming languages]]
[[Category:Programming languages created in 2002]]