This script will play a predetermined number of adverts through Aux1 deck after a specified number of music tracks. There are a number of configurable options which are explained below.
The script is available to download at the bottom of this article.
{********************************************************
PAL Script to play Adverts between Tracks with Aux Deck A
********************************************************}
PAL.Loop := True; // Loop the PAL Script
// Declare TPlayer Variables
var Player1 : TPlayer; // Declare an instance of TPlayer for the Active Player
var Player2 : TPlayer = DeckB; // Declare an instance of TPlayer for the Idle Player
var Player3 : TPlayer = aux1; // Declare an instance of TPlayer for the Aux1 Player
// Declare Variable to Store the Playlist Rules
var MinAlTime : integer; // Stores the current Minimum Album Repeat
var MinArTime : integer; // Stores the current Minimum Artist Repeat
var MinTiTime : integer; // Stores the current Minimum Title Repeat
var MinTrTime : integer; // Stores the current Minimum Track Repeat
// Declare the TSongInfo Containers
var P1Track, P2Track, P3Track : TSongInfo;
// Variable Declarations
var AdCount : integer; // Used to Count the number of adverts added and played
// Declare Adjustable Variables
var NormalVol : integer = 255; // Set the normal volume level here
var LoudVol : integer = 350; // Set the high volume level here
var AdTotal : integer = 5; // Set the number of adverts to play
var PlayCount : integer = 1; // Set the number of tracks to play before queuing adverts
var ShortOffSet : integer = 500; // Used to queue the adverts, adjust as necessary
var LongOffset : integer = 1500; // Used to wait for the end of the current track less this value
PAL.WaitForPlayCount(PlayCount - 1);// Wait for the set number of tracks to play before playing the adverts
PAL.LockExecution; // Speed up the Script processing
// Check for the Active Player
Player1 := ActivePlayer; // Assign the Active Player to Player1
If Player1 = DeckB Then Player2 := DeckA; // Assign the Idle Player to Player 2
Player2.pause; // Pause the non-playing deck
PAL.WaitForTime(Float(Now) + ((Player1.Duration - Player1.CurTime - 1500) / 86400000));
Player1.FadeToPause; // Fades the current track LongOffset from the end of the track
// Record the current Playlist Rules in Case they are not default
MinAlTime := PlaylistRules.MinAlbumTime;
MinArTime := PlaylistRules.MinArtistTime;
MinTiTime := PlaylistRules.MinTitleTime;
MinTrTime := PlaylistRules.MinTrackTime;
// Set the Playlist Rules to 1 to account for multiple repeats of short adverts
PlaylistRules.MinAlbumTime := 1; // Sets the minimum Album repeat to 1 minute
PlaylistRules.MinArtistTime := 1; // Sets the minimum Artist repeat to 1 minute
PlaylistRules.MinTitleTime := 1; // Sets the minimum Title repeat to 1 minute
PlaylistRules.MinTrackTime := 1; // Sets the minimum Track repeat to 1 minute
Player3.Volume := LoudVol; // Increase the Player Volume for the Adverts
// Add the required number of adverts to the top of the queue
for AdCount := 1 to AdTotal do
begin
CAT['Advertisements (All)'].QueueTop(smLRP,EnforceRules);
end;
AdCount := 0; // Reset AdCount to 0
// Play the Adverts
while (AdCount < AdTotal) do
begin
P3Track := Queue.NextInQueue;
Player3.QueueSong(P3Track);
Player3.Play;
PAL.WaitForTime(Float(Now) + ((Player3.Duration - Player3.CurTime - ShortOffSet) / 86400000));
AdCount := AdCount + 1;
end; // end for the While loop
// Restore the Normal Volume Level
Player3.Volume := NormalVol; // Restore the normal Player Volume level
Player2.Play; // Play the queued track
// Restore the original Playlist Rules
PlaylistRules.MinAlbumTime := MinAlTime;
PlaylistRules.MinArtistTime := MinArTime;
PlaylistRules.MinTitleTime := MinTiTime;
PlaylistRules.MinTrackTime := MinTrTime;
PAL.UnLockExecution; // Return PAL Script processing to normal speed
// Housekeeping
P1Track.Free;
P2Track.Free;
P3Track.Free;
So let's break this script down in to the various sections to make it simpler to understand:
The Opening Remarks
It is always a good idea to add some comments to a script to give an indication of the script's purpose. You could also consider including dates and code revision dates:
{********************************************************
PAL Script to play Adverts between Tracks with Aux Deck A
********************************************************}
Script Loop
PAL.Loop := True; // Loop the PAL Script
We usually want adverts to play at specific times without having to worry about scheduling. This script will play a certain number of adverts after a set number of tracks but this will only run once unless we set the script to loop.
Variable Declarations
It is usual to declare variables at the start of any script or program. They are easier to find which can simplify troubleshooting.
// Declare TPlayer Variables
var Player1 : TPlayer; // Declare an instance of TPlayer for the Active Player
var Player2 : TPlayer = DeckB; // Declare an instance of TPlayer for the Idle Player
var Player3 : TPlayer = aux1; // Declare an instance of TPlayer for the Aux1 Player
// Declare Variable to Store the Playlist Rules
var MinAlTime : integer; // Stores the current Minimum Album Repeat
var MinArTime : integer; // Stores the current Minimum Artist Repeat
var MinTiTime : integer; // Stores the current Minimum Title Repeat
var MinTrTime : integer; // Stores the current Minimum Track Repeat
// Declare the TSongInfo Containers
var P1Track, P2Track, P3Track : TSongInfo;
// Variable Declarations
var AdCount : integer; // Used to Count the number of adverts added and played
// Declare Adjustable Variables
var NormalVol : integer = 255; // Set the normal volume level here
var LoudVol : integer = 350; // Set the high volume level here
var AdTotal : integer = 5; // Set the number of adverts to play
var PlayCount : integer = 1; // Set the number of tracks to play before queuing adverts
var ShortOffSet : integer = 500; // Used to queue the adverts, adjust as necessary
var LongOffset : integer = 1500; // Used to wait for the end of the current track less this value
You can see we have declared the variables in blocks which helps to read the script. Firstly, the TPlayer containers are declared which enable us to make use of the players.
We declare variables to store the current Playlist Rotation Rules. It is good practice to store anything we will be changing so we can restore the original values later on, we should not assume that the default values were in use when we made changes.
Next, the TSongInfo containers are declared, one for each of the players.
Following this we have the variables used within the script which in this case is a single integer variable used to count the number of adverts.
The last section are the variables which the user can use to fine-tune the script, for example, the number of tracks to wait for which in this case is only set to 1. The ShortOffset is used to run the adverts back-to-back. If you find the ends of your adverts are being cut then you should reduce this number.
LongOffset is used to fade the last track to pause before the adverts and again, this should be adjusted to suit the needs of the DJ.
Program Main
Although not annotated in the code, the main section of the code starts when we speed up the processing of the script with PAL.LockExecution.
PAL.LockExecution; // Speed up the Script processing
// Check for the Active Player
Player1 := ActivePlayer; // Assign the Active Player to Player1
If Player1 = DeckB Then Player2 := DeckA; // Assign the Idle Player to Player 2
Player2.pause; // Pause the non-playing deck
PAL.WaitForTime(Float(Now) + ((Player1.Duration - Player1.CurTime - 1500) / 86400000));
Player1.FadeToPause; // Fades the current track LongOffset from the end of the track
With the script processing speed increased we check for the active player and in line with the other scripts provided, we assign the active player to Player1 and the queued player to Player2. This type of naming convention can simplify matters. We could have called them Active and Queued but this changes during the normal running of the script and the queued player will become the active player which might unfortunately then be called Queued.
The queued player (Player2) is paused to prevent anything playing through this player and the script waits for 1500 miliseconds from the end of the playing track before processing resumes. In this case, it uses this 1500 miliseconds to fade out the playing track to a pause.
Playlist Rotation Rules
As this script could potentially play a large number of short adverts in a fairly short period of time, we need to store the current Playlist Rotation Rules and replace them with the shortest rules available, i.e. 1 minute for each category.
// Record the current Playlist Rules in Case they are not default
MinAlTime := PlaylistRules.MinAlbumTime;
MinArTime := PlaylistRules.MinArtistTime;
MinTiTime := PlaylistRules.MinTitleTime;
MinTrTime := PlaylistRules.MinTrackTime;
// Set the Playlist Rules to 1 to account for multiple repeats of short adverts
PlaylistRules.MinAlbumTime := 1; // Sets the minimum Album repeat to 1 minute
PlaylistRules.MinArtistTime := 1; // Sets the minimum Artist repeat to 1 minute
PlaylistRules.MinTitleTime := 1; // Sets the minimum Title repeat to 1 minute
PlaylistRules.MinTrackTime := 1; // Sets the minimum Track repeat to 1 minute
We then assign the value of 1 minute to each category which should enable the adverts to comply with the rules but you should consider the track information as even with these rules, two adverts provided by the same source might have the same artist name and they would not play within 1 minute of each other.
Playing the Adverts
Player3 refers to Aux1 through which the adverts will be played so we raise the volume of this deck to 350 whilst remembering that 255 is the normal volume level.
Then we add the required number of adverts to the top of the queue, reset a counter to zero and play the adverts until the counter does not reach the number of adverts. We could have set the counter to 1 and checked for the counter equaling the number of adverts instead, there is little difference.
We cut the adverts short by the value of ShortOffset and again this can be adjusted to suit your needs.
When the adverts have finished playing we reset the Aux1 volume to the normal level and play the track which was automatically queued in the previously paused deck.
Player3.Volume := LoudVol; // Increase the Player Volume for the Adverts
// Add the required number of adverts to the top of the queue
for AdCount := 1 to AdTotal do
begin
CAT['Advertisements (All)'].QueueTop(smLRP,EnforceRules);
end;
AdCount := 0; // Reset AdCount to 0
// Play the Adverts
while (AdCount < AdTotal) do
begin
P3Track := Queue.NextInQueue;
Player3.QueueSong(P3Track);
Player3.Play;
PAL.WaitForTime(Float(Now) + ((Player3.Duration - Player3.CurTime - ShortOffSet) / 86400000));
AdCount := AdCount + 1;
end; // end for the While loop
// Restore the Normal Volume Level
Player3.Volume := NormalVol; // Restore the normal Player Volume level
Player2.Play; // Play the queued track
Restore the Playlist Rotation Rules
This section simply takes the previously captured Playlist Rotation Rules settings and restores them just in case they were different from the default settings.
// Restore the original Playlist Rules
PlaylistRules.MinAlbumTime := MinAlTime;
PlaylistRules.MinArtistTime := MinArTime;
PlaylistRules.MinTitleTime := MinTiTime;
PlaylistRules.MinTrackTime := MinTrTime;
Housekeeping
With the processing completed for this iteration we just need to return the scripting speed to normal and free up any memory still in use from the track containers.
PAL.UnLockExecution; // Return PAL Script processing to normal speed
// Housekeeping
P1Track.Free;
P2Track.Free;
P3Track.Free;
Comments