Skip to Content
It is currently November 30th, 2021, 1:47 pm

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: October 19th, 2008, 12:58 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
Here is my code...I have the ditties all set and everything, but the PAL always stops on its own when it tries to load. TIA

Code:
{
  Don't be a loser.  Leave this here.

  Category Show script by FesterHead (aka Steve Kunitzer)
  $Id: category-show-v1.pal,v 1.1 2007/12/01 21:49:11 FesterHead Exp $

  What this PAL does:
    * Plays songs from a category

  This is a generic PAL that can be used for many shows.
  My station uses it for the following:
    * Get the Led Out Hour
    * Instrumental Hour
    * Rush Hour
    * Is There Anybody Out There?
    * Guitar Mania!
    * Number 5
    * Entry of the Crims

  In short...  It kicks ass.

  What is configurable:
    * Toggle debug mode (ENABLED BY DEFAULT!)
    * Toggle memory leak warning
    * Database logging table name
    * Show updating title, description, and resets
    * Category to select songs
    * PAL id for automated schedule highlighting
    * Use distinct artists, titles, or title/artists
    * Use SAMs song time limit
    * Use SAMs artist time limit
    * Songtype
    * Show duration
    * Show padding
    * Intro, outro, and middle ditties
    * Number potential candidates to draw from category
    * Number songs between middle ditties

  Schedule this PAL with SAMs Event Scheduler (ES):
    * Switch to a desktop with the ES visible
      OR
      Make the ES visible by clicking the 'Window' menu item and selecting 'Event Scheduler'

    * Click '+' (Add new scheduled event)

    * Enter a name such as 'Category Show'

    * 'Event action' tab:
      * Under 'Action' click 'Execute PAL script'
      * In the 'PAL Script' section, click the folder icon and navigate to this script

    * 'Scheduled times' tab:
      * For a one time event:
        * Select the 'Execute one' button
        * Adjust the date/time
        * Click '+ Add'
        * Repeat as necessary for extra one time events
      * For recurring events:
        * Select the 'Execute every' button
        * Adjust date/time
        * Click '+ Add'

    * Save settings by clicking the 'File' menu item and selecting 'Save Configuration'

  WARNING!
  IF YOU DON'T CONFIGURE THE SCRIPT, DON'T EXPECT IT TO WORK PROPERLY!
  I built this PAL for my station using my station configuration
  Your results and mileage may vary

  I suggest running the PAL in debugOn mode for a couple days to see if it needs tweaking
}

// Make the PAL run fast!
PAL.LockExecution;

{
  **************************
  * START OF CONFIGURABLES *
  **************************
}

{
  Run in debug mode?
  This will write to the screen without any queue interaction
  Useful for testing the script settings
  Don't be a loser.  Test the script with your settings!
  Turns on memory leak warning
}
var debugOn : Boolean = false;

{
  Enable memory leak warning?
  Automatically enabled if debugOn is true
  Stoping then starting a running script will give false memory leak warnings.
  To stop/start do one of the following:
    1.
      a. Add some spaces to the end of a line
      b. Save the script
      c. Compile the script
      d. Run the script
    2.
      a. Remove the script
      b. Add the script
      c. Compile the script
      d. Run the script
}
var memoryLeakAlwaysOn : Boolean = false;

{
  Define automatic show updating values
  No show updating when debugOn is true
}
var text1Update : String = 'Now playing: Metallica, Inc.';
var text2Update : String = 'Playing Metallica songs for an hour';
var text1Reset : String = 'Now playing: Regular schedule';
var text2Reset : String = 'Normal rotation and listener requests';

{
  What is the name of the category?
  TODO: Allow an array of strings for multiple categories
}
var theCategory : String = 'Metallica files';

{
  Database table name for logging show history
  Debug table automatically appended with '_debug'
}
var tableName : String = 'metallica_inc';

