Der LADSPA-Standard hilft dabei, digitale Klangbausteine für eine Audio-Applikation so zu zimmern, dass auch andere Programme ohne viel Basteln in den Genuss der Klangbeeinflussung kommen. Der Artikel erklärt das Wie und schließt mit einem Programmierbeispiel für ein einfaches Effekt-Plugin.
Für das beste Betriebssystem der Welt ist auch ein breites Spektrum professioneller Audio-Anwendungen herangereift: vom Skript-gesteuerten Klangtüftler über DJ-Software bis zu Sequencern und Harddisk-Recording für den professionellen Einsatz im Studio.
Die meisten Applikationen hantieren mit mehr oder minder vielen Klangeffekten, meist Filtern und Oszillatoren jeder Couleur. Es ist wenig effektiv und läuft zudem dem Open-Source-Gedanken zuwider, wenn jedes Projekt die gleichen Funktionen programmiert – eine Plugin-Architektur liegt also nahe. Davon profitiert auch der Anwender, da er in weniger umfangreichen Programmen aufwändige Features nutzen kann, ohne sie neu übersetzen zu müssen.
Gerade fürs Digital Signal Processing (SDP, digitale Signalverarbeitung) bietet sich diese Architektur an: Ein digitales Audiosignal kann als kontinuierlicher Datenstrom betrachtet werden, der von einer Blackbox erzeugt oder verarbeitet wird, wobei der Benutzer den Klangcharakter durch Parameter regelt.
Die Entwicklung von digitalen Audio-Effekten und Oszillatoren ist ein sehr spezielles Feld. Einfache Schaltungen sind mit wenig Aufwand zu simulieren. Komplexere erfordern dagegen oft einige Kenntnisse in Signalverarbeitung und der zugehörigen Mathematik. In beiden Fällen lässt sich die Lösung aber meist unabhängig vom Einsatz beschreiben, ob der Computer nun in Echtzeit einen Raumhall simuliert oder eine Nacht lang nach ausgefeilten Regeln ein paar Minuten Klang errechnet.
Standard für Audio-Plugins
Seit dem Jahr 2000 verfügen Audio-Anwendungen unter Linux über eine eigene Softwareschnittstelle für eben diesen Zweck: LADSPA – Linux Audio Developer\’s Simple Plugin API. Anders als vergleichbare Lösungen auf proprietären Plattformen (VST, Direct-X) ist LADSPA konkurrenzlos und beliebt – alles was die Schnittstelle bereitstellt nutzen die Entwickler auch, den Rest implementieren sie selbst. Inzwischen existieren Plugins für beinahe alle Standardanwendungen. Die umfassendste Liste der verfügbaren Plugin-Bibliotheken bietet wahrscheinlich Dave Phillips\’ Site zu Linux und Audio [1].
Einfache Philosophie
Das S für Simple in LADSPA verdient besondere Betonung: Das API ist tatsächlich sehr einfach gehalten, trotzdem deckt es ein überraschend weites Anwendungsfeld ab: Vom Effektprozessor (Beispiel »jack-rack«, [2]) bis zum kompletten Softwaresynthesizer (Beispiel »om-synth«, [3]) arbeiten inzwischen ganze Applikationen komplett auf der Basis von LADSPA-Plugins. Für die meisten Distributionen gibt es Pakete mit dem LADSPA-SDK sowie zahlreiche Plugin-Pakete. Die Homepage führt das Quellcode-Paket, das neben dem Header ein paar nützliche Utilities und Beispiel-Plugins enthält.
Eine LADSPA-konforme Plugin-Bibliothek ist ein Shared Object, eine dynamisch gelinkte Bibliothek, die ein oder mehrere Plugins enthält. Jedes Plugin definiert Methoden und dazu ein oder mehrere so genannte Ports (Software-Endpunkt für Audio-Eingangs- und Ausgangssignale), über die es Daten mit dem Host austauscht. Ein Host ist eine Anwendung, die das Plugin aufnimmt.
Die Headerdatei »ladspa.h« definiert das LADSPA-Interface. Die Audio- und Kontrolldaten deklariert der Programmierer gleichermaßen als »LADSPA_Data«. Der Header wiederum definiert »LADSPA_Data« als »float«, also als 32-Bit-Gleitkommazahl, was sich wegen der hohen Genauigkeit für die interne Verarbeitung von Audiodaten durchgesetzt hat.

