So umfangreich die Funktionen in mAirList auch sind, so fehlt doch immer wieder mal das eine oder andere Feature für den gewünschten Zweck. Macht aber nichts, denn genau zu diesem Zweck gibt es die Scripting-Engine, mit welcher die Möglichkeiten in mAirList noch wesentlich umfangreicher werden als ohnehin schon. Also:
Zählvariablen
Habt Ihr irgendwo im Skript mehrere gleichlautende Anweisungen, die sich auf durchnumerierte Elemente beziehen, die also nacheinander abgearbeitet werden sollen? Ich gebe mal ein Beispiel, fünf Buttons, die alle scharfgeschaltet werden sollen:
begin
ExecuteCommand('BUTTON.1 ENABLE');
ExecuteCommand('BUTTON.2 ENABLE');
ExecuteCommand('BUTTON.3 ENABLE');
ExecuteCommand('BUTTON.4 ENABLE');
ExecuteCommand('BUTTON.5 ENABLE');
end;
Das sieht irgendwie nach zuviel, nach redundant aus. Alleine das eintippen ist ja schon doof! In der Tat, und deshalb gibt es dafür auch einen Trick, es einfacher zu gestalten: Die FOR … DO
-Anweisung. Sie klingt schon nach Arbeit (also für sie, nicht für uns!), duch das DO
– „tu was!“ Mit ihrer Hilfe lassen sich solche Aufgaben elegant vereinfachen:
var
i: integer;
begin
for i := 1 to 5 do
ExecuteCommand('BUTTON.' + IntToStr(i) + ' ENABLE');
end;
Was ist hier passiert? Die Zählvariable i
wird von 1 bis 5 durchgezählt und danach jeweils die Anweisung mit dem entsprechenden Index ausgeführt.
Damit mAirList das Ergebnis auch versteht, müssen wir noch zweimal in die Trickkiste greifen. Erstens: Die Befehle, die nichts weiter als sogenannte Zeichenketten, also eine Aneinanderreihung von Buchstaben oder Ziffern sind, lassen sich auch verknüpfen – im einfachsten Falle addieren, also aneinanderhängen. Die Zuweisung
s := 'BIER';
s := 'FREI' + s;
ergibt tatsächlich
'FREIBIER'
Und, zweitens, die Zählvariable i
läßt sich nicht ohne weiteres in die Zeichenkette einbauen. Die Integer-Zahl 5
ist etwas völlig anderes als die Zeichenkette '5'
, obwohl sie eigentlich gleich aussieht.* Zur Abhilfe gibt es aber die Funktion IntToStr
, Integer to String soll das wohl heißen, und die macht aus einer solchen Zahl eine Zeichenkette. Und damit lassen sich dann solche Anweisungen wie oben
ExecuteCommand('BUTTON.' + IntToStr(i) + ' ENABLE');
zusammenbauen, so daß am Ende wieder (lassen wir es beim Beispiel i := 5
)
ExecuteCommand('BUTTON.5 ENABLE');
herauskommt. Wichtig ist übrigens das führende Leerzeichen bei ' ENABLE'
, damit hinten die richtige Zeichenfolge herauskommt.
Soll mehr als nur eine Zeile bearbeitet werden, verpackt Ihr das ganze in begin
und end;
:
begin
for i := 1 to 5 do
begin
ExecuteCommand('BUTTON.' + IntToStr(i) + ' ENABLE');
ExecuteCommand(<irgendein Befehl>);
ExecuteCommand(<noch ein Befehl>);
sleep(35);
end;
end;
Dann wird alles zwischen begin
und end;
so oft wiederholt, wie die Schleife dauert.
Das ganze kann man sogar für nützliche Dinge einsetzen: Ich zitiere mal das Skript des Forenkollegen @shorty.xs, der sich das ausgedacht hatte, um auf ein bestimmtes Ereignis hin seine Player um einen bestimmten Betrag herunterzublenden und auf ein anderes Ereignis wieder herauf:
(Da Malte seinen Code ohnehin öffentlich zur Schau stellt, bin ich mal so frei, ihn hier wiederzugeben.)
{
:: This is a mAirlist Script file, that lowers the volume of the first 2 Players of a Playlist. The Default MIC-ON function lowers all Player inputs and does not allow any selection.
:: This file needs to be registered as a "Background Script" in mAirlist COnfigration.
:: @package
:: @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
:: @author Malte Schroeder <post@malte-schroeder.de>
:: @copyright Copyright (c) 2011-2019 Malte Schroeder (http://www.malte-schroeder.de)
}
procedure OnEncoderInputToggle(Input: TEncoderInput; NewState: boolean);
begin
if (Input = eiMic) and (NewState = false) then begin
ExecuteCommand('PLAYER 1-1 VOLUME -12');
ExecuteCommand('PLAYER 1-2 VOLUME -12');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -11');
ExecuteCommand('PLAYER 1-2 VOLUME -11');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -10');
ExecuteCommand('PLAYER 1-2 VOLUME -10');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -9');
ExecuteCommand('PLAYER 1-2 VOLUME -9');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -8');
ExecuteCommand('PLAYER 1-2 VOLUME -8');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -7');
ExecuteCommand('PLAYER 1-2 VOLUME -7');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -6');
ExecuteCommand('PLAYER 1-2 VOLUME -6');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -5');
ExecuteCommand('PLAYER 1-2 VOLUME -5');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -4');
ExecuteCommand('PLAYER 1-2 VOLUME -4');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -3');
ExecuteCommand('PLAYER 1-2 VOLUME -3');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -2');
ExecuteCommand('PLAYER 1-2 VOLUME -2');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -1');
ExecuteCommand('PLAYER 1-2 VOLUME -1');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME 0');
ExecuteCommand('PLAYER 1-2 VOLUME 0');
end
else if (Input = eiMic) and (NewState = true) then begin
ExecuteCommand('PLAYER 1-1 VOLUME 0');
ExecuteCommand('PLAYER 1-2 VOLUME 0');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -1');
ExecuteCommand('PLAYER 1-2 VOLUME -1');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -2');
ExecuteCommand('PLAYER 1-2 VOLUME -2');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -3');
ExecuteCommand('PLAYER 1-2 VOLUME -3');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -4');
ExecuteCommand('PLAYER 1-2 VOLUME -4');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -5');
ExecuteCommand('PLAYER 1-2 VOLUME -5');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -6');
ExecuteCommand('PLAYER 1-2 VOLUME -6');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -7');
ExecuteCommand('PLAYER 1-2 VOLUME -7');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -8');
ExecuteCommand('PLAYER 1-2 VOLUME -8');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -9');
ExecuteCommand('PLAYER 1-2 VOLUME -9');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -10');
ExecuteCommand('PLAYER 1-2 VOLUME -10');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -11');
ExecuteCommand('PLAYER 1-2 VOLUME -11');
Sleep(100);
ExecuteCommand('PLAYER 1-1 VOLUME -12');
ExecuteCommand('PLAYER 1-2 VOLUME -12');
end
end;
Das sind fast hundert Zeilen Code, die nichts anderes machen als die Player nacheinander immer wieder um 1 dB ab- oder aufzublenden. Mit der FOR … DO
-Schleife sieht es jedoch so aus:
{
:: This is a mAirlist Script file, that lowers the volume of the first 2 Players of a Playlist. The Default MIC-ON function lowers all Player inputs and does not allow any selection.
:: This file needs to be registered as a "Background Script" in mAirlist Configration.
:: @package
:: @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
:: @author Malte Schroeder <post@malte-schroeder.de> & Tondose
:: @copyright Copyright (c) 2011-2019 Malte Schroeder (http://www.malte-schroeder.de) & Tondose (https://community.mairlist.com/u/Tondose)
}
var
i, target, delay : integer;
procedure OnEncoderInputToggle(Input: TEncoderInput; NewState: boolean);
begin
target := -12; // set your target duck range here
delay := 100; // set the delay betwee steps here to smoothen the fade
if (Input = eiMic) and (NewState = false) then begin
for i := (target) to 0 do
begin
ExecuteCommand('PLAYER 1-1 VOLUME ' + IntToStr(i));
ExecuteCommand('PLAYER 1-2 VOLUME ' + IntToStr(i));
Sleep(delay);
end;
end
else if (Input = eiMic) and (NewState = true) then begin
for i := 0 downto (target) do
begin
ExecuteCommand('PLAYER 1-1 VOLUME ' + IntToStr(i));
ExecuteCommand('PLAYER 1-2 VOLUME ' + IntToStr(i));
Sleep(delay);
end;
end;
end;
Zack, sechzig Zeilen weniger! (Sieht man von den Kopfzeilen ab, ist das Ergebnis noch sparsamer.) Ist das nichts?!
Eine Feinheit sei noch erwähnt: Beim Teil, in dem abgeblendet wird, müssen die dB ja runter-, also rückwärts gezählt werden. Auch das geht: dann schreibt ihr in die Anweisung FOR … DOWNTO
, und schon läuft die Sache achteraus.
Gezählte Grüße
TSD
* Auch „Ketten“ aus einem einzigen Glied heißen bei Delphi „Zeichenkette“.
Edit: Wie immer ein Haufen Tippfehler.