{
  Define the PAL ids for automated schedule page highlighting
  No updating when debugOn is true
  Leave this alone if you don't have automated schedule page highlighting
}
var idThisPAL : Integer = 1;
var idResetPAL : Integer = 0;

{
  Use distinct artists?
  If true, then artists won't be duplicated
  Make sure to have enough distinct artists in the category
  Spelling counts!
  Currently case-sensitive!
  One and only one of useDistinctArtists, useDistinctTitles, useDistinctTitleArtists can be true!
}
var useDistinctArtists : Boolean = false;

{
  Use distinct titles?
  If true, then only one song titles won't be duplicated
  Make sure to have enough distinct titles in the category
  Spelling counts!
  Currently case-sensitive!
  One and only one of useDistinctArtists, useDistinctTitles, useDistinctTitleArtists can be true!
}
var useDistinctTitles : Boolean = false;

{
  Use distinct titles by the same artist?
  If true, then the same song title by the same artist won't be duplicated.
  However the same artist may be duplicated!
  Make sure to have enough distinct artists and titles in the category
  Spelling counts!
  Currently case-sensitive!
  One and only one of useDistinctArtists, useDistinctTitles, useDistinctTitleArtists can be true!
}
var useDistinctTitleArtists : Boolean = true;

{
  TODO:  Add integer for artist separation count.
  var artistSepartaion : Integer = 4;

  What this would do is cause a separation before playing the same artist again.
  Could be useful when:
    useDistinctArtists = false
    useDistinctTitles = true or
    useDistinctTitleArtists = true
}

{
  Use SAMs song time limit?
  i.e. don't consider recently played songs
}
var useSongTimeLimit : Boolean = true;

{
  Use SAMs artist time limit?
  i.e. don't consider recently played artists
}
var useArtistTimeLimit : Boolean = false;

{
  What songtypes to select?
  Multiple songtypes not supported at this time
  TODO: Allow an array of strings for multiple song types
}
var songTypeRestrictor : String = 'S';

{
  How long do you want this PAL to run?
  Variable is in minutes
  See padding below
}
var palDuration : Integer = 60;

{
  How much padding (on the + side) to give the script?
  Variable is in minutes
  Instead of trying to fit exactly palDuration minutes, palDuration + palPadding is ok
}
var palPadding : Integer = 10;

{
  How many potential songs to grab?
}
var numberSongsToGrab : Integer = 100;

{
  Define ditty file strings
  Ditties are required
}
var dittyDirectory : String = 'C:\Documents and Settings\Owner\Desktop\Sam Files\';
var dittyStart : String = 'meanzrock3.mp3';
var dittyMiddle : String = 'meanzrock2.mp3';
var dittyEnd : String = 'meanzrock4.mp3';

{
  How many songs to play before adding a middle ditty?
}
var addMiddleDitty : Integer = 3;

{
  Is this cool or what?
  var cool : Boolean = true;
}

{
  ************************
  * END OF CONFIGURABLES *
  ************************
}

// IF YOU EDIT BELOW HERE, MAKE DARN SURE YOU KNOW WHAT'S GOING ON

// Declare data sets
var theSongChooser, currentShow, categoryData : TDataSet;

// Initialize error checker
var hasErrors : Boolean = false;

// Check for intro ditty
if (not FileExists(dittyDirectory + dittyStart)) then
  begin
    ErrorDlg('dittyStart does not exist!');
    hasErrors := true;
  end;

// Check for middle ditty
if (not FileExists(dittyDirectory + dittyMiddle)) then
  begin
    ErrorDlg('dittyMiddle does not exist!');
    hasErrors := true;
  end;

// Check for outro ditty
if (not FileExists(dittyDirectory + dittyEnd)) then
  begin
    ErrorDlg('dittyEnd does not exist!');
    hasErrors := true;
  end;