Abbildung 1: Viele Audioprogramme unter Linux lassen sich mit LADSPA-Plugins erweitern, sofern der Programmautor dies vorgesehen hat. Der Screenshot zeigt einige Fenster des Drum-Computers Hydrogen. Links oben ist das Fenster zu sehen, das verfügbare Plugins und ihre Parameter auflistet.
LADSPA-Plugins bieten kein eigenes grafisches Interface an. Eins bereitzustellen und konkret zu gestalten bleibt dem Host-Programm überlassen, in dessen Kontext das Plugin arbeitet. Einerseits erleichtert das dem Plugin-Autor natürlich das Leben und erweitert das Einsatzgebiet auch auf textbasierte Hosts und Systeme ganz ohne Bildschirm. Andererseits setzt dieser Umstand auch Grenzen, beispielsweise wenn ein Parameter eines Plugins zweckmäßigerweise als Kurve dargestellt werden sollte.
In der Praxis ist diese Einschränkung meist weniger kritisch und im Gegensatz zur vorgerenderten Vielfenster-Welt von VST, wo ein schickes Äußeres oft als Verkaufsargument herhalten muss, gilt das einheitliche und Ressourcen-schonende GUI von LADSPA-Hosts manchem als ein willkommener Vorteil.
Beispiel: Waveshaper
Dieser Artikel implementiert ein einfaches Beispiel-Plugin mit dem Namen Drive (Listing siehe [11]) und demonstriert daran die Interaktion von Plugin und Host. Es handelt sich um einen Waveshaper, also ein Plugin zur Veränderung der Wellenform. Klanglich bewirkt Drive eine leichte Kompression und eine harmonische Verzerrung ähnlich einem saturierenden analogen Magnetband oder einer Röhrenverstärker-Endstufe unter hoher Last.
Übersetzt wird das Plugin mit der Zeile »gcc -Wall -nostartfiles -shared -lm -o drive.so drive.c«. Host-Programme finden Plugin-Bibliotheken über die Umgebungsvariable »$LADSPA_PATH«, die üblicherweise auf »/usr/lib/ladspa« zeigt. Falls nicht gesetzt, verwenden die meisten Hosts diesen Pfad als Default.
Nachdem ein Host die Bibliothek »drive.so« geladen hat, ruft er die darin enthaltene Funktion »ladspa_descriptor()« auf, die als Enumerator der Plugins fungiert. Das Beispiel besteht aus nur einem Plugin, also erhält der Host auch nur für den »index«-Wert »0« einen Zeiger auf die das Plugin beschreibende Struktur, sonst »NULL«. Eine korrekt geschriebene Plugin-Bibliothek exportiert »ladspa_descriptor()« als einziges öffentliches Symbol, um Namenskonflikte mit anderen Libraries zu vermeiden. Alle anderen Symbole definiert »drive.c« als »static«.
Plugin-Deskriptor
Ein Plugin ist vollständig in einer »LADSPA_Descriptor«-Struktur beschrieben (Listing 1). Das Feld »UniqueID« identifiziert das Plugin global eindeutig (Zeile 8). Auf Anfrage erteilt Richard Furse, Maintainer von [ladspa.org], eine solche ID. Die meisten Hosts nutzen das Feld »Name«, um dem Benutzer die Auswahl von Plugins zu ermöglichen, da das kürzere »Label« oft nicht eindeutig ist.
Das Feld »Properties« teilt dem Host in diesem Fall mit (»LADSPA_PROPERTY_HARD_RT_CAPABLE«, Zeile 11), dass das Plugin für Echtzeitnutzung vorgesehen ist, also im Betrieb keinen Code ausführt, dessen Laufzeit nicht strikt begrenzt ist. Diese Einschränkung betrifft nur die Methoden »run()« und »run_adding()«, nicht aber die anderen, mit Verwaltungsaufgaben betrauten Methoden des Plugins.
|
Listing 1: |
|---|
01 static LADSPA_Descriptor
02 drive_descriptor =
03 {
04 /* Diese UniqueID gilt nur für Testzwecke.
05 * Für echte Plugins sollte eine
06 * eigene angefordert werden.
07 */
08 .UniqueID = 1,
09 .Label = "Drive",
10
11 .Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE,
12
13 .Name = "4th Order Waveshaper",
14 .Maker = "Dein Name Hier <email@address>",
15 .Copyright = "Public Domain, 2005",
16
17 .PortCount = 4,
18 .PortDescriptors = drive_port_descriptors,
19 .PortNames = drive_port_names,
20 .PortRangeHints = drive_port_range_hints,
21 .ImplementationData = 0,
22
23 .instantiate = drive_instantiate,
24 .connect_port = drive_connect_port,
25 .activate = 0,
26 .run = drive_run,
27 .run_adding = drive_run_adding,
28 .set_run_adding_gain = drive_set_run_adding_gain,
29 .deactivate = 0,
30 .cleanup = drive_cleanup,
31 };
|
Blockierende Funktionen vermeiden
Nicht echtzeitfähig ist zum Beispiel »malloc()«, weil der Aufruf Paging erfordern kann, um neuen Speicherplatz zur Verfügung zu stellen. Dabei wird die Ausführung für einige Millisekunden blockiert und der Audiodatenstrom damit unterbrochen. In dieselbe Kategorie fallen viele Syscalls und Glibc-Aufrufe, zum Beispiel zum Lesen und Schreiben von Files. Am besten bleibt der DSP-Kern eines Plugin frei von Exkursionen in Code, der in dieser Hinsicht bedenklich ist. Das umzusetzen fällt angesichts der auf Rechenaufgaben konzentrierten Natur der meisten DSP-Algorithmen aber nicht weiter schwer.
Neben den Textfeldern, die das Plugin für den Benutzer beschreiben, ist für den Host vor allem die Beschreibung der Ports und der Methoden des Plugin wichtig. Das Beispiel besitzt vier Ports, je einen Ein- und Ausgang für das Audiosignal sowie die beiden Kontrollparameter »drive« und »gain (dB)«.
Die Art der Ports entnimmt der Host dem Array »PortDescriptors«. Dort stehen beispielsweise für den Audio-Eingang der Wert »LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO« und als Nächstes für den Parametereingang »drive« der Wert »LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL«. Parameterausgänge sind zwar möglich, werden in der Praxis aber sehr selten genutzt.
Das Array »PortRangeHints« enthält für jeden Port eine Struktur vom Typ »LADSPA_PortRangeHint«. Sie ist vor allem für die Übergabe von Reglerwerten zwischen Host und Plugin von Interesse, für Audioports sind die Einträge meist uninteressant. Beispielsweise ist der Parametereingang »gain (dB)« dort beschrieben als »LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0«, also mit einer Unter- und einer Obergrenze und als Normalstellung »0«.
Die Grenzwerte für diesen Port sind als »-36« und »+36« definiert. Dass es sich dabei um Werte in der Einheit »dB« handelt, teilt das Plugin dem Benutzer üblicherweise in Klammern hinter dem Portnamen mit, so auch hier.
|
Listing 2: Plugin |
|---|
01 static LADSPA_Handle
02 drive_instantiate (const struct _LADSPA_Descriptor * Descriptor, unsigned long SampleRate)
03 {
04 Drive * d = (Drive *) calloc (1, sizeof (Drive));
05 return (LADSPA_Handle) d;
06 }
|
|
Listing 3: Ports |
|---|
01 static void
02 drive_connect_port (LADSPA_Handle Instance, unsigned long Port, LADSPA_Data * DataLocation)
03 {
04 Drive * d = (Drive *) Instance;
05 d->ports[Port] = DataLocation;
06 }
|
|
Listing 4: |
|---|
01 static void
02 drive_run (LADSPA_Handle Instance, unsigned long SampleCount)
03 {
04 Drive * d = (Drive *) Instance;
05
06 LADSPA_Data * src = d->ports[0];
07 LADSPA_Data drive = 0.25f * *(d->ports[1]);
08 LADSPA_Data gain = pow (10, 0.05 * *(d->ports[2]));
09 LADSPA_Data * dest = d->ports[3];
10
11 LADSPA_Data x;
12 unsigned long i;
13
14 /* Ein Wert von 1 würde zu Division durch 0 führen, lieber defensiv mit dem
15 * Parameter umgehen.
16 */
17 if (drive == 1) drive = .9999;
18
19 /* Korrektur für die Lautstärkensenkung durch den Algorithmus */
20 gain *= 1.0f / (1.0f - drive);
21
22 for (i = 0; i < SampleCount; ++i)
23 {
24 x = src[i];
25 dest[i] = gain * (x - drive * fabsf (x) * x * x * x);
26 }
27 }
|
Das Plugin im Einsatz
Wenn der Host das Beispiel-Plugin verwenden möchte, bemüht er die Methoden der Deskriptor-Struktur beginnend mit dem Konstruktor »instantiate()«, der eine Instanz des Plugin anlegt. Eine einfache Struktur repräsentiert eine lauffähige Instanz des Beispiel-Plugin:
typedef struct
{
LADSPA_Data * ports[4];
LADSPA_Data adding_gain;
} Drive;
Da der DSP-Algorithmus des Beispiels zustandslos ist, speichert das Plugin nur die Übergabepunkte (Adressen) der vier Plugin-Ports sowie ein Mischverhältnis, das erforderlich wird, wenn das Ausgangssignal mit einem bereits vorliegenden Signal zu mischen ist. Das Plugin zu instanziieren erschöpft sich zum größten Teil darin, Speicher zu reservieren (siehe Listing 2).
Plugin-Parameter
Für den Fall, dass die Plugin-Bibliothek mehrere Plugins mit derselben »instantiate()«-Methode anlegen kann, übergibt der Host einen Zeiger auf den gewünschten »Descriptor«. Der Beispielcode mit nur einer Art von Plugin kann diesen Parameter getrost ignorieren. In vielen Fällen ist jedoch der zweite Parameter »SampleRate« wichtig, da das Plugin die Sample-Frequenz nur dieses eine Mal erfährt. Der Wert sollte also in der Instanz des Plugin gespeichert werden, falls er für den eigentlichen DSP-Algorithmus wichtig ist.
Die Funktion »instantiate()« gibt einen »LADSPA_Handle« zurück. Den benutzt der Host in allen folgenden Methodenaufrufen, um auf die Plugin-Instanz zuzugreifen. Für den Fall, dass das Plugin nicht mit der gewünschten Samplerate arbeitet oder ein Fehler bei der Instanziierung auftritt, soll diese Methode »NULL« zurückgeben.

