RadioFreeMonkey 1.2

Post a reply

Smilies
:D :) :( :o :-? 8) :lol: :x :P :oops: :cry: :evil: :roll: :wink:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: RadioFreeMonkey 1.2

Re: RadioFreeMonkey 1.2

by imagehopper » Tue Mar 19, 2013 2:06 am

Is this going to work in mm4?

Re: RadioFreeMonkey 1.2

by wishmaster » Wed Feb 01, 2012 7:36 am

I need this in MM4 also

Re: RadioFreeMonkey 1.2

by anonym... » Fri Jun 10, 2011 5:38 pm

WANT THIS IN MM4!

Re: RadioFreeMonkey 1.2

by front243 » Wed Oct 27, 2010 12:08 pm

Thanks. I found the Auto DJ RadioFreeMonkey script and its working perfectly :D

Re: RadioFreeMonkey 1.2

by nohitter151 » Mon Oct 25, 2010 8:58 am

This script was written for MediaMonkey version 2, I assume it isn't compatible with the latest version of MM.

Re: RadioFreeMonkey 1.2

by front243 » Mon Oct 25, 2010 7:44 am

Hi, I am all new to using MediaMonkey and this is the first script I got so I hope you can help me:

1. I have modified none of the variables in RadioFreeMonkey, and have installed the latest version a few messages up from this.
2. All my tracks are new except for a few I played and rated already.
3. The played and rated tracks appear correctly in the "Done" tab.
4. All my other unplayed tracks appear under "Weightings->3.0"
5. No tracks appear under the main "Radio List".
6. I have installed MediaMonkey less than a day ago so I assume the age parameters don't kick in yet.

What do I need to modify in order to have the unplayed tracks appear in the playlist? (I assume that is the "Radio List")

I confess to terminal idiocy...

by soundbyte » Sun Feb 03, 2008 2:18 am

I can't get Version 1.8.0 to work with MM3. I've copied the scrips, saved it as a vbs file and placed it in the \scripts\auto folder. "Radio Free Monkey 1.8.0" appears under library, but is totally non-functional.

by Tylast » Sat Feb 02, 2008 3:54 pm

Thanks! :D

by popper » Sat Feb 02, 2008 3:46 pm

Tylast wrote:Ohhh, it would be so nice if there were a way to edit the excluded genres as an option instead of me trying to find the genre numbers. 8)
I assume that you are using the version 1.8.0 with MM3? Then you don't have to look up genre numbers any more (the explanation in the comment is outdated). Instead, they are configured as plain text now. Look at this:

Code: Select all

Const NotPlayGenres = "'Speech'" 
You can add more genres by just adding to this list, like so:

Code: Select all

Const NotPlayGenres = "'Speech','Jazz','Soundtrack'" 
cheers,
popper.

by Tylast » Sat Feb 02, 2008 8:17 am

Ohhh, it would be so nice if there were a way to edit the excluded genres as an option instead of me trying to find the genre numbers. 8)

by D!m » Sat Jan 19, 2008 11:07 am

Here is a version that work with MM3

Code: Select all

' RadioFreeMonkey
' Version 1.8.0
' A script to create a "radio station" for you based on your song ratings.

' #####################
' Version 1.2 by Risser

' This script creates a root node in the tree, beneath the library node, called "RadioFreeMonkey".
' Under this node, you have a Radio List node, a Done node and a Weightings node.
' - The Radio List node lists 20 songs, in random order. These are weighted, so songs
' with a higher weighting have a higher chance of getting selected.
' - If you have selected a sorting column, even though the songs are selected randomly, the
' radio list will be sorted based on that column. To return the list to "random" sorting, click
' on any playlist (Now Playing works nicely). When you visit the Radio List node, the songs will
' be unsorted, in true random order.
' - The Done list shows you which songs aren't going to be played. This includes songs that have
' passed their maximum playcount, or anything within MinDaysRepeat.
' - The Weighting node shows all tunes, sorted by their calculated weights. This can help you
' determine what the optimal weighting choices are for you. Plus, it's just nice to see what's
' more likely to be played.

' Songs are weighted as follows:
' Rating * 2 (5 stars = 10, 3.5 stars = 7, 0 stars = 0)
' - Number of Plays (if Reduce if Played is TRUE)
' + Days since added to library / DayFactor (always rounded down)
' However, the weighting can't be more than the original rating (* 2).

' TO DO: At some point, I'd like to make the main 'list' node a PlayList instead of a regular
' list of tracks, but I'm not sure how to do this.
'
' This script can be freely used and modified.
' This is an early release and there may be bugs. If it's causing you problems, simply delete
' it or move it out of the scripts\auto folder.
'
' The script does not modify the database, registry or INI file.

' #####################
' Version 1.5 by popper

' - added possibility to boost songs that have been added to the DB recently
' - added possibility to define the genres that should be played
' - redesign of the mechanism that selects the actual songs to be played (because I did not
'   really understand what was going on in the existing algorithm ;-), with the goal of making
'   it easier to influence what will be played (e.g. 30% of songs with a weighting of 8-10 and
'   70% with a weighting of 5-7))
' #####################
' Version 1.6 by ElGringo

' - Fixes to the algorithm
'   - 1. There was always a song that had nothing to do in my playlists, investigated
'        and saw the error in FillGoodLeaf
'   - 2. There is an error in the calculation of the dateboost formula, the
'        dateboostcutoff*20 should be dateboostcutoff*10. There were a couple of places wrong
'   - 3. By adding, the BoostNewSongsModifier, the actual weight calculated, could go higher
'        than 10, but the algorithm was never picking songs with a weight higher than 10. So,
'        i fixed a couple of places in the script, so that calculated weight higher than 10,
'        are now fixed at 10.
'   - 4.There was a bug, when the BoostNewSongsModifier is set to 0... fixed it.
'
'
'
' #####################
' Version 1.6.1 by popper