// Check distinct values
if ((useDistinctArtists and useDistinctTitles) or
    (useDistinctTitles and useDistinctTitleArtists) or
    (useDistinctArtists and useDistinctTitleArtists)) then
  begin
    ErrorDlg('One and only one of useDistinctArtists, useDistinctTitles, useDistinctTitleArtists can be true!');
    hasErrors := true;
  end;

// Initialize duration of show (songs plus ditties)
var duration : Integer = 0;

// Initialize ditty counter
var dittyCounter : Integer = 0;

// Count the actual songs
var theActualCount : Integer = 0;

// SQL restrictions for song and artist
var sqlRestriction : String = '';

if (useSongTimeLimit) then
  begin
    // SQL restriction
    sqlRestriction := 'AND date_played < date_sub(now(), interval ' + IntToStr(PlaylistRules.MinSongTime) + ' minute) ';
   end;

if (useArtistTimeLimit) then
  begin
    // SQL restriction
    sqlRestriction := sqlRestriction + 'AND date_artist_played < date_sub(now(), interval ' + IntToStr(PlaylistRules.MinArtistTime) + ' minute) ';
   end;

// SQL group by
var sqlGroupBy : String = '';

if (useDistinctArtists) then
  begin
    sqlGroupBy := 'GROUP BY songlist.artist ';
  end;

if (useDistinctTitles) then
  begin
    sqlGroupBy := 'GROUP BY songlist.title ';
  end;

if (useDistinctTitleArtists) then
  begin
    sqlGroupBy := 'GROUP BY songlist.title, songlist.artist ';
  end;

// Initialize wait string.  Starts with + because this is a timed wait
var theTimeToWait : String = '+';

// Initialize selections gatherer
var selections : String = '';

var doneGathering : Boolean = false;

// selection pipe
var selectionsPipe : Boolean = false;

PAL.UnlockExecution;