Abbildung 2: Das Funktionsprinzip des Beispiel-Plugin mit Kontroll- (blau) und Audioports (rot). In der Mitte die Steuerkurve des Waveshaper-Algorithmus.
Üblicherweise ruft der Host für jeden Port einmal »connect_port()« auf, um der Plugin-Instanz mitzuteilen, wo eingehende und ausgehende Audiosignale sowie Kontrollwerte im Speicher liegen (Listing 3).
Initialisieren oder aktivieren
Da das Plugin nicht davon ausgehen kann, dass »DataLocation« zu diesem Zeitpunkt auf gültige Daten zeigt, speichert es die Adresse zur späteren Verwendung. Bevor die eigentliche Audioverarbeitung beginnt, ruft der Host noch die Methode »activate()« auf, falls das Plugin sie definiert.
Das Beispiel-Plugin kommt ohne diesen Service aus. Plugins, die umfangreichere Berechnungen ausführen müssen, bevor sie betriebsbereit sind, sollten diese Gelegenheit nutzen. Der LADSPA-Header empfiehlt dafür »activate()« statt »instantiate()«. In der Praxis ist dieser Unterschied aber selten von Belang.
Zwei Umstände sind für den Plugin-Autor in diesem Zusammenhang wichtig: Erstens kann der Host »connect_port()« jederzeit aufrufen, zweitens ist nicht sichergestellt, dass er »activate()« tatsächlich erst bemüht, nachdem er für jeden Port »connect _port()« ausgeführt hat. In der Praxis bedeutet Letzteres, dass ein Plugin in »activate()« keine Initialisierung auf der Basis bereits zugänglicher und zuverlässiger Regelwerte durchführen kann.
Das hat Auswirkungen auf den Echtzeitbetrieb: In der CAPS-Bibliothek des Autors sind die meisten Plugins darauf ausgelegt, Regleränderungen abzufedern, also plötzliche Sprünge in Kontrollparametern nicht mit einem hörbaren Klicken zu quittieren, sondern eine gleichmäßige Änderung des Klangs zum neuen Parameterwert zu gestalten.
Dafür muss ein Plugin bei jedem zu behandelnden Block Audiodaten vom vorherigen Reglerstand aus weiterrechnen. Liegen beim Aufruf von »activate()« keine gültigen Startwerte bei den Ports an, geht ein Plugin zu Beginn des laufenden Betriebs von einer Regleränderung aus, obwohl dies gar nicht der Fall ist.
Audio- und Kontrollports
Nachdem das Plugin instanziiert, alle Ports verbunden und das grüne Licht per »activate()« eingeschaltet ist, geht das Plugin zur Audioverarbeitung über. Der Host ruft wiederholt die Methode »drive_run()« auf (Listing 4). Es fällt zuerst der Unterschied zwischen Audio- und Kontrollports auf: die Audioports mit den Indizes 0 und 3 (Zeilen 6 und 9) zeigen auf ein Array von »LADSPA_Data«, das jeweils ein Audiosignal mit »SampleCount« Samples aufnimmt. Die Kontrollports enthalten lediglich einen einzelnen Wert.
Echtzeit oder offline?
Das Plugin selbst kann nicht wissen, ob es in Echtzeit oder offline läuft. Es ist bewusst offen gehalten, welche Werte »SampleCount« annehmen kann, also wie groß der jeweils zu behandelnde Block von Audiodaten ist. Hosts können damit die Rate steuern, mit der sich Kontrollwerte (im durch CSound geprägten Jargon die K-Rate) ändern lassen, bis zum Extremfall A-Rate = K-Rate, also Sample-Frequenz gleich Kontrollwertfrequenz. Im Normalfall reichen aber die meisten Hosts die Blockgröße des verwendeten Audio-Interface direkt durch, für harte Echtzeitanwendungen üblicherweise 32 bis 128 Samples.
Im Offline-Betrieb verarbeiten Plugins möglichst große Blöcke, um den Overhead durch häufige Funktionsaufrufe und nicht gefüllte Caches zu verringern. In jedem Fall kann der Plugin-Autor keine Annahmen über die Blockgröße bei der Verarbeitung treffen.
|
Listing 5: Mischen |
|---|
01 static void
02 drive_run_adding (LADSPA_Handle Instance, unsigned long SampleCount)
03 {
04 ...
05 /* Hier verarbeitet das Plugin den 'adding_gain' */
06 gain *= d->adding_gain / (1.0f - drive);
07
08 for (i = 0; i < SampleCount; ++i)
09 {
10 x = src[i];
11
12 /* '+=' anstatt '=' sorgt für das gewünschte Mischen */
13 dest[i] += gain * (x - drive * fabsf (x) * x * x * x);
14 }
15 }
|

