Wir zeigen Dir, wie man mit dem Kontakt Scripting Processor die Benutzeroberfläche von Software-Instrumenten gestaltet und Potis, Fader, Switches & Co. mit entsprechenden Funktionen verknüpft. Nach diesem Einsteiger-Tutorial bist auch Du in der Lage, gleich heute Dein erstes eigenes Instrument zu scripten!
von Marc Bohn und Klaus Baetz
Kontakt von Native Instruments ist wohl einer der verbreitetsten Software-Sampler überhaupt. Der Kontakt Scripting Processor, kurz KSP, wurde mit Kontakt 2 eingeführt und hat sich über die Jahre zu einem unglaublich mächtigen Werkzeug entwickelt. Mittlerweile gibt es hunderte Libraries, die die Funktionen von KSP nutzen um Samples auf intelligente Art und Weise abzuspielen und dem so entstandenen Instrument ein Gesicht zu geben. Dieses kleine Tutorial soll Dir ein paar Grundfunktionen von KSP näherbringen. Wir versuchen uns in diesem Beispiel an etwas ganz einfachem und bringen die Steuerelemente eines einbandigen Equalizers auf die Benutzeroberfläche.
Die Arbeit mit dem KSP Editor
Um komplexere KSP Scripts zu bearbeiten, die auch gerne mal 15000 Zeilen Code und mehr enthalten können, empfiehlt sich definitiv der Einsatz eines externen Texteditors; für unsere Zwecke reicht Kontakts eigener Editor jedoch völlig aus. Nachdem wir also Kontakt geöffnet haben erstellen wir ein neues NKI (Kontakt Instrument) durch Doppelklick auf einen leeren Slot im Multirack.
Jetzt wechseln wir in den Editmode (Schraubenschlüssel Button) und klicken dort rechts auf den Button „Script“. Nun öffnet sich Kontakts Scripteditor mit dem wir einem NKI bis zu fünf verschiedene Scripts zuweisen können. Uns reicht eines, daher können wir direkt auf den kleinen Editbutton unten links klicken und fröhlich in das nun offene Textfeld hineintippen.
Wenn wir unser Script ausführen wollen, verwenden wir dazu einfach den „Apply“ Button oben rechts. Gesetzt den Fall, es gibt keine Fehler in unserem Script, sollte Kontakt auch keine Fehlermeldung ausspucken: Die Infozeile direkt unter dem Editor zeigt „script updated (no errors)“ an und wir können unsere Änderungen direkt ausprobieren.
Weitere Vorbereitungen
Damit wir den Equalizer auf die Oberfläche bringen können, müssen wir natürlich auch einen in unser NKI einfügen. Daher wählen wir im Groupeditor die erste Gruppe an (in einem neuen NKI gibt es nur eine Gruppe) und fügen dann weiter unten in den Group Insert FX den 1-band EQ in den ersten Effektslot ein.
Callbacks
Ein Kontakt Script ist in verschiedene „Sinnabschnitte“ unterteilt, sogenannte Callbacks. Diese Callbacks werden immer dann ausgeführte, wenn bestimmte Dinge innerhalb des Scripts passieren. Wenn der User also auf einen Knopf auf der eigens gescripteten Benutzeroberfläche klickt, wird der zugehörige Callback des Buttons ausgeführt. Den ersten Callback, den wir jedoch benötigen, ist der sogenannte init Callback – er initialisiert das Instrument und wird dann einmals ausgeführt, wenn die NKI Datei geöffnet wird. Wir leiten den Callback mit on init ein und beenden ihn mit end on. Unser Script sieht also bisher so aus:
on init end on
Zwischen diesen beiden Zeilen fügen wir jetzt also den Code ein, der beim Laden unseres Instruments ausgeführt wird. Unter anderem werden hier sämtliche Befehle eintragen, die unsere GUI, die Grafische Benutzeroberfläche definieren.
Eine GUI entsteht
Für unseren Equalizer brauchen wir drei Potis damit wir ihn vollparametrisch bedienen können. Da wir in unserem Beispiel keine eigenen Grafiken verwenden werden, greifen wir auf ein vordefiniertes Steuerelement von Kontakt zurück, den ui_knob. Wir fügen folgenden Code ein:
declare ui_knob $Freq (0,1000000,1) declare ui_knob $Gain (0,1000000,1) declare ui_knob $BW (0,1000000,1)
Soeben haben wir drei Potis erstellt:
Den declare Befehl verwendet man, um Variablen zu erstellen oder, wie in unserem Fall, Steuerelemente. Darauf folgt der Typ des Steuerelements; hier also ein ui_knob. Als nächstes folgt der interne Name des Steuerelements. Dieser ist frei wählbar, beginnt jedoch immer mit einem $-Zeichen und sollte weiterhin auf Buchstaben, Zahlen und Binde- bzw. Unterstriche beschränkt sein. Die drei, durch Kommata getrennten Zahlen in Klammern definieren das Verhalten unseres Potis jetzt noch genauer. Die ersten beiden Zahlen geben den Wertebereich des Potis an, also von 0 bis 1000000. Dazu muss man wissen, dass jedes Kontakt-interne Poti mit einem Wertebereich von 0 bis 1000000 arbeitet. Die letzte Zahl sagt dem Poti dann einfach nur noch, dass sich die Werte in Einerschritten erhöhen. Wenn man nun Genaueres über die Definition eines solchen Befehls wissen will, empfiehlt sich der Blick in das KSP Reference Manual, was bei jeder Kontakt Installation mitkopiert wird. Dort sind sämtliche Befehle mit Beispielen aufgeführt.
Unser Beispielscript sollte also nun ungefähr so aussehen und einen Klick auf den Apply-Button sollte Kontakt auch problemlos akzeptieren:
on init declare ui_knob $Freq (0,1000000,1) declare ui_knob $Gain (0,1000000,1) declare ui_knob $BW (0,1000000,1) end on
Somit haben wir jetzt drei Potis die man auch schon fröhlich bewegen kann. Leider passiert ansonsten rein gar nichts, denn das Script weiß ja noch nicht, was es bei einer Bewegung der Potis tun soll. Widmen wir uns also den nächsten Callbacks.
Es funktioniert
Der nächste Callback, den wir kennenlernen, ist der ui_control Callback; dieser kommt immer dann ins Spiel, wenn ein Steuerelement auf der GUI verwendet wird. Jedes unserer drei Potis bekommt seinen eigenen ui_control Callback, daher tippen wir folgendes unterhalb unseres bisherigen Codes in den Editor:
on ui_control ($Freq) end on on ui_control ($Gain) end on on ui_control ($BW) end on
Somit haben wir die Grundlage für die Arbeit mit unseren Potis geschaffen indem wir ihnen nun individuelle Befehle zuweisen können. Damit die Potis jetzt auch Kontakts eigenen EQ fernsteuern können, brauchen sie den set_engine_par Befehl. Dieser ist folgendermaßen definiert:
set_engine_par (parameter,value,group,slot,generic)
„Parameter“ bestimmt, welcher Funktion angesteuert werden soll, „Value“ ist der Wert, „Group“ ist die Gruppennummer, „Slot“ ist der Effektslot (falls man einen Effekt ansteuert) und „Generic“ wird für verschiedene Zwecke verwendet. Überarbeiten wir also unser erstes Poti:
on ui_control ($Freq) set_engine_par ($ENGINE_PAR_FREQ1,$Freq,0,0,-1) end on
Der Parameter ist in diesem Falle also die Centerfrequenz des EQ Bandes welche mit $ENGINE_PAR_FREQ1 angesteuert wird, Value ist logischweise unser Poti (also $Freq), Group ist 0 (in Kontakt ist alles nullbasierend – Gruppe 1 ist 0, Gruppe 2 ist 1 etc.), der Slot ist ebenfalls 0 und den Generic Wert brauchen wir nicht, daher setzen wir ihn auf -1. Mit ganz ähnlichen Befehlen können wir auch die anderen beiden Potis ergänzen und das Script sollte jetzt ungefähr so aussehen:
on init declare ui_knob $Freq (0,1000000,1) declare ui_knob $Gain (0,1000000,1) declare ui_knob $BW (0,1000000,1) end on on ui_control ($Freq) set_engine_par ($ENGINE_PAR_FREQ1,$Freq,0,0,-1) end on on ui_control ($Gain) set_engine_par ($ENGINE_PAR_GAIN1,$Gain,0,0,-1) end on on ui_control ($BW) set_engine_par ($ENGINE_PAR_BW1,$BW,0,0,-1) end on
Nach einem Klick auf Apply funktionieren die Potis jetzt auch und steuern Kontakts internen EQ.
Falscher Start
Die Potis funktionieren – so weit, so gut. Jedoch bei jedem Klick auf Apply oder beim erneuten Laden des NKIs stehen die Potis wieder auf Linksanschlag. Damit sie schon beim Start den richtigen Wert besitzen, müssen wir diesen im init Callback auslesen. Dazu verwenden wir diesmal nicht set_engine_par sondern get_engine_par, denn wir wollen ja keinen Wert setzen sondern einen erhalten. Unter die drei declare Befehle im init Callback schreiben wir jetzt also
$Freq:=get_engine_par ($ENGINE_PAR_FREQ1,0,0,-1) $Gain:=get_engine_par ($ENGINE_PAR_GAIN1,0,0,-1) $BW:=get_engine_par ($ENGINE_PAR_BW1,0,0,-1)
Mit := weißt man einer Variable oder einem Steuerelement einen bestimmten Wert zu; in diesem Falle also den internen Wert des entsprechenden EQ Parameters den wir mit get_engine_par auslesen können.
Verfeinerungen
Leider zeigen die Potis EQ-untypische Werte an – nämlich ihren eigenen Wert zwischen 0 und 1000000. Um dies zu ändern, müssen wir unsere ui_control Callbacks um jeweils einen Befehl ergänzen: set_knob_label (variable,text)
„Variable“ ist der Name unseres Steuerelements und „Text“ ist der Text, der ausgegeben werden soll. Um die EQ-Werte auszugeben brauchen wir allerdings noch die Hilfe eines zweiten Befehls der dem get_engine_par Befehl extrem ähnlich ist:
set_knob_label ($Freq,get_engine_par_disp ($ENGINE_PAR_FREQ1,0,0,-1))
Der Unterschied ist, dass get_engine_par_disp im Gegensatz zu get_engine_par nicht den internen Kontakt-Wert ausgibt, sondern die interne Kontakt-Anzeige. Und damit die korrekten Werte auch gleich zu Beginn angezeigt werden, schreiben wir dieselben drei Zeilen auch in unseren init Callback und das komplette Script sieht nun ungefähr so aus:
on init declare ui_knob $Freq (0,1000000,1) declare ui_knob $Gain (0,1000000,1) declare ui_knob $BW (0,1000000,1) $Freq:=get_engine_par ($ENGINE_PAR_FREQ1,0,0,-1) $Gain:=get_engine_par ($ENGINE_PAR_GAIN1,0,0,-1) $BW:=get_engine_par ($ENGINE_PAR_BW1,0,0,-1) set_knob_label ($Freq,get_engine_par_disp ($ENGINE_PAR_FREQ1,0,0,-1)) set_knob_label ($Gain,get_engine_par_disp ($ENGINE_PAR_GAIN1,0,0,-1)) set_knob_label ($BW,get_engine_par_disp ($ENGINE_PAR_BW1,0,0,-1)) end on on ui_control ($Freq) set_engine_par ($ENGINE_PAR_FREQ1,$Freq,0,0,-1) set_knob_label ($Freq,get_engine_par_disp ($ENGINE_PAR_FREQ1,0,0,-1)) end on on ui_control ($Gain) set_engine_par ($ENGINE_PAR_GAIN1,$Gain,0,0,-1) set_knob_label ($Gain,get_engine_par_disp ($ENGINE_PAR_GAIN1,0,0,-1)) end on on ui_control ($BW) set_engine_par ($ENGINE_PAR_BW1,$BW,0,0,-1) set_knob_label ($BW,get_engine_par_disp ($ENGINE_PAR_BW1,0,0,-1)) end on
Eine letzte Verfeinerung noch und dann soll es das erst mal gewesen sein. Wenn wir den Editmode verlassen (klick auf den Schraubenschlüssel), ist auch unsere GUI weg. Das soll natürlich nicht so sein und deshalb müssen wir die GUI dieses Scripts als sogenannte Performanceview definieren. Das lässt sich ganz einfach erledigen indem wir in unseren init Callback noch den Befehl einfügen:
make_perfview
Fertig ist unser gescripteter 1-band EQ:
Weiterführende Informationen:
Für alle die sich für diese Art des Scriptings interessieren ist das Buch „KSP Scripting 1, NI Kontakt-Skripte verstehen und entwickeln“ von Mike Novy zu empfehlen. Das einzige deutschsprachige Buch zu diesem Thema.
Da das aktuelle Manual von Kontakt 5 keine wirkliche Einführung in die Skriptsprache bietet sondern eine Auflistung aller verfügbaren Befehle ist, ist es ratsam, das KSP Manual von Kontakt 2 als Grundlage zu nehmen, da dieses auch für Einsteiger gedacht ist.
Ein gutes Online-Tutorial stamm von Nils Liberg: http://www.nilsliberg.se/ksp/scripts/tutorial. Auf seiner Webseite findet man außerdem einen empfehlenswerten Editor.
_____________________________________
Über die Autoren:
Marc Bohn ist Systeminformatiker und Absolvent der SAE in Köln – Bachelor of Arts (Hons.) Audio Production. Er arbeitet derzeit als Produzent und Audio Engineer für verschiedene Tonstudios und Labels in Köln. Zudem ist er als freier Mitarbeiter für die SALZBRENNER STAGETEC MEDIAGROUP tätig und schreibt als Press Release Assistant dort Reportagen, Fachmagazinartikel und Pressemeldungen.
Klaus Baetz hat in Köln sein Audio Engineering Diploma gemacht und ist im Anschluss für den Bachelor of Recording Arts nach Berlin. Heute ist er als Sound Designer und KSP-Scripter für Native Instruments, Sample Logic und Galaxy Instruments tätig.
Ein Portrait über Klaus und seine Arbeit findest du hier im Blog:
Audio-Engineer oder Coder? Warum nicht beides!
Bilder: Klaus Baetz, Martin Ulm (Titelbild)