I created a script to select songs without having to iterate through the songs.
I needed this because I am using predictive loading, and iterating takes to long otherwise as it would need to load every song (rackspace) between the start and end song.
Forgive me about the name of the songs, as I used this just as proof of concept.
My song list looks like this:
And the global rackspace like this:
The knob has GPScript handle SongSelectorKnob and the button is called SelectSongButton.
The labels have the following GP handles: LabelMinusTwo, LabelMinusOne, LabelActive, LabelPlusOne, LabelPlusTwo
The following script is used:
var
LabelMinusTwo, LabelMinusOne, LabelActive, LabelPlusOne, LabelPlusTwo : Widget
SongSelectorKnob, SelectSongButton : Widget
SongNames : String array
Initialization
SwitchToSetlistView()
End
Function FillSongNamesArray()
var
songsAmount : int
songIndex : int
ClearArray(SongNames)
if InSetlistView() then
songsAmount = GetSongCount()
ClearArray(SongNames)
for songIndex = 0; songIndex < songsAmount; songIndex = songIndex + 1 do
SongNames <-- GetSongName(songIndex)
end
end
End
Function BubbleSort(arr : string Array)
var
i, j : integer
s : string
for i = 0; i < Size(arr) - 2; i = i + 1 do
for j = 0; j < Size(arr) - 2 - i; j = j + 1 do
if arr[j] > arr[j + 1] then
s = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = s
end
end
end
End
Function GetOrder(songIndex : integer) returns string
result = IntToString(songIndex + 1) + "/" + IntToString(Size(SongNames)) + ": "
End
Function ShowLabelWidgets(show : boolean)
var hide : boolean = not show
SetWidgetHideOnPresentation(LabelMinusTwo, hide)
SetWidgetHideOnPresentation(LabelMinusOne, hide)
SetWidgetHideOnPresentation(LabelActive, hide)
SetWidgetHideOnPresentation(LabelPlusOne, hide)
SetWidgetHideOnPresentation(LabelPlusTwo, hide)
End
On WidgetValueChanged(newValue : double) from SongSelectorKnob
var
songsAmount : int
songIndex : int
FillSongNamesArray()
BubbleSort(SongNames)
songIndex = Round(newValue * (Size(SongNames) - 1))
ShowLabelWidgets(True)
SetWidgetLabel(LabelMinusTwo, if songIndex < 2 then "" else GetOrder(songIndex - 2) + GetSongName(songIndex - 2) end)
SetWidgetLabel(LabelMinusOne, if songIndex < 1 then "" else GetOrder(songIndex - 1) + GetSongName(songIndex - 1) end)
SetWidgetLabel(LabelActive, GetOrder(songIndex ) + GetSongName(songIndex) )
SetWidgetLabel(LabelPlusOne, if songIndex > Size(SongNames) - 2 then "" else GetOrder(songIndex + 1) + GetSongName(songIndex + 1) end)
SetWidgetLabel(LabelPlusTwo, if songIndex > Size(SongNames) - 3 then "" else GetOrder(songIndex + 2) + GetSongName(songIndex + 2) end)
SetWidgetHideOnPresentation(SelectSongButton, False)
End
On WidgetValueChanged(newValue : double) from SelectSongButton
var
songsAmount : int = Size(SongNames)
songIndex : int = Round(GetWidgetValue(SongSelectorKnob) * (Size(SongNames) - 1))
songSelected : boolean
if InSetlistView() and newValue > 0.5 then
songSelected = SwitchToSongByIndex(songIndex, 0)
ShowLabelWidgets(False)
SetWidgetHideOnPresentation(SelectSongButton, True)
end
End
What the script does is:
- Reading the song names of the current set list
- Sort the titles
- When the SL3 button is changed, the list with songs is shown on the right of the global rackspace and shows the to be selected song and the 4 surrounding songs. Also the selector button is shown.
- When the selector button is used, the song is activated and the button and song list in the global rackspace are hidden.
Note that on my gigging PC, I added a bit of code that the slider knob only activates the button and song list when the value is < 10 to prevent an accidental slider event in case of a wobbly keyboard (stand).
Also while reading in the songs, I ignore songs starting with * as I typically use those for *SET 1, *SET 2, *ENCORE etc, which are never needed to be selected directly, making the range on the knob (or slider in my gig’s version) a bit bigger.
Gig file
SImpleSongSelector.gig (118.4 KB)
Also see
Also see the related post Converting Program Changes to Prev/Next song
If you are looking for a very fancy song selector, check out this video for a Gig Performer extension created by @DaveBoulden.