FAUST (programmeringsspråk)

FAUST
Originalförfattare Yann Orlarey, Dominique Fober, Stéphane Letz
Utvecklare GRAME, Centre National de Création Musicale
Initial release 2002 ( 2002 )
Stabil frisättning
2.54.9 / 18 december 2022 ( 2022-12-18 )
Skrivet i C++
Operativ system Linux , OS X , Windows , Unix
Typ Funktionellt programmeringsspråk för ljudsignalbehandling
Licens GPL
Hemsida faust .grame .fr

FAUST (Functional AUdio STream ) är ett domänspecifikt rent funktionellt programmeringsspråk för att implementera signalbehandlingsalgoritmer i form av bibliotek , plugin-program för ljud eller fristående applikationer. Ett FAUST-program betecknar en signalprocessor: en matematisk funktion som appliceras på någon insignal och sedan matas ut.

Översikt

FAUST- programmeringsmodellen kombinerar en funktionell programmeringsmetod med en blockdiagramsyntax :

  • Den funktionella programmeringsmetoden ger ett naturligt ramverk för signalbehandling . Digitala signaler modelleras som diskreta funktioner av tid, signalprocessorer som andra ordningens funktioner som verkar på dem, och FAUST:s blockdiagramkompositionsoperatorer, som används för att kombinera signalprocessorer tillsammans, som tredje ordningens funktioner, etc.
  • Blockdiagram, även om de är rent textmässiga som i FAUST, främjar ett modulärt tillvägagångssätt för signalbehandling som överensstämmer med ljudteknikers och ljudutvecklares vanor.

Ett FAUST-program beskriver inte ett ljud eller en grupp av ljud, utan en signalprocessor . Programkällan är organiserad som en uppsättning definitioner med åtminstone definitionen av nyckelordsprocessen ( motsvarigheten till main i C):

   process  =  ...  ; 

FAUST- kompilatorn översätter FAUST-kod till ett C++- objekt , som sedan kan samverka med annan C++-kod för att skapa ett fullständigt program.

Den genererade koden fungerar på exempelnivå. Den är därför lämpad för att implementera lågnivå DSP- funktioner som rekursiva filter . Koden kan också vara inbäddad . Det är fristående och är inte beroende av något DSP-bibliotek eller körtidssystem . Den har ett mycket deterministiskt beteende och en konstant minnesstorlek.

FAUSTs semantik drivs på att vara enkel och väldefinierad. Det gör att FAUST - kompilatorn kan drivas semantiskt . Istället för att kompilera ett program bokstavligt, kompilerar det den matematiska funktion det betecknar. Detta kan främja återanvändning av komponenter. Att ha tillgång till den exakta semantiken för ett FAUST-program kan dessutom förenkla bevarandeproblem.

FAUST är ett textspråk men blockschemaorienterat. Den kombinerar två tillvägagångssätt: funktionell programmering och algebraiska blockscheman , som är konstruerade via funktionssammansättning . För det förlitar sig FAUST på en blockdiagramalgebra med fem sammansättningsoperationer.

Exempelkod

FAUST-program definierar en processfunktion som arbetar på inkommande data. Detta är analogt med huvudfunktionen i de flesta programmeringsspråk. Följande är ett exempel som skapar tystnad:

  0 process  =  ; 

Det andra exemplet kopierar insignalen till utgången. Det involverar _ som anger identitetsfunktionen för signaler:

   process  =  _  ; 

Ett annat exempel summerar en stereosignal till en monosignal med hjälp av primitiv + :

   process  =  +  ; 
Blockdiagram genererade av Faust från några enkla program

De flesta FAUST-primitiver är analoga med deras C-motsvarighet på siffror, men lyfts till signaler. Till exempel arbetar FAUSTs primitiva sin på en signal X genom att applicera C -funktionen sin på varje sampel X[t]. Alla C-numeriska funktioner har sin motsvarighet i FAUST. Vissa signalbehandlingsprimitiver är specifika för FAUST. Till exempel tar fördröjningsoperatören @ två insignaler: X (signalen som ska fördröjas) och D (fördröjningen som ska appliceras), och producerar en utsignal Y så att Y(t) = X(t − D(t) )).

Blockdiagram sammansättning

I motsats till Max-liknande visuella programmeringsspråk där användaren gör manuella anslutningar, sätts FAUST-primitiv samman i blockscheman genom att använda en uppsättning blockschemakompositioner på hög nivå.