' - In my opinion, the dateboostcutoff*20 (point 2. from ElGringo's list above) was correct
'   ("Please correct me if I am wrong, but the ratings are stored in the database using
'    numbers from 0 (or -1) to 100. So to calculate the number of stars from a rating in
'    the database, you have to divide by 20, and not by ten.")
'   So I changed it back in this release.
'   No other modifications made. ElGringo was right in all other points ;-)
'
'
' #####################
' Version 1.7 by RedX
'
' - Improvements to the algorithm
'  1. I have replaced all looping with SQL access statements improving overall query time and
'     and IMHO readabilty of the code
'  2. Added option to improve weights of songs with low played count especially one  that have not yet
'      been heard at all but are old in the db, old means longer then boostnewsongsdays
'  3. Added check for SetXPercentage and numberofsongs
'  My modifications are restricted to FillGoodLeaf and adding a new Formula in the general section
'
'
' #####################
' Version 1.7.1 by D!m
'
' - Fix some bugs
'  1. BoostNewSongs now work with unrated songs.
'  2. Song with a weight higher than 10 are now fixed at 10.
'  3. Option genres that should not be played now work.
'
'
' #####################
' Version 1.8.0 by D!m
'
' - MediaMonkey v3 compatible
'
'
'
' Disclaimer:
' Use at your own risk. Back up your data before using.
' Changing some of the values might lead to endless loops that can only be solved by
' killing the MediaMonkey process, so take care when modifying anything!

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' Global Variables and Declarations
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Option Explicit

' %%% The caption for the root node.
Const RootNodeCaption = "Radio FreeMonkey 1.8.0"

' %%% Add 1 to weighting for each X days since added to library
Const DayFactor = 20

' %%% Anything rated this or below will not receive the 'date boost'
Const DateBoostCutoff = 1.5

' %%% The minimum number of days that must pass before a song is repeated. Zero means, go ahead
' and repeat it right away.
Const MinDaysRepeat = 1

' %%% Reduce the weighting by the number of times played. This means, as songs are played more often,
' they are less likely to be played again
Const ReduceIfPlayed = True

' %%% Boost Songs that have been added during the last n days (MinDaysRepeat does still apply for these)
Const BoostNewSongsDays = 30

' %%% The boost modifier for new songs (Zero means, don't boost):
' Add x to the weighting of these songs
Const BoostNewSongsModifier = 3

' %%% Anything rated this or below will not receive the 'new song boost'
Const BoostNewSongsCutoff = 1.5

' %%% Tracks that have not been heard yet and have not been recently added receive this bonus (Dateadded > BoostNewSongsDays)
Const BoostNotPlayedModifier=5
'Const BoostNotPlayedModifier=0

' %%% Limit for the not heard Bonus, 0 means only songs u never played get the bonus
Const BoostNotPlayedCutoff=0

' %%% Boost not rated songs (problem is bomb = not rated = rating -1)
Const BoostNotPlayedNotRated=True
'Const BoostNotPlayedNotRated=False

' %%% In case some of the non played songs have a rating do not pick songs with ratings below (0 to 10)
' %% 2 = 20=1 star 4=40=2 stars
Const BoostNotPlayedRatingCutoff=5

' %%% Genres that should not be played. Leave empty (Const NotPlayGenres = "") to ignore.
' "-1, 13, 17, 20, 24" means "empty genre field, Pop, Rock, Alternative, Soundtrack"
' Look up the other genre Ids in the database by using MS Access
Const NotPlayGenres = "'Speech'"

' %%% Number of Songs in list
Const NumberOfSongs = 25


' %%% Influence which songs will be played. You have three sets that you can use
' Example:
' Const Set1Weight = 8.5    ' Basic weight for this set is 8.5
' Const Set1Boundary = 1.5  ' with a variation of 1.5, which means that songs between 7 and 10 will be chosen
' Const Set1Percentage = 60 ' this is how big the part of this set should be in the overall contents

Const Set1Weight = 7.0
Const Set1Boundary = 3
Const Set1Percentage = 90    ' make sure all 3 percentages sum up to 100!

Const Set2Weight = 2.0
Const Set2Boundary = 2
Const Set2Percentage = 10   ' make sure all 3 percentages sum up to 100!

Const Set3Weight = 1.0      ' Right now, it is not possible to choose songs with a weight < 1, so unfortunately you cannot add unrated songs
Const Set3Boundary = 1
'Const Set3Percentage = 20  ' This is not needed because it just takes what is missing to 100%


'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' The Meat. Don't change anything under here.
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

' the text of the formulas to be used throughout
Dim weightedRatingFormula, dateBoostFormula, ratingFormula, weightedPlayCountFormula, boostNewSongsFormula, boostNotPlayedFormula

If BoostNewSongsModifier <> 0 Then
        If (CurrentVersion() < 300) then
                dateBoostFormula = "IIF(Songs.rating <= " & (BoostNewSongsCutoff *10) & " OR FIX(DateDiff('d',Songs.DateAdded,Now) <= " & BoostNewSongsDays &  "), 0, FIX(DateDiff('d',Songs.DateAdded,Now) / " & DayFactor & "))"
        Else
                dateBoostFormula = "(CASE WHEN ( (Songs.rating <= " & (BoostNewSongsCutoff *10) & ") OR ((julianday('Now') - julianday('1899-12-30') - Songs.DateAdded) <= " & BoostNewSongsDays &  ")) Then 0 Else ((julianday('Now') - julianday('1899-12-30') - Songs.DateAdded) / " & DayFactor & ") END)"

        End if
Else
        If (CurrentVersion() < 300) then
                dateBoostFormula = "IIF(Songs.rating <= " & (DateBoostCutoff*10) & ", 0, FIX(DateDiff('d',Songs.DateAdded,Now) / " & DayFactor & "))"
        Else
                dateBoostFormula = "(CASE WHEN (Songs.rating <= " & (DateBoostCutoff*10) & ") Then 0 Else (julianday('Now') - julianday('1899-12-30') - Songs.DateAdded)/ " & DayFactor & " END)"
        End if
End If