while (not hasErrors) do
  begin
    PAL.LockExecution;

    // Turn on memory leak?
    if (debugOn or memoryLeakAlwaysOn) then
      begin
        PAL.MemoryLeakWarning := true;
        WriteLn('Memory leak warning is ON');
        WriteLn('');
      end;

    // Add end ditty
    if (not debugOn) then
      begin
        Queue.AddFile(dittyDirectory + dittyEnd, ipTop);
      end;

    theActualCount := theActualCount + 1;

    // Determine the category ID
    categoryData := Query('SELECT id FROM category WHERE name = ' + QuotedStr(theCategory), [], true);

    // Get 100 random songs from the category
    theSongChooser := Query('SELECT songlist.id, songlist.filename, songlist.duration, songlist.title, songlist.album, songlist.artist ' +
                            'FROM songlist, categorylist ' +
                            'WHERE songlist.id = categorylist.songid ' +
                            'AND categorylist.categoryid = ' + IntToStr(categoryData['id']) + ' ' +
                            sqlRestriction + ' ' +
                            'AND songlist.songtype = ' + QuotedStr(songTypeRestrictor) + ' ' +
                            sqlGroupBy + ' ' +
                            'ORDER BY RAND() LIMIT ' + IntToStr(numberSongsToGrab), [], true);

    theSongChooser.First;

    while ((duration < (palDuration * 60000)) and (not theSongChooser.EOF)) do
      begin
        if ((duration + theSongChooser['duration']) < ((palDuration + palPadding) * 60000)) then
          begin
            WriteLn(theSongChooser['artist'] + ' *** ' + theSongChooser['title'] + ' ***from*** ' + theSongChooser['album']);

            if (not debugOn) then
              begin
                Queue.AddFile(theSongChooser['filename'], ipTop);
              end;

            theActualCount := theActualCount + 1;

            duration := duration + StrToInt(theSongChooser['duration']);

            // Does selections gatherer need a pipe?
            if (selectionsPipe) then
              begin
                selections := selections + '|';
              end;

            // Build selections gatherer
            selections := selections + IntToStr(theSongChooser['id']);
            selectionsPipe := true;

            // See if we need to put in a ditty
            dittyCounter := dittyCounter + 1;
            if ((dittyCounter = addMiddleDitty) and (duration < (palDuration * 60000))) then
              begin
                dittyCounter := 0;
                if (not debugOn) then
                  begin
                    Queue.AddFile(dittyDirectory + dittyMiddle, ipTop);
                  end;

                theActualCount := theActualCount + 1;
              end;
          end;
        theSongChooser.Next;
      end;

    // Add start ditty
    if (not debugOn) then
      begin
        Queue.AddFile(dittyDirectory + dittyStart, ipTop);
      end;

    theActualCount := theActualCount + 1;

    // Create show history tables
    if (debugOn) then
      begin
        // Create the table if it doesn't already exist
        ExecSQL('CREATE TABLE IF NOT EXISTS ' + tableName + '_debug ' +
                '(id MEDIUMINT(9) AUTO_INCREMENT PRIMARY KEY, ' +
                'date DATETIME, ' +
                'selections TEXT)', []);
        ExecSQL('INSERT INTO ' + tableName + '_debug (date, selections) VALUES (''' +
                FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + ''', ' +
                QuotedStr(selections) + ')', []);
      end
    else
      begin
        // Create the table if it doesn't already exist
        ExecSQL('CREATE TABLE IF NOT EXISTS ' + tableName + ' ' +
                '(id MEDIUMINT(9) AUTO_INCREMENT PRIMARY KEY, ' +
                'date DATETIME, ' +
                'selections TEXT)', []);
        ExecSQL('INSERT INTO ' + tableName + ' (date, selections) VALUES (''' +
                FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + ''', ' +
                QuotedStr(selections) + ')', []);
      end;

    PAL.UnlockExecution;

    // Wait for 1 song to play before starting the show
    WriteLn('');
    WriteLn('Waiting for one song to play before starting the show...');
    if (not debugOn) then
      begin
        PAL.WaitForPlayCount(1);
      end;

    PAL.LockExecution;

    if (not debugOn) then
      begin
        // Create the table if it doesn't already exist
        ExecSQL('CREATE TABLE IF NOT EXISTS currentshow ' +
                '(id MEDIUMINT(9), text1 VARCHAR(255), text2 VARCHAR(255))', []);

        currentShow := Query('SELECT COUNT(*) AS cnt FROM currentshow', [], true);

        // If no rows in currentshow, do an insert
        // Else, do an update
        if (currentShow['cnt'] = 0) then
          begin
            ExecSQL('INSERT INTO currentshow (id, text1, text2) ' +
                    'VALUES (' + IntToStr(idThisPAL) + ', ' + QuotedStr(text1Update) + ', ' +
                                 QuotedStr(text2Update) + ')', []);
          end
        else
          begin
            ExecSQL('UPDATE currentshow SET id = ' + IntToStr(idThisPAL), []);
            ExecSQL('UPDATE currentshow SET text1 = ' + QuotedStr(text1Update), []);
            ExecSQL('UPDATE currentshow SET text2 = ' + QuotedStr(text2Update), []);
          end;
      end;

    PAL.UnlockExecution;

    // Wait for the show to end
    WriteLn('Waiting for ' + IntToStr(theActualCount) + ' songs to play before ending the show...');
    WriteLn('');
    if (not debugOn) then
      begin
        PAL.WaitForPlayCount(theActualCount);
      end;

    PAL.LockExecution;

    if (not debugOn) then
      begin
        ExecSQL('UPDATE currentshow SET id = ' + IntToStr(idResetPAL), []);
        ExecSQL('UPDATE currentshow SET text1 = ' + QuotedStr(text1Reset), []);
        ExecSQL('UPDATE currentshow SET text2 = ' + QuotedStr(text2Reset), []);
      end;

    // Not really an error, but we're pau with the show
    hasErrors := true;

    PAL.UnlockExecution;
  end;

WriteLn('');
WriteLn('Show pau');

theSongChooser.Free;
categoryData.Free;
currentShow.Free;
Queue.Free;


Last edited by Elevatorboy on October 19th, 2008, 4:08 pm, edited 1 time in total.
Added code tags to improve readbility


Top
 Profile  
Reply with quote  
PostPosted: October 19th, 2008, 1:33 pm 
Offline
SVS Member
SVS Member

Joined: May 8th, 2004, 9:00 am
Posts: 10551
Location: Denver, CO
On what line does the script just 'stop' as you have stated?

_________________
- Rob Oyler, SVS
Image


Top
 Profile  
Reply with quote  
PostPosted: October 19th, 2008, 2:52 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
It seems to stop around here:
WriteLn('');
WriteLn('Show pau');

Also it says:

Error: Invalid variant type conversion
Error: Access violation at address 00564D5B in module 'SAMBC.exe'. Read Of Address 00000001


Top
 Profile  
Reply with quote  
PostPosted: October 19th, 2008, 2:55 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
Every time I start the script it puts in the dittystart and dittyend mp3s right away into the queue.


Top
 Profile  
Reply with quote  
PostPosted: October 20th, 2008, 8:15 am 
Offline
SVS Member
SVS Member

Joined: May 8th, 2004, 9:00 am
Posts: 10551
Location: Denver, CO
Do some detective work, comment out the Pal.LockExecution and unlockexecution. Run the script line-by-line and see where the problem is.

_________________
- Rob Oyler, SVS
Image


Top
 Profile  
Reply with quote  
PostPosted: October 20th, 2008, 6:15 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
Ok...I went with the code form the wiki...1st the code:

Code:

// Don't be a dick.  Leave this here.
// Artist hour script by FesterHead (fester@festerhead.com)
// Version 1.0 05/21/2003
//
// Plays an hour of an artist

// Declare variables
var theSongChooser : TDataSet;
var duration : Integer;
var theArtist, theShow : String;

// Keep da bugger goin!
PAL.Loop := True;

// Wait for the designated time
if ((now >= T['18:30:00']) and (now <= T['18:30:30']) and (DayOfWeek(Now) = Wednesday)) or
  ((now >= T['20:00:00']) and (now <= T['20:00:30']) and (DayOfWeek(Now) = Friday)) then
 begin
   if (DayOfWeek(Now) = Tuesday) then
     begin
       theArtist := 'Metallica';
       theShow := 'Metallica, Inc.';
     end;
   if (DayOfWeek(Now) = Friday) then
     begin
       theArtist := 'Kiss';
       theShow := 'Hour From The Elder';
     end;

   WriteLn('Starting ' + theArtist + ' hour PAL script...');
  WriteLn();

   theSongChooser := Query('select *' +
     ' from songlist' +
     ' where artist = ' + QuotedStr(theArtist) +
     ' and songtype = S' +
     ' order by rand() limit 100',[],True);

   duration := 0;

   theSongChooser.First;

   while not theSongChooser.EOF do
     begin
       if ( (duration + theSongChooser['duration']) < 4200000 ) then
         begin
           WriteLn(theSongChooser['title'] + ' *from* ' + theSongChooser['album']);
           Queue.AddFile(theSongChooser['filename'], ipTop);
           duration := duration + theSongChooser['duration'];
         end;
       theSongChooser.Next;
     end;

   theSongChooser.Free;
   // Let's wait for two songs to play...  just in case
   PAL.WaitForPlayCount(2);
end;*** PAL END ***


My error now is (this here - WriteLn();):

Code:
syntax error: more arguments expected! (line 33, column 4)


Top
 Profile  
Reply with quote  
PostPosted: October 20th, 2008, 7:23 pm 
Offline
SVS Member
SVS Member

Joined: May 8th, 2004, 9:00 am
Posts: 10551
Location: Denver, CO
Change it to this
Code:
WriteLn('');
that is '' (two apostrophe's).

_________________
- Rob Oyler, SVS
Image


Top
 Profile  
Reply with quote  
PostPosted: October 22nd, 2008, 11:39 am 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
I did that and it displays compiler error, but the pal keeps bbouncing back from the start time of the Wednesday hour to the beginning of the Pal.

Do I need anything else for this pal? Just wondering if I needed some software or something.


Top
 Profile  
Reply with quote  
PostPosted: October 22nd, 2008, 2:09 pm 
Offline
SVS Member
SVS Member

Joined: May 8th, 2004, 9:00 am
Posts: 10551
Location: Denver, CO
What line does the compiler report as a problem?

_________________
- Rob Oyler, SVS
Image


Top
 Profile  
Reply with quote  
PostPosted: October 22nd, 2008, 3:17 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
It just keeps bouncing back and forth here at the beginning:

PAL.Loop := True;

// Wait for the designated time
if ((now >= T['15:02:00']) and (now <= T['15:02:30']) and (DayOfWeek(Now) = Wednesday)) or


Top
 Profile  
Reply with quote  
PostPosted: October 22nd, 2008, 8:46 pm 
Offline
Alumni
Alumni

Joined: March 11th, 2003, 1:34 pm
Posts: 9959
Location: Maui, HI
meanzrock wrote:
It just keeps bouncing back and forth here at the beginning

Unless the time falls between the range then yes, it will bounce between.
In other words, if it's not time to run it won't run.

Code:
end;*** PAL END ***

That can't be good. Trim the *** PAL END ***

RE: The latest unsupported category show from my FHR 1.x collection:
I don't recall any invalid variant conversions but this is generally caused by using a non-String value as a String without casting it.

This is ported over to the FHR 2.x PALs by way of a controller and show PAL combo that fills and plays the category respectively.

_________________
- Steve Kunitzer
- SVS (Spacial Volunteer Support) / Forum Administrator

Image
Image


Top
 Profile  
Reply with quote  
PostPosted: October 23rd, 2008, 2:57 pm 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
Ok..I have been doing everything you guys have said. Now it stops on:

Code:
 theSongChooser.First;


and bounces back and forth from here

Code:
and PAL.Loop := True;


The compiler error at the bottom reads

Code:
error access violation at address 00564D5B in module 'SAMBC.exe'.  Read of address 00000001


Top
 Profile  
Reply with quote  
PostPosted: October 24th, 2008, 6:45 am 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
This section here:
Code:
var text1Update : String = 'Now playing: Metallica, Inc.';
var text2Update : String = 'Playing Metallica songs for an hour';
var text1Reset : String = 'Now playing: Regular schedule';
var text2Reset : String = 'Normal rotation and listener requests';

{
  What is the name of the category?
  TODO: Allow an array of strings for multiple categories
}
var theCategory : String = 'Metallica files';

{
  Database table name for logging show history
  Debug table automatically appended with '_debug'
}
var tableName : String = 'metallica_inc';


I assumed this pal was creating tables? And also I have everything right now in one category. Do I need to create a Metallica category? I also assumed it looked up all of the Metallica related songs. Other than this I can't figure out what is wrong.


Top
 Profile  
Reply with quote  
PostPosted: October 24th, 2008, 8:17 am 
Offline
SVS Member
SVS Member

Joined: May 8th, 2004, 9:00 am
Posts: 10551
Location: Denver, CO
Your assumptions are incorrect. The PAL assumes you already have a category called "Metallica files" spelled just as you have typed it in, it does not look up Metallica related songs it only looks for tracks in that category and while it does create db tables they are only used for historical purposes.

_________________
- Rob Oyler, SVS
Image


Top
 Profile  
Reply with quote  
PostPosted: October 24th, 2008, 8:32 am 
Offline
Experienced User
Experienced User

Joined: October 12th, 2008, 2:10 pm
Posts: 283
Thanks Rob...a big learning curve here :oops:


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 19 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group