PAL Scripting - Lesson 4 Working with Classes and Loops
The best way to grow your PAL scripting skills is to practice and investigate by taking something you know and making a change or adding something different.
If you open Notepad on your computer and save a blank text document as PlayGround.pal (you might need to select 'All Files (*.*)' from the Save as type, you can load this into the PAL Scripts window within SAM Broadcaster and use this to develop your PAL Scripting skills.
In this example we have copied the code from Lesson 3, Working with Classes and we have added a number of additional lines which increase the functionality of the script.
In basic terms we have added a loop which queries and displays the attributes for the next 10 playing tracks:
var Song : TSongInfo;
var MyPlayer : TPlayer;
var Count : Integer;
Count := 0;
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
begin
WriteLn(Count);
WriteLn('Artist: '+Song['artist']);
WriteLn('Title: '+Song['title']);
WriteLn('Album: '+Song['album']);
WriteLn('Label: '+Song['Label']);
WriteLn('Duration: '+Song['Duration']);
WriteLn('Composer: '+Song['Composer']);
WriteLn('Genre: '+Song['Genre']);
WriteLn('Album Year : '+Song['Albumyear ']);
WriteLn('genre: '+Song['Genre']);
WriteLn('Track No: '+Song['Trackno']);
WriteLn('Weighting: '+Song['Weight']);
WriteLn('-------------------');
end;
Song.Free;
MyPlayer.FadeToNext;
Count := Count+1;
end;
Let's break this down into the different sections within the script and explain what is happening:
Variable Declaration
var Song : TSongInfo;
var MyPlayer : TPlayer;
var Count : Integer;
Here we can see we are declaring three variables, the first is entitled 'Song' and is a container for the TSongInfo Class. This is used in the same way as shown in Lesson 3.
We declare the 'MyPlayer' variable which is used to reference the TPlayer Class.
Finally we declare an integer variable called 'Count'.
Whilst we could just as easily have named these variables X, Y and Z, you will find that by giving them identifiable names, you will more easily be able to follow the code without having to continually refer back to the Variable Declarations.
Variable Assignment
Whilst there are three places variables are assigned, two of these are repeated and within the loop and for this reason, only one variable is assigned which in this instance is the zero assigned to the variable 'Count'. This example script uses a 'While' loop which will run ten times based on the value of the variable 'Count' and for this to work, we must assign the value to the variable before the loop for this to work as expected.
Count := 0;
Script Body
The script body is where the reason for the script happens.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
begin
WriteLn(Count);
WriteLn('Artist: '+Song['artist']);
WriteLn('Title: '+Song['title']);
WriteLn('Album: '+Song['album']);
WriteLn('Label: '+Song['Label']);
WriteLn('Duration: '+Song['Duration']);
WriteLn('Composer: '+Song['Composer']);
WriteLn('Genre: '+Song['Genre']);
WriteLn('Album Year : '+Song['Albumyear ']);
WriteLn('genre: '+Song['Genre']);
WriteLn('Track No: '+Song['Trackno']);
WriteLn('Weighting: '+Song['Weight']);
WriteLn('-------------------');
end;
Song.Free;
MyPlayer.FadeToNext;
Count := Count+1;
end;
Let's break this down, line-by-line:
While Count<10 Do
This says whatever follows will run while the contents of the variable 'Count' is less that 10. Remembering we set the initial content to zero then this will run ten times (0, 1, 2, 3, 4, 5 ,6, 7, 8 & 9).
While Count<10 Do
begin
We need to show what exactly should happen whilst 'Count' is less than 10 and to do this, we use the keyword 'begin'. This must have a corresponding 'end' and it is customary to use indents to indicate matching pairs of keywords. In the image below of the PAL Scripting IDE, this 'begin' is shown on line 8 and the closing 'end' is on line 32.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
In Lesson 3 we specifically referred to Deck A however, in this script we want to refer to the active deck, no matter where this is Deck A or Deck B and to do this, we declared the MyPlayer variable and we use this to refer to the active deck.
MyPlayer references the currently Active Player and we then assign the variable 'Song', the attributes of the song information playing on the active player.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
Again we should include error checking and we want to ensure there is a track playing by checking the contents of 'Song' is not 'nil' or empty which would indicate no track is playing. If the error checking is passed then we have an alternative set of code to run which is indicated by the 'else' keyword.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
begin
WriteLn(Count);
WriteLn('Artist: '+Song['artist']);
WriteLn('Title: '+Song['title']);
WriteLn('Album: '+Song['album']);
WriteLn('Label: '+Song['Label']);
WriteLn('Duration: '+Song['Duration']);
WriteLn('Composer: '+Song['Composer']);
WriteLn('Genre: '+Song['Genre']);
WriteLn('Album Year : '+Song['Albumyear ']);
WriteLn('genre: '+Song['Genre']);
WriteLn('Track No: '+Song['Trackno']);
WriteLn('Weighting: '+Song['Weight']);
WriteLn('-------------------');
end;
Between the matching 'begin' and 'end' keywords we write the contents of the Class attributes as we did in Lesson 3.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
begin
WriteLn(Count);
WriteLn('Artist: '+Song['artist']);
WriteLn('Title: '+Song['title']);
WriteLn('Album: '+Song['album']);
WriteLn('Label: '+Song['Label']);
WriteLn('Duration: '+Song['Duration']);
WriteLn('Composer: '+Song['Composer']);
WriteLn('Genre: '+Song['Genre']);
WriteLn('Album Year : '+Song['Albumyear ']);
WriteLn('genre: '+Song['Genre']);
WriteLn('Track No: '+Song['Trackno']);
WriteLn('Weighting: '+Song['Weight']);
WriteLn('-------------------');
end;
Song.Free;
Song.Free simply cleans the memory we have been using and whilst this is not absolutely necessary, it is a good habit to get into when using loops.
While Count<10 Do
begin
MyPlayer := ActivePlayer;
Song := MyPlayer.GetSongInfo;
if Song = nil then
WriteLn('No song loaded into either Deck!')
else
begin
WriteLn(Count);
WriteLn('Artist: '+Song['artist']);
WriteLn('Title: '+Song['title']);
WriteLn('Album: '+Song['album']);
WriteLn('Label: '+Song['Label']);
WriteLn('Duration: '+Song['Duration']);
WriteLn('Composer: '+Song['Composer']);
WriteLn('Genre: '+Song['Genre']);
WriteLn('Album Year : '+Song['Albumyear ']);
WriteLn('genre: '+Song['Genre']);
WriteLn('Track No: '+Song['Trackno']);
WriteLn('Weighting: '+Song['Weight']);
WriteLn('-------------------');
end;
Song.Free;
MyPlayer.FadeToNext;
Count := Count+1;
end;
We need to load another track if we do not want to repeat the same track data ten times and in this instance we use FadeToNext which references the active player. We then increment the 'Count' variable to ensure the script stops when required.
The last line includes the 'end' which matches the 'begin' from line 8.
Comments