'If the songs played MORE then x times OR Songs' shorter then X days in DB or rating below X then RETURN 0 ELSE is ok
If BoostNotPlayedModifier > 0 then
        if boostnotplayednotrated=true Then
                If (CurrentVersion() < 300) then
                        boostNotPlayedFormula= " IIF((Songs.PlayCounter >" & BoostNotPlayedCutoff & " OR FIX(Datediff('d',Songs.DateAdded,Now))<" & BoostNewSongsDays & " OR (Songs.rating<"& boostnotplayedratingcutoff*10 & " AND songs.rating <> -1)),0,"& BoostNotPlayedModifier &") "
                Else
                        boostNotPlayedFormula= " (CASE WHEN ((Songs.PlayCounter >" & BoostNotPlayedCutoff & ") OR (julianday('Now') - julianday('1899-12-30') - Songs.DateAdded <=" & BoostNewSongsDays & ") OR ((Songs.rating<"& boostnotplayedratingcutoff*10 & ") AND songs.rating <> -1)) Then 0 Else "& BoostNotPlayedModifier &" END) "
                End if
        Else
                If (CurrentVersion() < 300) Then
                        boostNotPlayedFormula= " IIF(Songs.PlayCounter >" & BoostNotPlayedCutoff & " OR FIX(Datediff('d',Songs.DateAdded,Now))<" & BoostNewSongsDays & " OR Songs.rating<"& boostnotplayedratingcutoff*10 & ",0,"& BoostNotPlayedModifier &") "
                Else
                        boostNotPlayedFormula= " (CASE WHEN ((Songs.PlayCounter >" & BoostNotPlayedCutoff & ") OR ((julianday('Now') - julianday('1899-12-30') - Songs.DateAdded)<" & BoostNewSongsDays & ") OR (Songs.rating<"& boostnotplayedratingcutoff*10 & ")) Then 0 Else "& BoostNotPlayedModifier &" END) "
                End If
   end if
end if

If (CurrentVersion() < 300) Then
        ratingFormula = "(IIF(Songs.rating < 0, 0, Songs.rating) / 10)"
Else
        ratingFormula = "((CASE WHEN (Songs.rating < 0) Then 0 Else Songs.rating End) / 10)"
End if

If ReduceIfPlayed Then
        weightedPlayCountFormula = "(Songs.PlayCounter - " & dateBoostFormula & ")"
Else
        weightedPlayCountFormula = "0"
End If

If BoostNewSongsModifier <> 0 Then
        If (CurrentVersion() < 300) then
                boostNewSongsFormula = "IIF(Songs.rating <= " & (BoostNewSongsCutoff*10) & " AND songs.rating <> -1, 0, (IIF(FIX(DateDiff('d',Songs.DateAdded,Now) > " &                         BoostNewSongsDays & "), 0, " & BoostNewSongsModifier & ")))"
        Else
                boostNewSongsFormula = "(CASE WHEN ((Songs.rating <= " & (BoostNewSongsCutoff*10) & ") AND (songs.rating <> -1)) Then 0 Else (CASE WHEN ((julianday('Now') - julianday('1899-12-30') - Songs.DateAdded) > " & BoostNewSongsDays & ") Then 0 Else " & BoostNewSongsModifier & " END) END)"
        End if
End If

weightedRatingFormula = ratingFormula & "-" & weightedPlayCountFormula
if boostNewSongsFormula <> "" Then
        weightedRatingFormula = weightedRatingFormula & "+ " & boostNewSongsFormula
End if
'msgbox boostnotplayedformula
if boostNotPlayedFormula <> "" Then
        weightedRatingFormula = weightedRatingFormula & "+ " & boostNotPlayedFormula
End if

If (CurrentVersion() < 300) Then
        weightedRatingFormula = " IIF( " & weightedRatingFormula & "> 10,10, " & weightedRatingFormula & ") "
Else
        weightedRatingFormula = " (CASE WHEN ( " & weightedRatingFormula & "> 10) Then 10 Else round(" & weightedRatingFormula & ") END) "
End If

' Get version of mediamonkey
Function CurrentVersion()
        CurrentVersion = 100 * SDB.VersionHi + SDB.VersionLo
End Function

Sub FillStandardProperties(parentNode, childNode)
   With childNode
      .CustomNodeId = parentNode.CustomNodeId
      .CustomDataId = parentNode.CustomDataId + 1
      .UseScript = Script.ScriptPath
   End With
End Sub

'msgbox weightedRatingFormula & vbcrlf & vbcrlf & dateBoostFormula & vbcrlf & vbcrlf & ratingFormula & vbcrlf & vbcrlf & weightedPlayCountFormula & vbcrlf & vbcrlf & boostNewSongsFormula

