Please note that you should only run this script if you have tracks where the BPM has been calculated. If you do not have any (in the filter selected) then this will cause Auto DJ to cease functioning. However, they do not all need to have BPM values, the tracks without will simply be ignored and never selected.
As always, the installer can be downloaded from my website, which is linked to in my signature. And here is the code...
Code: Select all
'
' MediaMonkey Script
'
' NAME: AutoBeatsDJ 1.4
'
' AUTHOR: trixmoto (http://trixmoto.net)
' DATE : 12/07/2012
'
' INSTALL: Copy to Scripts directory
'
' FIXES: Added option to not favour unplayed tracks
' Added option to exclude last X played tracks
'
Option Explicit
Dim Filters()
Dim Debug : Debug = False
Dim FilterName : FilterName = "- No Filter -"
Dim FilterSQL : FilterSQL = ""
Dim Tolerance : Tolerance = 10
Dim Wandering : Wandering = 1
Dim Unplayed : Unplayed = True
Dim History : History = 50
Sub Install()
'set default values
Dim ini : Set ini = SDB.IniFile
If ini.StringValue("AutoBeatsDJ","FilterName") = "" Then
ini.StringValue("AutoBeatsDJ","FilterName") = FilterName
End If
If ini.StringValue("AutoBeatsDJ","Tolerance") = "" Then
ini.IntValue("AutoBeatsDJ","Tolerance") = Tolerance
End If
If ini.StringValue("AutoBeatsDJ","Wandering") = "" Then
ini.IntValue("AutoBeatsDJ","Wandering") = Wandering
End If
If ini.StringValue("AutoBeatsDJ","Unplayed") = "" Then
ini.BoolValue("AutoBeatsDJ","Unplayed") = Unplayed
End If
If ini.StringValue("AutoBeatsDJ","History") = "" Then
ini.IntValue("AutoBeatsDJ","History") = History
End If
'add ini entries
Set ini = SDB.Tools.IniFileByPath(SDB.ApplicationPath&"Scripts\Scripts.ini")
If Not (ini Is Nothing) Then
ini.StringValue("AutoBeatsDJ","Filename") = "AutoBeatsDJ.vbs"
ini.StringValue("AutoBeatsDJ","DisplayName") = "Auto Beats DJ"
ini.StringValue("AutoBeatsDJ","Description") = "An AutoDJ which selects similar BPM"
ini.StringValue("AutoBeatsDJ","Language") = "VBScript"
ini.StringValue("AutoBeatsDJ","ScriptType") = "4"
SDB.RefreshScriptItems
End If
If Debug Then
Call clear()
End If
Set SDB.Objects("AutoBeatsData") = Nothing
End Sub
Sub InitConfigSheet(Sheet)
Dim ui : Set ui = SDB.UI
Dim ini : Set ini = SDB.IniFile
FilterName = ini.StringValue("AutoBeatsDJ","FilterName")
Tolerance = ini.IntValue("AutoBeatsDJ","Tolerance")
Wandering = ini.IntValue("AutoBeatsDJ","Wandering")
Unplayed = ini.BoolValue("AutoBeatsDJ","Unplayed")
History = ini.IntValue("AutoBeatsDJ","History")
Dim edt : Set edt = ui.NewLabel(Sheet)
edt.Common.SetRect 0, 6, 50, 20
edt.Caption = "Filter:"
edt.Autosize = False
Set edt = ui.NewDropDown(Sheet)
edt.Common.SetRect 34, 3, 150, 20
edt.Style = 2
edt.Common.ControlName = "ABDJFilterName"
Call CreateFiltersArray()
Call FillDropDownFromArray(edt,Filters)
edt.ItemIndex = GetFiltersArrayID(FilterName)
Set edt = ui.NewLabel(Sheet)
edt.Common.SetRect 194, 6, 50, 20
edt.Caption = "±BPM:"
edt.Autosize = False
Set edt = ui.NewSpinEdit(Sheet)
edt.Common.SetRect 232, 3, 40, 20
edt.Common.ControlName = "ABDJTolerance"
edt.MinValue = 0
edt.MaxValue = 99
edt.Value = Tolerance
Set edt = ui.NewLabel(Sheet)
edt.Common.SetRect 283, 6, 50, 20
edt.Caption = "Wandering:"
edt.Autosize = False
Set edt = ui.NewSpinEdit(Sheet)
edt.Common.SetRect 345, 3, 40, 20
edt.Common.ControlName = "ABDJWandering"
edt.MinValue = 1
edt.MaxValue = 99
edt.Value = Wandering
Set edt = ui.NewLabel(Sheet)
edt.Common.SetRect 397, 6, 150, 20
edt.Caption = "Exclude last played:"
edt.Autosize = False
Set edt = ui.NewSpinEdit(Sheet)
edt.Common.SetRect 500, 3, 40, 20
edt.Common.ControlName = "ABDJHistory"
edt.MinValue = 1
edt.MaxValue = 99
edt.Value = History
Set edt = ui.NewCheckbox(Sheet)
edt.Common.SetRect 0, 25, 110, 20
edt.Common.ControlName = "ABDJUnplayed"
edt.Caption = "Favour unplayed?"
edt.Checked = Unplayed
End Sub
Sub CloseConfigSheet(Sheet,SaveConfig)
If SaveConfig Then
Dim ini : Set ini = SDB.IniFile
Dim edt : Set edt = Sheet.Common.ChildControl("ABDJFilterName")
ini.StringValue("AutoBeatsDJ","FilterName") = edt.ItemText(edt.ItemIndex)
ini.IntValue("AutoBeatsDJ","Tolerance") = Sheet.Common.ChildControl("ABDJTolerance").Value
ini.IntValue("AutoBeatsDJ","Wandering") = Sheet.Common.ChildControl("ABDJWandering").Value
ini.BoolValue("AutoBeatsDJ","Unplayed") = Sheet.Common.ChildControl("ABDJUnplayed").Checked
ini.IntValue("AutoBeatsDJ","History") = Sheet.Common.ChildControl("ABDJHistory").Value
Set SDB.Objects("AutoBeatsData") = Nothing
If Debug Then
Call clear()
End If
End If
End Sub
Function GenerateNewTrack()
Set GenerateNewTrack = Nothing
If Debug Then
Call out("GenerateNewTrack")
End If
Dim iter : Set iter = Nothing
Dim dic : Set dic = SDB.Objects("AutoBeatsData")
If dic Is Nothing Then
Set dic = CreateObject("Scripting.Dictionary")
dic.Item("cur") = 0
dic.Item("dir") = 0
dic.Item("tol") = SDB.IniFile.IntValue("AutoBeatsDJ","Tolerance")
dic.Item("wan") = SDB.IniFile.IntValue("AutoBeatsDJ","Wandering")
dic.Item("unp") = SDB.IniFile.IntValue("AutoBeatsDJ","Unplayed")
dic.Item("lst") = SDB.IniFile.IntValue("AutoBeatsDJ","History")
dic.Item("sql") = GetFilterSQL()
Set iter = SDB.Database.OpenSQL("SELECT MIN(Songs.BPM),MAX(Songs.BPM) FROM Songs WHERE Songs.ID>0 "&dic.Item("sql"))
dic.Item("min") = Int(iter.ValueByIndex(0))
dic.Item("max") = Int(iter.ValueByIndex(1))
Set iter = Nothing
If Debug Then
Call out("Tolerance="&dic.Item("tol"))
Call out("Wandering="&dic.Item("wan"))
Call out("Unplayed= "&dic.Item("wan"))
Call out("History= "&dic.Item("wan"))
Call out("Min BPM= "&dic.Item("min"))
Call out("Max BPM= "&dic.Item("max"))
End If
End If
Randomize
Dim cur : cur = Int(dic.Item("cur"))
Dim dir : dir = Int(dic.Item("dir"))
If cur = 0 Then
cur = Int(Int(dic.Item("wan"))*Rnd)+1
dir = 0
End If
If dir = 0 Then
dir = Int(3*Rnd)-1
dic.Item("dir") = dir
End If
If Debug Then
Call out("Current= "&cur)
Call out("Direction="&dir)
End If
Dim tol : tol = Int(dic.Item("tol"))
Dim lst : lst = Int(dic.Item("lst"))
Dim sql : sql = "SELECT Songs.ID FROM Songs WHERE Songs.ID NOT IN (0"
Dim list : Set list = SDB.Player.CurrentSongList
Dim itm : Set itm = Nothing
Dim i : i = 0
Dim j : j = 0
If list.Count > lst Then
j = list.Count-lst-1
End If
For i = j To list.Count-1
Set itm = list.Item(i)
sql = sql&","&itm.ID
Next
sql = sql&") "&dic.Item("sql")
While (tol < 100)
Dim sql2 : sql2 = ""
If Not (itm Is Nothing) Then
If Debug Then
Call out("Cur BPM= "&itm.BPM)
End If
If itm.BPM < 0 Then
sql2 = sql2&" AND Songs.BPM>-1"
Else
Dim bpm : bpm = itm.BPM+Int(dir*(tol/2)) 'apply direction
If tol = 0 Then
sql2 = sql2&" AND Songs.BPM="&bpm
Else
sql2 = sql2&" AND Songs.BPM>="&(bpm-tol)&" AND Songs.BPM<="&(bpm+(tol/2))
End If
End If
End If
If Int(dic.Item("unp")) = 1 Then
sql2 = sql&sql2&" ORDER BY PlayCounter,Random() LIMIT 1"
Else
sql2 = sql&sql2&" ORDER BY Random() LIMIT 1"
End If
If Debug Then
Call out("#"&sql2)
End If
Set iter = SDB.Database.OpenSQL(sql2)
If iter.EOF Then
If itm.BPM < 0 Then
tol = 100
Else
tol = tol+Int(dic.Item("tol")) 'increase tolerance
End If
Else
Set iter = SDB.Database.QuerySongs("Songs.ID="&iter.ValueByIndex(0))
Set GenerateNewTrack = iter.Item
tol = 100 'exit while
End If
Set iter = Nothing
WEnd
If GenerateNewTrack Is Nothing Then
If Int(dic.Item("unp")) = 1 Then
sql = sql&" ORDER BY PlayCounter,Random() LIMIT 1"
Else
sql = sql&" ORDER BY Random() LIMIT 1"
End If
If Debug Then
Call out("#"&sql)
End If
Set iter = SDB.Database.OpenSQL(sql)
If Not (iter.EOF) Then
Set iter = SDB.Database.QuerySongs("Songs.ID="&iter.ValueByIndex(0))
Set GenerateNewTrack = iter.Item
End If
Set iter = Nothing
End If
If Debug Then
If GenerateNewTrack Is Nothing Then
Call out(">Nothing")
Else
Call out(">"&GenerateNewTrack.ID&"="&GenerateNewTrack.BPM)
End If
End If
dic.Item("cur") = cur-1
Set SDB.Objects("AutoBeatsData") = dic
End Function
Function GetFilterID(Name)
Dim nam : nam = Replace(Name,"'","''")
If SDB.Database.OpenSQL("SELECT COUNT(*) FROM Filters WHERE Name='"&nam&"'").ValueByIndex(0) = 0 Then
FilterName = "- No Filter -"
SDB.IniFile.StringValue("AdvancedReport","FilterName") = FilterName
GetFilterID = -1
Else
GetFilterID = SDB.Database.OpenSQL("SELECT ID FROM Filters WHERE Name='"&name&"'").ValueByIndex(0)
End If
End Function
Sub FillDropDownFromArray(DropDown,SourceArray)
Dim i : i = 0
For i = 0 To UBound(SourceArray)
Call DropDown.AddItem(SourceArray(i))
Next
End Sub
Sub CreateFiltersArray()
Redim Filters(SDB.Database.OpenSQL("SELECT COUNT(*) FROM Filters").ValueByIndex(0)+1)
Filters(0) = "- No Filter -"
Filters(1) = "- Active Filter -"
Dim i : i = 2
Dim iter : Set iter = SDB.Database.OpenSQL("SELECT Name FROM Filters ORDER BY Pos")
Do While Not iter.EOF
Filters(i) = iter.StringByIndex(0)
i = i+1
iter.Next
Loop
Set iter = Nothing
End Sub
Function GetFiltersArrayID(Name)
GetFiltersArrayID = 0
Dim i : i = 0
For i = 0 To UBound(Filters)
If Filters(i) = Name Then
GetFiltersArrayID = i
Exit For
End If
Next
End Function
Function GetFilterSQL()
Dim Name : Name = SDB.IniFile.StringValue("AutoBeatsDJ","FilterName")
Select Case Name
Case "- No Filter -"
GetFilterSQL = ""
Case "- Active Filter -"
GetFilterSQL = SDB.Database.ActiveFilterQuery
Case Else
Dim id : id = GetFilterID(Name)
If id = -1 Then
GetFilterSQL = ""
Else
GetFilterSQL = SDB.Database.GetFilterQuery(id)
End If
End Select
If Not (GetFilterSQL = "") Then
GetFilterSQL = "AND "&GetFilterSQL
End If
End Function
Sub clear()
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim loc : loc = SDB.TemporaryFolder&"\AutoBeatsDJ.log"
Dim logf : Set logf = fso.CreateTextFile(loc,True)
Call logf.Close()
End Sub
Sub out(txt)
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Dim loc : loc = SDB.TemporaryFolder&"\AutoBeatsDJ.log"
Dim logf : Set logf = fso.OpenTextFile(loc,8,True)
Call logf.WriteLine(SDB.ToAscii(txt))
Call logf.Close()
End Sub