Abbildung 3: Das Beispiel-Plugin im »jack-rack«, das den Sound-Daemon Jack und LADSPA-Plugins verbindet; unten die Parameter »drive« und »gain (dB)«.
Obwohl der Port »drive« mit einem Wertebereich von 0 bis 1 spezifiziert ist, fängt das Plugin einen Wert außerhalb dieses Bereichs extra ab, um eine Division durch 0 zu vermeiden (Zeile 20) – der Betrieb von Geräten außerhalb der Spezifikation besitzt im Audio-Umfeld eine große Tradition.
Schließlich geht aus der Formulierung des DSP-Algorithmus hervor, dass das Plugin Wertebereiche des Audiosignals von -1 bis 1 an Ein- wie Ausgängen voraussetzt. Das heißt, ein Pegel von 0 dB entspricht rechnerisch einer glatten 1 oder -1. Diese Konvention hat sich im digitalen Audiobereich, zumindest wenn Samples als Datentyp »float« dargestellt werden, weitgehend durchgesetzt.
Ausgangssignal schon im Plugin mischen
Die »run()«-Methode überschreibt den Speicherbereich, der mit dem Audio-Ausgang des Plugin verbunden ist. Manche Hosts sind aus Effizienzgründen so konzipiert, dass Plugins das Ausgangssignal mit einem bereits berechneten Signal mischen können. Für diesen Zweck sieht »ladspa.h« die Methode »run_adding()« vor.
Ein Plugin, das die optionale Methode unterstützt, stellt zugleich auch die Methode »set_run _adding_gain()« zur Verfügung, mit der der Host einen Multiplikator für Ausgangssignale setzen kann, um das Lautstärkenverhältnis der Mischung vorzugeben. Listing 5 zeigt für das Beispiel-Plugin den Unterschied in der Implementation.
Abmelden und aufräumen
Da »run_adding()« fast exakt die gleiche Funktionalität implementiert wie »run()«, sehen sich beide – wie hier – meist zum Verwechseln ähnlich. Der duplizierte Code und die subtilen Unterschiede erfordern besondere Sorgfalt bei Implementierung und Wartung. Viele Plugin-Autoren lassen stattdessen »run_adding()« einfach weg oder setzen auf eigens entwickelte Mechanismen, um den eigentlichen DSP-Algorithmus nur einmal schreiben zu müssen und die beiden verwandten Methoden automatisiert generieren zu lassen.
Sobald der Host die Plugin-Instanz nicht mehr benötigt, ruft er die »deactivate()«-Methode auf, falls das Plugin eine solche besitzt. Danach kann der Host das Plugin mit einem erneuten Aufruf von »activate()« auf den weiteren Betrieb vorbereiten. Alternativ ruft der Host den Destruktor »cleanup()« auf, um sämtliche von der Instanz belegten Ressourcen freizugeben:
static void
drive_cleanup (LADSPA_Handle Instance)
{
free ((void *) Instance);
}
Im Normalfall ist selten mehr Arbeit nötig als hier in »drive_cleanup()«. Natürlich sollten Plugins in dieser Funktion auch offene Dateien schließen und belegten Speicher wieder freigeben.
Testen mit »applyplugin«
Zum Testen eines Plugin bieten sich zunächst Offline-Hosts wie »applyplugin« (aus dem LADSPA-SDK) und die darauf folgende visuelle und rechnerische Inspektion der resultierenden Audiosignale an. Diese Methode sortiert die gröbsten Fehler aus, ohne Schäden an Ohr oder technischer Ausstattung zu riskieren. Um das Beispiel-Plugin bei maximalem »drive« und Senkung des Pegels um 3Â dB zu testen, genügt das Kommando:
applyplugin Eingang.wav Ausgang.wav drive.so Drive 1 -3
Anschließend lässt sich das Ergebnis »Ausgang.wav« im Soundeditor oder mit Hilfe eines geeigneten Skripts genauer analysieren.
Beim Entwickeln von LADSPA-Plugins erweist sich ein Offline-Host mit guter Scripting-Fähigkeit als nützlich, beispielsweise das mitgelieferte »applyplugin«, »snd« [5] oder »ecasound« [6]. In einer solchen kontrollierten Umgebung ist es möglich, allgemeine und spezielle Anwendungsfälle aufs Bit genau zu untersuchen. Zu beachten ist, dass viele Hosts nur beim Programmstart nach verfügbaren Plugins suchen und die neu übersetzte Version eines Plugin vor dem nächsten Start nicht berücksichtigen.
Erst wenn die generelle Funktion eines neuen Plugin sichergestellt ist, lohnt sich der Test in einem Echtzeithost wie Jack-Rack, Ardour [7] oder Pd [8]. Das Feilen an klanglichen Details kann zwar viel Zeit in Anspruch nehmen, ist für ein wirklich gutes Ergebnis aber unumgänglich.
|
LADSPA-Schwächen |
|---|
|
Beim einfach gehaltenen Ansatz von LADSPA bleibt einiges unberücksichtigt, was Plugin- und Host-Autoren sinnvoll erscheint:
|
Kosten der Einfachheit?
LADSPA konzentriert sich auf den kleinsten gemeinsamen Nenner der Audioverarbeitung durch Plugins. Der Header »ladspa.h« ist im Interesse größter Klarheit bewusst ausführlich gehalten. Das führt bei komplexen Plugins aber schnell zu ebenso ausführlichem Code. Es lohnt sich daher für den Entwickler, die Vorgaben des API umzuformulieren, um Plugin-Quelltexte einfach strukturiert, lesbar und kompakt zu halten.
Das Beispiel-Plugin zeigt bescheidene Ansätze in dieser Richtung, viele Autoren gehen aber noch einen Schritt weiter und automatisieren die repetitiven Elemente der Architektur. Beispielsweise setzt Steve Harris in seiner eindrucksvollen Kollektion [http://plugin.org.uk] Perl ein, um aus Plugin-Beschreibungen in einem XML-Format den eigentlichen C-Quelltext seiner Plugins zu generieren. Der Autor verlässt sich aber für sein CAPS-Paket [10] stattdessen auf Templates in C++.
Wie jede Software-Architektur besitzt auch LADSPA einige Schwachpunkte, siehe Kasten “LADSPA-Schwächen”. Viele dieser Mängel können Plugin-Entwickler aber mit etwas Gedankenarbeit umgehen.
Nicht perfekt, aber einfach gut
Die große Auswahl und die Qualität der bereits vorhandenen Plugins spricht trotz der Schwächen für den LADSPA-Standard. Mit DSSI (DSSI Soft Synth Instrument, [11]) gibt es inzwischen eine viel versprechende Erweiterung dafür. Sie ermöglicht nicht nur GUIs für Plugins, sondern bietet auch eine Umgebung für komplette Softwaresynthesizer im Plugin-Format. Das Beste dabei: LADSPA-Kenntnisse sind weiterhin nützlich. (ofr)
|
Infos |
|---|
|
[1] Mirror der Linux-Sound-Site: [http://linuxsound.atnet.at] [2] Jack-Rack: [http://jack-rack.sourceforge.net] [3] Om-Synth: [http://www.nongnu.org/om-synth] [4] LADSPA-Homepage: [http://www.ladspa.org] [5] Sound-Editor Snd: [http://ccrma.stanford.edu/software/snd] [6] Ecasound: [http://eca.cx/ecasound] [7] Ardour: [http://ardour.sourceforge.net] [8] Pd: [http://pure-data.org] [9] Steve Harris\’ Plugins: [http://plugin.org.uk] [10] CAPS-Plugins: [http://quitte.de/dsp/caps.html] [11] DSSI: [http://dssi.sourceforge.net] [12] Listings online: [https://www.linux-magazin.de/pub/listings/magazin/2005/09/LADSPA] |
|
Der Autor |
|---|
|
Tim Goetze arbeitet seit 1988 als freier Programmierer. Er ist seit 1996 beruflich und privat passionierter Linux-Nutzer. |