Sub FillGoodLeaf(Node)
  Randomize

    'Before anything let's check the weights for correct input!
   if numberofsongs<=0 then
      msgbox "You don't want any songs? Please set value of NumberOfSongs > 0 !"
      exit sub
   end if

   if (set1percentage+set2percentage)>100 or set1percentage>100 or set2percentage>100 then
      msgbox "Your SetXPercentage settings are messed up! They add to over 100% !"
      exit sub
   end if


   Dim Tracks
   Dim SQLStatement,SQL
   Dim SELECT_TOP_Clause, SELECT_Clause, FROM_Clause, WHERE_Clause, WHERE_WEIGHT_Clause, ORDER_Clause
   Dim Iter, res, i, total, sum, index
   Dim weight, minweight, maxweight
   Dim hold, weights, average, start, baseweight, boundary,alreadyused
   Dim R, max : max = NumberOfSongs
   Dim inStr : inStr = ""

   Set hold = CreateObject("Scripting.Dictionary") ' define an associative array or "hash array" to hold the songs
   Set weights = CreateObject("Scripting.Dictionary") ' define an associative array or "hash array" to hold the weightings
   Set alreadyused = CreateObject("Scripting.Dictionary") 'define an array with the list of already used tracks

   SELECT_TOP_Clause = "SELECT TOP "
   If (CurrentVersion() < 300) then 
           SELECT_Clause = " Songs.Id, IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") "
   Else
           SELECT_Clause = " Songs.Id, (CASE WHEN (" & weightedRatingFormula & ">10) Then 10 Else " & weightedRatingFormula & " END) "
   End if
   FROM_Clause = " FROM Songs "
   If (CurrentVersion() < 300) Then
           WHERE_Clause = " WHERE " & weightedPlayCountFormula &" < " & ratingFormula & " AND DateDiff('d',Songs.LastTimePlayed, Now) > " & MinDaysRepeat
   Else
           WHERE_Clause = " WHERE " & weightedPlayCountFormula &" < " & ratingFormula & " AND ((julianday('Now') - julianday('1899-12-30') - Songs.LastTimePlayed) > " & MinDaysRepeat & " )"
   End if
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " AND Songs.Genre NOT IN (" & NotPlayGenres & ")"
   End If
   ORDER_Clause = " ORDER BY Rnd((1000*Songs.ID)*Now())" ' This is important because otherwise they will all come as they are stored in the DB

   'SQLStatement = SELECT_Clause & FROM_Clause & WHERE_Clause & ORDER_Clause
   'Stricly debug
   '   msgbox "Attention hidden box from ie!"
   '   Dim objIE
   '   Set objIE = CreateObject("InternetExplorer.Application")
   '   objIE.Navigate("about:blank")
   '   objIE.document.parentwindow.clipboardData.SetData "text",SQLStatement
   '   objIE.Quit
   '   Set objIE=nothing
   '   msgbox "Copied!"
   'End Debug

    'From below here it's old code!
    'Was nice but i'll try it with SQL only

    'All 3 weighting statements!
   Set Tracks = SDB.MainTracksWindow

   For i=1 to 3
           'each i correspons do one section of weights
           if i=1 Then
                   If (CurrentVersion() < 300) then
                           Select_top_clause = "SELECT TOP " & (max * Set1Percentage / 100)
                   Else
                           Select_top_clause = "SELECT"
                           ORDER_Clause = " ORDER BY random() LIMIT round(" & (max * Set1Percentage / 100) & ")"
                   End If
                   Where_weight_clause= " AND (" & weightedratingformula & " between " & set1weight-set1boundary & " AND " & set1weight+set1boundary & ") "
           elseif i=2 then
                   if set1percentage=100 then
                           exit for
                   end If
                   If (CurrentVersion() < 300) then
                           Select_top_clause = "SELECT TOP " & (max * Set2Percentage / 100)
                   Else
                           Select_top_clause = "SELECT"
                           ORDER_Clause = " ORDER BY random() LIMIT round(" & (max * Set2Percentage / 100) & ")"
                   End if
                   Where_weight_clause= " AND (" & weightedratingformula & " between " & set2weight-set2boundary & " AND " & set2weight+set2boundary & ") "
           elseif i=3 then
                   if set1percentage+set2percentage=100 then
                           exit for
                   end If
                   If (CurrentVersion() < 300) then
                           Select_top_clause = "SELECT TOP " & (max * (100-(Set1Percentage+Set2Percentage)) / 100)
                   Else
                           Select_top_clause = "SELECT"
                           ORDER_Clause = " ORDER BY random() LIMIT round(" & (max * (100-(Set1Percentage+Set2Percentage)) / 100) & ")"
                   End if
                   Where_weight_clause= " AND (" & weightedratingformula & " between " & set3weight-set3boundary & " AND " & set3weight+set3boundary & ") "
           end if

      SQL =SELECT_TOP_Clause & SELECT_Clause & FROM_Clause & WHERE_Clause & WHERE_WEIGHT_Clause & ORDER_Clause
      Set Iter = SDB.Database.OpenSQL(SQL)

      'Stricly debug
      'msgbox "Attention hidden box from ie!"
      'Dim objIE
      'Set objIE = CreateObject("InternetExplorer.Application")
      'objIE.Navigate("about:blank")
      'objIE.document.parentwindow.clipboardData.SetData "text",SQL
      'objIE.Quit
      'Set objIE=nothing
      'msgbox "Copied!"
      'End Debug
      do while iter.eof =false
         if instr ="" then
            instr=iter.stringbyindex(0)
         else
            instr = instr & ", " & iter.StringByIndex(0)
         end if
         iter.next
      loop

   Next

   'msgbox instr
   If inStr <> "" Then
           If (CurrentVersion() < 300) then
                   Tracks.AddTracksFromQuery("AND Songs.ID IN (" & inStr & ") ORDER BY Rnd((1000*Songs.ID)*Now())")
           Else
                   Tracks.AddTracksFromQuery("WHERE Songs.ID IN (" & inStr & ") ORDER BY Random()")
           End if
           Tracks.FinishAdding
   End If
   Set iter=nothing
   set tracks = nothing

End Sub

Sub FillWeightNode(Node)

   Dim Tree, newNode
   Dim SQLStatement ' SQL query to the database
   Dim Iter ' SDBD Iterator obtained by running the SQL query to get the nodes

   Set Tree = SDB.MainTree
   Node.HasChildren = false ' To delete all old children

   If (CurrentVersion() < 300) Then
           SQLStatement = "SELECT DISTINCT IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") from Songs "
   Else
           SQLStatement = "SELECT DISTINCT (CASE WHEN (" & weightedRatingFormula & ">10) Then 10 Else " & weightedRatingFormula & " END) from Songs "
   End if
   'res = InputBox("SQL Statement Node: ", SQLStatement, SQLStatement) ' For debugging
   Set Iter = SDB.Database.OpenSQL(SQLStatement)

   While Not Iter.EOF

      Set newNode = Tree.CreateNode

      NewNode.Caption = Iter.StringByIndex(0)
      NewNode.iconIndex = 32
      newNode.CustomData = Iter.StringByIndex(0)

      FillStandardProperties node,newNode
      newNode.onFillTracksFunct = "FillWeightLeaf"
      newNode.hasChildren = False
      Tree.AddNode Node, NewNode, 3

      Iter.Next
   Wend

End Sub