Enkla exempel på blockschemasammansättning
Operatörerna för sammansättning av blockdiagram som används i FAUST
f~g Rekursiv sammansättning (företräde 4)
f,g Parallell komposition (prioritet 3)
f:g Sekventiell komposition (företräde 2)
f<:g Delad komposition (företräde 1)
f:>g Sammanfoga sammansättning (företräde 1)

Med sekventiell kompositionsoperator : utsignalen från + kan dirigeras till ingången för abs för att beräkna det absoluta värdet av signalen:

     process  =  +  :  abs  ; 

Här är ett exempel på parallell komposition med operatorn , som ordnar sina vänster- och högeruttryck parallellt. Detta är analogt med en stereokabel.

   process  =  _  ,  _  ; 

Dessa operatörer kan kombineras godtyckligt. Följande kod multiplicerar en insignal med 0,5:

     process  =  _  ,  0,5  :  *  ; 

Ovanstående kan skrivas om i curryform :

   process  =  *  (  0,5  ); 

Den rekursiva sammansättningsoperatorn ~ kan användas för att skapa blockdiagram med cykler (som inkluderar en implicit fördröjning med ett sampel). Här är ett exempel på en integrator som tar en insignal X och beräknar en utsignal Y så att Y(t) = X(t) + Y(t−1):

     process  =  +  ~  _  ; 

Genererar fullständiga applikationer

Med hjälp av specifika arkitekturfiler kan ett FAUST-program användas för att producera kod för en mängd olika plattformar och plugin-format. Dessa arkitekturfiler fungerar som omslag och beskriver interaktionerna med värdljud- och GUI-systemet. Från och med 2021 stöds mer än 30 arkitekturer och nya kan implementeras av vem som helst.

Skärmdump av mixer.dsp (tillgänglig i FAUST-distributionen) med jack-qt-arkitekturen
Vissa arkitekturfiler tillgängliga för FAUST
alsa-gtk.cpp ALSA-applikation + GTK
alsa-qt.cpp ALSA-applikation + QT4
android.cpp Android-applikationer
au.cpp Audio Unit plug-in
ca-qt.cpp CoreAudio-applikation + QT4
ios-coreaudio.cpp iPhone och iPad applikationer
jack-gtk.cpp JACK-applikation + GTK
jack-qt.cpp JACK-applikation + QT4
ladspa.cpp LADSPA plug-in
max-msp.cpp Max MSP plug-in
pd.cpp Puredata plug-in
q.cpp Q-språk plug-in
supercollider.cpp Supercollider plug-in
vst.cpp VST plug-in
vsti-mono.cpp Monofonisk VST Instrument plug-in
vsti-poly.cpp Polyfonisk VST Instrument plug-in

Generera blockdiagram

Ett användbart alternativ gör det möjligt att generera blockschemarepresentationen av programmet som en eller flera SVG-grafikfiler.

Det är användbart att notera skillnaden mellan blockschemat och den genererade C++-koden. Som sagt är nyckelidén här inte att kompilera blockdiagrammet bokstavligt, utan den matematiska funktionen det betecknar. Moderna C/C++-kompilatorer kompilerar inte heller program bokstavligen. Men på grund av den komplexa semantiken i C/C++ (på grund av biverkningar, pekaraliasing, etc.) kan de inte gå särskilt långt i den riktningen. Detta är en tydlig fördel med ett rent funktionellt språk: det tillåter kompilatorer att göra mycket avancerade optimeringar.

Pilliknande semantik

Faust-semantiken är nästan densamma som för Haskells Arrows -typklass. Men klassen Arrow är inte bunden till signalprocessorer.

Ekvivalenser mellan FAUST- och Arrow-kombinatorer
f~g loop (( \ ( a , b ) -> ( b , a )) ^>> f >>> id &&& ( delay >>> g )) där fördröjning inte är en metod av klassen Arrow , utan är specifik för signalbehandlingspilar
f,g f***g
f:g f>>>g
f<:g f>>^h>>>g med lämplig funktion h (eller &&& i speciella fall)
f:>g f>>^h>>>g med lämplig funktion h

Arrow-kombinatorerna är mer restriktiva än sina FAUST-motsvarigheter, t.ex. bevaras kapslingen av parallell komposition, och inmatningar av operanderna för &&& måste matcha exakt.

externa länkar