Note that this Wiki is a work in progress, items may not be updated or may disappear entirely as the pages are updated.
Different Rules for Requests than for PAL queued songs
From SpacialAudio
The goals of my script are..
1. To maintain 2 different sets of rules for how often songs and artists can repeat: Hourly, if a song is requested. But much longer for songs selected by script instead of requested.
2. To give requests priority over script selected songs: My script will NOT select a song and add it to the bottom of the queue unless the queue duration has slipped below 1 hour. If enough requests keep coming in to maintain the 1 hour queue, the script won't add any songs.
3. To ensure that requests are not played until an hour has passed.
4. To eliminate request rejects for "recently played".
5. To change the number of requests allowed per listener per hour, based on the number of current listeners: Fewer listeners means more requests permitted. More listeners means fewer requests permitted.
6. To help vary the song selections that this script makes (when requests aren't enough to maintain the 1 hour queue): Random numbers are used in PAL to change the values of Artist Repeat and Song Repeat rules. Each time the script selects and queues a song, it uses 1 of many different rules combinations that I've defined in PAL.
My PAL script ensures that my queue always contains a minimum of 1 hour of songs. I have all incoming requests sent to the bottom of my queue immediately, with the 1 hour queue serving as the required 1 hour delay before a request can be played.
My PAL script manipulates the settings for the number of minutes before a repeat artist or song is allowed: When requests are coming in, the rules are set to 0 minutes - because the 1 hour queue provides the necessary wait time all by itself. For songs selected for play by my script, as opposed to by request, the repeat rules are set to much higher values.
If 'Gloria' by U2 plays at 1 PM, and you request it at 1:05 PM, the request is accepted and goes to the bottom of the queue and will play at approx. 2:05 PM. If no requests are made for U2, my script won't select other U2 songs for 5 hours (maybe much longer, depending on the various possibilities in the PAL script) and it won't select 'Gloria' again for a long time.
Of course, you can use parts of my PAL script that suit you if you don't want to implement the whole thing. If you do plan to run the entire script effectively, you'll need to do these 3 things at a minimum:
1. In the SAM2 GUI, set your request policy so that all requests are sent to the bottom of your queue immediately.
2. In the SAM2 GUI, set it to run songs from your Queue (instead of Auto DJ or Manual DJ modes)
3. In the PAL Script, edit the section where song categories are listed. The script shows generic categories like 'Alternative', 'Soul', etc. You'll need to replace those category names with your own SAM2 song category names.
You may download the script here. http://spacialaudio.com/knowledge/attachment.php?attId=84 (retrieved from archive.org below)
// ENSURE THAT THE SCRIPT RUNS CONTINUOUSLY
PAL.Loop := True;
// DECLARE THE VARIABLES
var QueueTime: Integer = (60*60*1000); // SET THE VALUE OF QUEUETIME AS 1 HOUR
var myCategory : String;
var myCriteria : Integer;
var minutesRepeatSong : Integer;
var minutesRepeatArtist : Integer;
//=======================================
// DYNAMIC REASSIGNMENT OF REQUEST LIMITS
// WE ARE GOING TO SET A LIMIT ON REQUESTS PER PERSON
// PER HOUR, SO WE'LL ASSIGN A VALUE OF 60 (MINUTES)
// TO THE LIMITINTERVAL PROPERTY.
RequestPolicy.LimitInterval := 60;
// GET THE COUNT OF CURRENT LISTENERS, AND USE THAT
// COUNT TO DECIDE HOW MANY REQUESTS PER HOUR
// WE'LL PERMIT PEOPLE TO MAKE.
PAL.LockExecution;
Case (Relays[0].Viewers) of
1: // IF 1 LISTENER, PERMIT 10 REQUESTS PER PERSON PER HOUR
begin
RequestPolicy.Limit := 10;
end;
2: // 2 LISTENERS, 8 REQUESTS PER PERSON
begin
RequestPolicy.Limit := 8;
end;
3: // 3 LISTENERS, 6 REQUESTs PER PERSON
begin
RequestPolicy.Limit := 6;
end;
4: // 4 LISTENERS, 4 REQUESTS PER PERSON
begin
RequestPolicy.Limit := 4;
end;
5..6: // 5 OR 6 LISTENERS, 3 REQUESTS PER PERSON
begin
RequestPolicy.Limit := 3;
end;
7..9: // 7 TO 9 LISTENERS, 2 REQUESTS PER PERSON
begin
RequestPolicy.Limit := 2;
end;
Else // NO LISTENERS, OR 10 + LISTENERS, 1 REQUEST PER PERSON
begin
RequestPolicy.Limit := 1;
end;
End;
PAL.UnlockExecution;
//=======================================
// CHECK THE DURATION OF THE CURRENT QUEUE
// ONCE EVERY MINUTE, WE'LL CHECK THE DURATION OF THE QUEUE
// (THE TOTAL TIME OF ALL QUEUED SONGS).
// IF THERE'S LESS THAN 1 HOUR OF SONGS QUEUED, WE'LL
// ADD A SONG TO THE BOTTOM OF THE QUEUE.
// IF THERE'S 1 HOUR OF SONGS (OR MORE) ALREADY IN
// THE QUEUE, WE'LL DO NOTHING AND THEN CHECK
// AGAIN IN 1 MINUTE.
While Queue.Duration > QueueTime Do
Pal.WaitForTime('+00:01:00');
//=======================================
// THE FOLLOWING INTEGER VALUES FOR SONG SELECTION LOGIC
// COME FROM THE PAL HELP DOCUMENTATION.
// smWeighted = 0 Song with lowest balance
// smPriority = 1 Song with highest priority (Weight)
// smRandom = 2 Totally random selection
// smMRP = 3 Most recently played song
// smLRP = 4 Least recently played song
// smMRPA = 5 Most recently played artist
// smLRPA = 6 Least recently played artist
// smLemmingLogic = 7 Random logic chooser
// I USE 5 OF THOSE 8 ITEMS, YOU CAN USE AS MANY AS YOU LIKE.
// I DO NOT USE THE 2 'MOSTRECENTLYPLAYED' ITEMS NOR THE
// LEMMINGLOGIC ITEM.
// SO HERE ARE THE 5 THAT I PUT TO USE, BELOW:
// smWeighted = 0 Song with lowest balance
// smPriority = 1 Song with highest priority (Weight)
// smRandom = 2 Totally random selection
// smLRP = 4 Least recently played song
// smLRPA = 6 Least recently played artist
// THE NEXT BLOCK OF CODE WILL CHOOSE 1 OF THOSE 5
// LOGIC METHODS, VIA RANDOM NUMBER, AND IT WILL POPULATE
// THE 'myCriteria' VARIABLE WITH THE LOGIC METHOD THAT WAS
// RANDOMLY SELECTED FOR USE.
//=======================================
// GET A RANDOM NUMBER FROM 1 TO 20, AND USE THE
// RANDOM NUMBER TO SELECT THE SAM2 LOGIC TO USE
// WHEN THIS SCRIPT SELECTS A SONG TO QUEUE
PAL.LockExecution;
Randomize;
// GET RANDOM NUMBER FROM 1 TO 20
case (RandomInt(20) + 1) of
1..2:
begin
myCriteria := 0; // RANDOM NUMBER IS 1 OR 2, USE smWeighted
end; // (in the table above, smWeighted is zero)
3..4:
begin
myCriteria := 1; // RANDOM NUMBER IS 3 OR 4, USE smPriority
end;
5..9:
begin
myCriteria := 2; // RANDOM NUMBER IS 5 THRU 9, USE smRandom
end;
10..17 :
begin
myCriteria := 4; // RANDOM NUMBER IS 10 THRU 17, USE smLRP
end;
18..20 :
begin
myCriteria := 6; // RANDOM NUMBER IS 18 THRU 20, USE smLRPA
end;
end;
// AT THIS POINT, THE myCriteria VARIABLE CONTAINS THE NUMBER
// THAT CORRESPONDS TO A SAM2 LOGIC METHOD THAT WE ARE GOING
// APPLY WHEN WE QUEUE A SONG
//=======================================
//DETERMINE WHICH CATEGORY TO PULL A SONG FROM
// GENERATE A NEW RANDOM NUMBER.
// USE THE RANDOM NUMBER TO CHOOSE A SAM2 SONG CATEGORY.
// YOU'LL HAVE TO SUBSTITUTE YOUR OWN SAM2 CATEGORY
// NAMES HERE.
case (RandomInt(56) + 1) of
1..10 :
begin
myCategory := 'Alternative';
end;
11..20 :
begin
myCategory := 'Metal';
end;
21..30 :
begin
myCategory := '70s';
end;
31..40 :
begin
myCategory := '80s';
end;
41..48 :
begin
myCategory := '60s';
end;
49..54 :
begin
myCategory := 'Soul';
end;
55..56 :
begin
myCategory := 'Punk';
end;
end;
// AT THIS POINT, THE myCategory VARIABLE CONTAINS THE
// NAME OF THE SAM2 CATEGORY THAT WE ARE GOING TO
// PULL 1 SONG FROM
//=======================================
// WE'LL TEMPORARILY SET VALUES FOR TIME LIMITS ON
// REPEAT SONGS AND ARTISTS, FOR JUST A SPLIT-SECOND:
// JUST LONG ENOUGH TO SELECT ONE SONG TO QUEUE, THEN
// WE'LL RESET THE RULES TO WHAT WE WANT FOR REQUESTS.
// THEREFORE, THE SONG THAT WE ARE ABOUT TO SELECT AND SEND
// TO THE BOTTOM OF THE QUEUE WILL MEET STRICTER RULES THAN
// THE SONGS REQUESTED BY LISTENERS.
// TO HELP VARY THE SONG SELECTION, WE'LL USE RANDOM NUMBERS
// TO DETERMINE WHICH VALUES TO USE FOR OUR RULES.
//=======================================
// USE A NEW RANDOM NUMBER TO DETERMINE HOW OFTEN WE'LL LET
// ARTISTS REPEAT
// GET RANDOM NUMBER FROM 1 TO 4
case (RandomInt(4) + 1) of
1..2 :
begin // RANDOM NUMBER = 1 or 2
minutesRepeatArtist := 300; // 5 Hours before Artist repeat
end;
3:
begin // RANDOM NUMBER = 3
minutesRepeatArtist := 600; // 10 Hours before Artist repeat
end;
4:
begin // RANDOM NUMBER = 4
minutesRepeatArtist := 900; // 15 Hours before Artist repea
end;
end;
//=======================================
// USE A NEW RANDOM NUMBER TO DETERMINE HOW OFTEN WE'LL LET
// A SONG REPEAT
// GET RANDOM NUMBER FROM 1 TO 7
case (RandomInt(7) + 1) of
1:
begin
// Song repeat = Artist Repeat time multiplied by 2
// (if Artist Repeat is 300: Song Repeat will be 600)
// (if Artist Repeat is 600: Song Repeat will be 1200)
// (if Artist Repeat is 900: Song Repeat will be 1800)
minutesRepeatSong := (minutesRepeatArtist * 2);
end;
2:
begin
// Song repeat = Artist Repeat time multiplied by 3
minutesRepeatSong := (minutesRepeatArtist * 3);
end;
3:
begin
// Song repeat = Artist Repeat time multiplied by 4
minutesRepeatSong := (minutesRepeatArtist * 4);
end;
4:
begin
// Song repeat = Artist Repeat time multiplied by 5
minutesRepeatSong := (minutesRepeatArtist * 5);
end;
5:
begin
// Song repeat = Artist Repeat time multiplied by 6
minutesRepeatSong := (minutesRepeatArtist * 6);
end;
6:
begin
// Song repeat = Artist Repeat time multiplied by 7
minutesRepeatSong := (minutesRepeatArtist * 7);
end;
7:
begin
// Song repeat = Artist Repeat time multiplied by 10
minutesRepeatSong := (minutesRepeatArtist * 10);
end;
end;
//=======================================
// SINCE WE'VE JUST FIGURED OUT WHICH VALUES TO USE FOR
// THE SONG & ARTIST REPEAT RULES, AND WE'VE PLACED THOSE
// VALUES INTO VARIABLES.... WE'LL NOW USE THE VALUES OF THE
// VARIABLES TO SET THE RULES
PlaylistRules.MinSongTime := minutesRepeatSong;
PlaylistRules.MinArtistTime := minutesRepeatArtist;
//=======================================
// ADD A SONG TO THE BOTTOM OF THE QUEUE.
// WE CHOOSE THE SONG USING THE LOGIC, CATEGORY,
// AND RULES THAT WE SELECTED EARLIER IN THIS
// SCRIPT (VIA RANDOM NUMBERS)
CAT[myCategory].QueueBottom(myCriteria,EnforceRules);
//=======================================
// NOW THAT WE'VE JUST QUEUED A SONG, WE'LL RESET THE RULES
// SO ALL REQUESTS WILL HAVE THE FOLLOWING RULES APPLIED
// (INSTEAD OF THE RULES USED ABOVE).
// THE FOLLOWING RULES WILL APPLY FOR ALL REQUESTS, AND
// ONLY FOR REQUESTS!
PlaylistRules.MinArtistTime := 0; // # of minutes before Artist repeat
PlaylistRules.MinSongTime := 0; // # of minutes before Song repeat
// THE 1 HOUR QUEUE THAT WE MAINTAIN AT ALL TIMES WILL
// SERVE AS OUR NO-REPEAT RULE, SO ITS OK TO SET RULES
// TO = 0 MINUTES.
// REQUESTS FOR ARTISTS ALREADY QUEUED WILL BE REJECTED
// BY THE REQUEST SYSTEM. WITH THOSE REJECTIONS PREVENTING
// ANY REPEATS WITHIN AN HOUR, WE DON'T NEED ANY RULES TO
// HANDLE THE REQUESTS. WE NEED RULES ONLY
// WHEN THIS SCRIPT IS SELECTING SONGS, AS OPPOSED TO
// LISTENERS REQUESTING SONGS.
PAL.UnlockExecution;