Sub FillWeightLeaf(Node)
   Dim Weight
   Dim Tracks
   Dim SELECT_Clause, FROM_Clause, WHERE_Clause

   Weight = Node.CustomData

   SELECT_Clause = " SELECT Songs.Id "
   FROM_Clause = " FROM Songs "
   If (CurrentVersion() < 300) Then
           WHERE_Clause = " WHERE IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") = " & Weight & " AND DateDiff('d',Songs.LastTimePlayed, Now) > " & MinDaysRepeat
   Else
           WHERE_Clause = " WHERE ((CASE WHEN ( " & weightedRatingFormula & ">10 ) THEN 10 ELSE " & weightedRatingFormula & " END) = " & Weight & ") AND ((julianday('Now') - julianday('1899-12-30')-Songs.LastTimePlayed) > " & MinDaysRepeat & ")"
   End if
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " AND Songs.Genre NOT IN (" & NotPlayGenres & ")"
   End If
   'res = InputBox("SQL Statement Leaf: ", "Debugging", SELECT_Clause & FROM_Clause & WHERE_Clause) ' For debugging

   Set Tracks = SDB.MainTracksWindow

   If (CurrentVersion() < 300) Then
           Tracks.AddTracksFromQuery("AND Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   Else
           Tracks.AddTracksFromQuery("WHERE Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   End If
   
   Tracks.FinishAdding

End Sub


Sub FillDoneLeaf(Node)
   Dim Tracks
   Dim SELECT_Clause, FROM_Clause, WHERE_Clause


   SELECT_Clause = " SELECT Songs.Id "
   FROM_Clause = " FROM Songs "
   If (CurrentVersion() < 300) then
           WHERE_Clause = " WHERE DateDiff('d',Songs.LastTimePlayed, Now) <= " & MinDaysRepeat
   Else
           WHERE_Clause = " WHERE (julianday('Now') - julianday('1899-12-30') - Songs.LastTimePlayed) <= " & MinDaysRepeat
   End if
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " OR Songs.Genre IN (" & NotPlayGenres & ")"
   End If

   Set Tracks = SDB.MainTracksWindow

   If (CurrentVersion() < 300) then
           Tracks.AddTracksFromQuery("AND Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   Else
           Tracks.AddTracksFromQuery("WHERE Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   End if
   Tracks.FinishAdding

End Sub



'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' Startup Function
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Sub onStartUp
   Dim Tree, RadioFreeMonkeyRoot
   Dim RadioMonkeyGood, RadioMonkeyBad, RadioMonkeyWeight

   Set Tree = Sdb.MainTree
   Set RadioFreeMonkeyRoot = Tree.createNode

   RadioFreeMonkeyRoot.Caption = RootNodeCaption
   RadioFreeMonkeyRoot.IconIndex = 14
   RadioFreeMonkeyRoot.UseScript = Script.ScriptPath
   RadioFreeMonkeyRoot.hasChildren = True
   Tree.AddNode Tree.Node_Library, RadioFreeMonkeyRoot, 1
   SDB.Objects("RadioFreeMonkeyRoot") = RadioFreeMonkeyRoot

   Set RadioMonkeyGood = Tree.createNode
   RadioMonkeyGood.Caption = "Radio List"
   RadioMonkeyGood.IconIndex = 14
   RadioMonkeyGood.UseScript = Script.ScriptPath
   RadioMonkeyGood.hasChildren = False
   RadioMonkeyGood.onFillTracksFunct = "FillGoodLeaf"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyGood, 2
   SDB.Objects("RadioMonkeyGood") = RadioMonkeyGood

   Set RadioMonkeyWeight = Tree.createNode
   RadioMonkeyWeight.Caption = "Weightings"
   RadioMonkeyWeight.IconIndex = 32
   RadioMonkeyWeight.UseScript = Script.ScriptPath
   RadioMonkeyWeight.hasChildren = True
   RadioMonkeyWeight.onFillTracksFunct = "FillWeightNode"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyWeight, 3
   SDB.Objects("RadioMonkeyWeight") = RadioMonkeyWeight

   Set RadioMonkeyBad = Tree.createNode
   RadioMonkeyBad.Caption = "Done"
   RadioMonkeyBad.IconIndex = 15
   RadioMonkeyBad.UseScript = Script.ScriptPath
   RadioMonkeyBad.hasChildren = False
   RadioMonkeyBad.onFillTracksFunct = "FillDoneLeaf"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyBad, 3
   SDB.Objects("RadioMonkeyBad") = RadioMonkeyBad
End Sub

by popper » Fri Jan 18, 2008 4:21 pm

In my opinion, for MM3 this needs to be rewritten completely. Especially in order to make use of the new script-enabled Auto-DJ function.
I have started work on this a while ago, but haven't gotten very far yet, and i am not sure when i will find the time.

But yes, I am missing this also...

MM3

by jsummers » Wed Jan 16, 2008 2:34 pm

Will this be migrated to mm3?


Missing this ... :(

by lemo » Wed Jan 02, 2008 5:20 pm

Has anyone got this working with MM3?

by D!m » Sat Nov 24, 2007 6:21 am

I do some bug fix.

Mainly, the BoostNewSongs now work with unrated songs. Songs with a weight higher than 10 were never picked, theirs weight are now fixed to 10.

I fixed also the option to disable some genres.

Code: Select all

' RadioFreeMonkey
' Version 1.7.1
' A script to create a "radio station" for you based on your song ratings.

' #####################
' Version 1.2 by Risser

' This script creates a root node in the tree, beneath the library node, called "RadioFreeMonkey".
' Under this node, you have a Radio List node, a Done node and a Weightings node.
' - The Radio List node lists 20 songs, in random order. These are weighted, so songs
' with a higher weighting have a higher chance of getting selected.
' - If you have selected a sorting column, even though the songs are selected randomly, the
' radio list will be sorted based on that column. To return the list to "random" sorting, click
' on any playlist (Now Playing works nicely). When you visit the Radio List node, the songs will
' be unsorted, in true random order.
' - The Done list shows you which songs aren't going to be played. This includes songs that have
' passed their maximum playcount, or anything within MinDaysRepeat.
' - The Weighting node shows all tunes, sorted by their calculated weights. This can help you
' determine what the optimal weighting choices are for you. Plus, it's just nice to see what's
' more likely to be played.

' Songs are weighted as follows:
' Rating * 2 (5 stars = 10, 3.5 stars = 7, 0 stars = 0)
' - Number of Plays (if Reduce if Played is TRUE)
' + Days since added to library / DayFactor (always rounded down)
' However, the weighting can't be more than the original rating (* 2).

' TO DO: At some point, I'd like to make the main 'list' node a PlayList instead of a regular
' list of tracks, but I'm not sure how to do this.
'
' This script can be freely used and modified.
' This is an early release and there may be bugs. If it's causing you problems, simply delete
' it or move it out of the scripts\auto folder.
'
' The script does not modify the database, registry or INI file.

' #####################
' Version 1.5 by popper

' - added possibility to boost songs that have been added to the DB recently
' - added possibility to define the genres that should be played
' - redesign of the mechanism that selects the actual songs to be played (because I did not
'   really understand what was going on in the existing algorithm ;-), with the goal of making
'   it easier to influence what will be played (e.g. 30% of songs with a weighting of 8-10 and
'   70% with a weighting of 5-7))
' #####################
' Version 1.6 by ElGringo

' - Fixes to the algorithm
'   - 1. There was always a song that had nothing to do in my playlists, investigated
'        and saw the error in FillGoodLeaf
'   - 2. There is an error in the calculation of the dateboost formula, the
'        dateboostcutoff*20 should be dateboostcutoff*10. There were a couple of places wrong
'   - 3. By adding, the BoostNewSongsModifier, the actual weight calculated, could go higher
'        than 10, but the algorithm was never picking songs with a weight higher than 10. So,
'        i fixed a couple of places in the script, so that calculated weight higher than 10,
'        are now fixed at 10.
'   - 4.There was a bug, when the BoostNewSongsModifier is set to 0... fixed it.
'
'
'
' #####################
' Version 1.6.1 by popper

' - In my opinion, the dateboostcutoff*20 (point 2. from ElGringo's list above) was correct
'   ("Please correct me if I am wrong, but the ratings are stored in the database using
'    numbers from 0 (or -1) to 100. So to calculate the number of stars from a rating in
'    the database, you have to divide by 20, and not by ten.")
'   So I changed it back in this release.
'   No other modifications made. ElGringo was right in all other points ;-)
'
'
' #####################
' Version 1.7 by RedX
'
' - Improvements to the algorithm
'  1. I have replaced all looping with SQL access statements improving overall query time and
'     and IMHO readabilty of the code
'  2. Added option to improve weights of songs with low played count especially one  that have not yet
'      been heard at all but are old in the db, old means longer then boostnewsongsdays
'  3. Added check for SetXPercentage and numberofsongs
'  My modifications are restricted to FillGoodLeaf and adding a new Formula in the general section
'
'
' #####################
' Version 1.7.1 by D!m
'
' - Fix some bugs
'  1. BoostNewSongs now work with unrated songs.
'  2. Song with a weight higher than 10 are now fixed at 10.
'  3. Option genres that should not be played now work.
'
' Disclaimer:
' Use at your own risk. Back up your data before using.
' Changing some of the values might lead to endless loops that can only be solved by
' killing the MediaMonkey process, so take care when modifying anything!

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' Global Variables and Declarations
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Option Explicit

' %%% The caption for the root node.
Const RootNodeCaption = "Radio FreeMonkey 1.7.1"

' %%% Add 1 to weighting for each X days since added to library
Const DayFactor = 20

' %%% Anything rated this or below will not receive the 'date boost'
Const DateBoostCutoff = 1.5

' %%% The minimum number of days that must pass before a song is repeated. Zero means, go ahead
' and repeat it right away.
Const MinDaysRepeat = 1

' %%% Reduce the weighting by the number of times played. This means, as songs are played more often,
' they are less likely to be played again
Const ReduceIfPlayed = True

' %%% Boost Songs that have been added during the last n days (MinDaysRepeat does still apply for these)
Const BoostNewSongsDays = 30

' %%% The boost modifier for new songs (Zero means, don't boost):
' Add x to the weighting of these songs
Const BoostNewSongsModifier = 3

' %%% Anything rated this or below will not receive the 'new song boost'
Const BoostNewSongsCutoff = 1.5

' %%% Tracks that have not been heard yet and have not been recently added receive this bonus (Dateadded > BoostNewSongsDays)
Const BoostNotPlayedModifier=5

' %%% Limit for the not heard Bonus, 0 means only songs u never played get the bonus
Const BoostNotPlayedCutoff=0

' %%% Boost not rated songs (problem is bomb = not rated = rating -1)
Const BoostNotPlayedNotRated=True

' %%% In case some of the non played songs have a rating do not pick songs with ratings below (0 to 10)
' %% 2 = 20=1 star 4=40=2 stars
Const BoostNotPlayedRatingCutoff=5

' %%% Genres that should not be played. Leave empty (Const NotPlayGenres = "") to ignore.
' "-1, 13, 17, 20, 24" means "empty genre field, Pop, Rock, Alternative, Soundtrack"
' Look up the other genre Ids in the database by using MS Access
Const NotPlayGenres = ""

' %%% Number of Songs in list
Const NumberOfSongs = 25


' %%% Influence which songs will be played. You have three sets that you can use
' Example:
' Const Set1Weight = 8.5    ' Basic weight for this set is 8.5
' Const Set1Boundary = 1.5  ' with a variation of 1.5, which means that songs between 7 and 10 will be chosen
' Const Set1Percentage = 60 ' this is how big the part of this set should be in the overall contents

Const Set1Weight = 7.0
Const Set1Boundary = 3
Const Set1Percentage = 90    ' make sure all 3 percentages sum up to 100!

Const Set2Weight = 2.0
Const Set2Boundary = 2
Const Set2Percentage = 10   ' make sure all 3 percentages sum up to 100!

Const Set3Weight = 1.0      ' Right now, it is not possible to choose songs with a weight < 1, so unfortunately you cannot add unrated songs
Const Set3Boundary = 1
'Const Set3Percentage = 20  ' This is not needed because it just takes what is missing to 100%


'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' The Meat. Don't change anything under here.
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

' the text of the formulas to be used throughout
Dim weightedRatingFormula, dateBoostFormula, ratingFormula, weightedPlayCountFormula, boostNewSongsFormula, boostNotPlayedFormula

If BoostNewSongsModifier <> 0 Then
   dateBoostFormula = "IIF(Songs.rating <= " & (BoostNewSongsCutoff *10) & " OR FIX(DateDiff('d',Songs.DateAdded,Now) <= " & BoostNewSongsDays & "), 0, FIX(DateDiff('d',Songs.DateAdded,Now) / " & DayFactor & "))"
Else
   dateBoostFormula = "IIF(Songs.rating <= " & (DateBoostCutoff*10) & ", 0, FIX(DateDiff('d',Songs.DateAdded,Now) / " & DayFactor & "))"
End If

'If the songs played MORE then x times OR Songs' shorter then X days in DB or rating below X then RETURN 0 ELSE is ok
If BoostNotPlayedModifier > 0 then
   if boostnotplayednotrated=true then
      boostNotPlayedFormula= " IIF((Songs.PlayCounter >" & BoostNotPlayedCutoff & " OR FIX(Datediff('d',Songs.DateAdded,Now))<" & BoostNewSongsDays & " OR (Songs.rating<"& boostnotplayedratingcutoff*10 & " AND songs.rating <> -1)),0,"& BoostNotPlayedModifier &") "
   else
      boostNotPlayedFormula= " IIF(Songs.PlayCounter >" & BoostNotPlayedCutoff & " OR FIX(Datediff('d',Songs.DateAdded,Now))<" & BoostNewSongsDays & " OR Songs.rating<"& boostnotplayedratingcutoff*10 & ",0,"& BoostNotPlayedModifier &") "
   end if
end if


ratingFormula = "(IIF(Songs.rating < 0, 0, Songs.rating) / 10)"

If ReduceIfPlayed Then
   weightedPlayCountFormula = "(Songs.PlayCounter - " & dateBoostFormula & ")"
Else
   weightedPlayCountFormula = "0"
End If

If BoostNewSongsModifier <> 0 Then
   boostNewSongsFormula = "IIF(Songs.rating <= " & (BoostNewSongsCutoff*10) & " AND songs.rating <> -1, 0, (IIF(FIX(DateDiff('d',Songs.DateAdded,Now) > " &                         BoostNewSongsDays & "), 0, " & BoostNewSongsModifier & ")))"
End If

weightedRatingFormula = ratingFormula & "-" & weightedPlayCountFormula
if boostNewSongsFormula <> "" then weightedRatingFormula = weightedRatingFormula & "+ " & boostNewSongsFormula
'msgbox boostnotplayedformula
if boostNotPlayedFormula <> "" then weightedRatingFormula = weightedRatingFormula & "+ " & boostNotPlayedFormula

weightedRatingFormula = " IIF( " & weightedRatingFormula & "> 10,10, " & weightedRatingFormula & ") "


Sub FillStandardProperties(parentNode, childNode)
   With childNode
      .CustomNodeId = parentNode.CustomNodeId
      .CustomDataId = parentNode.CustomDataId + 1
      .UseScript = Script.ScriptPath
   End With
End Sub

'msgbox weightedRatingFormula & vbcrlf & vbcrlf & dateBoostFormula & vbcrlf & vbcrlf & ratingFormula & vbcrlf & vbcrlf & weightedPlayCountFormula & vbcrlf & vbcrlf & boostNewSongsFormula

Sub FillGoodLeaf(Node)
  Randomize

    'Before anything let's check the weights for correct input!
   if numberofsongs<=0 then
      msgbox "You don't want any songs? Please set value of NumberOfSongs > 0 !"
      exit sub
   end if

   if (set1percentage+set2percentage)>100 or set1percentage>100 or set2percentage>100 then
      msgbox "Your SetXPercentage settings are messed up! They add to over 100% !"
      exit sub
   end if


   Dim Tracks
   Dim SQLStatement,SQL
   Dim SELECT_TOP_Clause, SELECT_Clause, FROM_Clause, WHERE_Clause, WHERE_WEIGHT_Clause, ORDER_Clause
   Dim Iter, res, i, total, sum, index
   Dim weight, minweight, maxweight
   Dim hold, weights, average, start, baseweight, boundary,alreadyused
   Dim R, max : max = NumberOfSongs
   Dim inStr : inStr = ""

   Set hold = CreateObject("Scripting.Dictionary") ' define an associative array or "hash array" to hold the songs
   Set weights = CreateObject("Scripting.Dictionary") ' define an associative array or "hash array" to hold the weightings
    Set alreadyused = CreateObject("Scripting.Dictionary") 'define an array with the list of already used tracks

   SELECT_TOP_Clause = "SELECT TOP "
   SELECT_Clause = " Songs.Id, IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") "
   FROM_Clause = " FROM Songs "
   WHERE_Clause = " WHERE " & weightedPlayCountFormula &" < " & ratingFormula & " AND DateDiff('d',Songs.LastTimePlayed, Now) > " & MinDaysRepeat
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " AND Songs.Genre NOT IN (" & NotPlayGenres & ")"
   End If
   ORDER_Clause = " ORDER BY Rnd((1000*Songs.ID)*Now())" ' This is important because otherwise they will all come as they are stored in the DB

   'SQLStatement = SELECT_Clause & FROM_Clause & WHERE_Clause & ORDER_Clause
   'Stricly debug
   '   msgbox "Attention hidden box from ie!"
   '   Dim objIE
   '   Set objIE = CreateObject("InternetExplorer.Application")
   '   objIE.Navigate("about:blank")
   '   objIE.document.parentwindow.clipboardData.SetData "text",SQLStatement
   '   objIE.Quit
   '   Set objIE=nothing
   '   msgbox "Copied!"
   'End Debug

    'From below here it's old code!
    'Was nice but i'll try it with SQL only

    'All 3 weighting statements!
   Set Tracks = SDB.MainTracksWindow

   For i=1 to 3
      'each i correspons do one section of weights
      if i=1 then
         Select_top_clause = "SELECT TOP " & (max * Set1Percentage / 100)
         Where_weight_clause= " AND (" & weightedratingformula & " between " & set1weight-set1boundary & " AND " & set1weight+set1boundary & ") "
      elseif i=2 then
         if set1percentage=100 then
            exit for
         end if
         Select_top_clause = "SELECT TOP " & (max * Set2Percentage / 100)
         Where_weight_clause= " AND (" & weightedratingformula & " between " & set2weight-set2boundary & " AND " & set2weight+set2boundary & ") "
      elseif i=3 then
         if set1percentage+set2percentage=100 then
            exit for
         end if
         Select_top_clause = "SELECT TOP " & (max * (100-(Set1Percentage+Set2Percentage)) / 100)
         Where_weight_clause= " AND (" & weightedratingformula & " between " & set3weight-set3boundary & " AND " & set3weight+set3boundary & ") "
      end if

      SQL =SELECT_TOP_Clause & SELECT_Clause & FROM_Clause & WHERE_Clause & WHERE_WEIGHT_Clause & ORDER_Clause
      Set Iter = SDB.Database.OpenSQL(SQL)

      'Stricly debug
      'msgbox "Attention hidden box from ie!"
      'Dim objIE
      'Set objIE = CreateObject("InternetExplorer.Application")
      'objIE.Navigate("about:blank")
      'objIE.document.parentwindow.clipboardData.SetData "text",SQL
      'objIE.Quit
      'Set objIE=nothing
      'msgbox "Copied!"
      'End Debug
      do while iter.eof =false
         if instr ="" then
            instr=iter.stringbyindex(0)
         else
            instr = instr & ", " & iter.StringByIndex(0)
         end if
         iter.next
      loop

   Next

   'msgbox instr
   If inStr <> "" then
           Tracks.AddTracksFromQuery("AND Songs.ID IN (" & inStr & ") ORDER BY Rnd((1000*Songs.ID)*Now())")
           Tracks.FinishAdding
   End If
   Set iter=nothing
   set tracks = nothing

End Sub

Sub FillWeightNode(Node)

   Dim Tree, newNode
   Dim SQLStatement ' SQL query to the database
   Dim Iter ' SDBD Iterator obtained by running the SQL query to get the nodes

   Set Tree = SDB.MainTree
   Node.HasChildren = false ' To delete all old children

   SQLStatement = "SELECT DISTINCT IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") from Songs "
   'res = InputBox("SQL Statement Node: ", SQLStatement, SQLStatement) ' For debugging
   Set Iter = SDB.Database.OpenSQL(SQLStatement)

   While Not Iter.EOF

      Set newNode = Tree.CreateNode

      NewNode.Caption = Iter.StringByIndex(0)
      NewNode.iconIndex = 32
      newNode.CustomData = Iter.StringByIndex(0)

      FillStandardProperties node,newNode
      newNode.onFillTracksFunct = "FillWeightLeaf"
      newNode.hasChildren = False
      Tree.AddNode Node, NewNode, 3

      Iter.Next
   Wend

End Sub


Sub FillWeightLeaf(Node)
   Dim Weight
   Dim Tracks
   Dim SELECT_Clause, FROM_Clause, WHERE_Clause

   Weight = Node.CustomData

   SELECT_Clause = " SELECT Songs.Id "
   FROM_Clause = " FROM Songs "
   WHERE_Clause = " WHERE IIF(" & weightedRatingFormula & ">10,10," & weightedRatingFormula & ") = " & Weight & " AND DateDiff('d',Songs.LastTimePlayed, Now) > " & MinDaysRepeat
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " AND Songs.Genre NOT IN (" & NotPlayGenres & ")"
   End If
   'res = InputBox("SQL Statement Leaf: ", "Debugging", SELECT_Clause & FROM_Clause & WHERE_Clause) ' For debugging

   Set Tracks = SDB.MainTracksWindow

   Tracks.AddTracksFromQuery("AND Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   Tracks.FinishAdding

End Sub


Sub FillDoneLeaf(Node)
   Dim Tracks
   Dim SELECT_Clause, FROM_Clause, WHERE_Clause


   SELECT_Clause = " SELECT Songs.Id "
   FROM_Clause = " FROM Songs "
   WHERE_Clause = " WHERE DateDiff('d',Songs.LastTimePlayed, Now) <= " & MinDaysRepeat
   If NotPlayGenres <> "" then
      WHERE_Clause = WHERE_Clause & " OR Songs.Genre IN (" & NotPlayGenres & ")"
   End If

   Set Tracks = SDB.MainTracksWindow

   Tracks.AddTracksFromQuery("AND Songs.ID IN (" & SELECT_Clause & FROM_Clause & WHERE_Clause & ")")
   Tracks.FinishAdding

End Sub



'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' Startup Function
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Sub onStartUp
   Dim Tree, RadioFreeMonkeyRoot
   Dim RadioMonkeyGood, RadioMonkeyBad, RadioMonkeyWeight

   Set Tree = Sdb.MainTree
   Set RadioFreeMonkeyRoot = Tree.createNode

   RadioFreeMonkeyRoot.Caption = RootNodeCaption
   RadioFreeMonkeyRoot.IconIndex = 14
   RadioFreeMonkeyRoot.UseScript = Script.ScriptPath
   RadioFreeMonkeyRoot.hasChildren = True
   Tree.AddNode Tree.Node_Library, RadioFreeMonkeyRoot, 1
   SDB.Objects("RadioFreeMonkeyRoot") = RadioFreeMonkeyRoot

   Set RadioMonkeyGood = Tree.createNode
   RadioMonkeyGood.Caption = "Radio List"
   RadioMonkeyGood.IconIndex = 14
   RadioMonkeyGood.UseScript = Script.ScriptPath
   RadioMonkeyGood.hasChildren = False
   RadioMonkeyGood.onFillTracksFunct = "FillGoodLeaf"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyGood, 2
   SDB.Objects("RadioMonkeyGood") = RadioMonkeyGood

   Set RadioMonkeyWeight = Tree.createNode
   RadioMonkeyWeight.Caption = "Weightings"
   RadioMonkeyWeight.IconIndex = 32
   RadioMonkeyWeight.UseScript = Script.ScriptPath
   RadioMonkeyWeight.hasChildren = True
   RadioMonkeyWeight.onFillTracksFunct = "FillWeightNode"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyWeight, 3
   SDB.Objects("RadioMonkeyWeight") = RadioMonkeyWeight

   Set RadioMonkeyBad = Tree.createNode
   RadioMonkeyBad.Caption = "Done"
   RadioMonkeyBad.IconIndex = 15
   RadioMonkeyBad.UseScript = Script.ScriptPath
   RadioMonkeyBad.hasChildren = False
   RadioMonkeyBad.onFillTracksFunct = "FillDoneLeaf"
   Tree.AddNode RadioFreeMonkeyRoot, RadioMonkeyBad, 3
   SDB.Objects("RadioMonkeyBad") = RadioMonkeyBad
End Sub

Top