Handling Song Changes in Global Rackspace

Hi, I need to do change several widgets in the Global rackspace upon song change. However, I found out the “On Song” callback is only available in the gig script where, no surprises, widgets and plugins are out of scope. I came up with an ugly hack:

Var i : Integer

On Song(oldSongIndex : Integer, newSongIndex : Integer)
    // Dummy GlobalTranspose to get the SongChange to Global Rackspace
    i = GetGlobalTranspose()
    SetGlobalTranspose(i)
End

Then I catch GlobalTransposeChanged in the Global rackspace script and do my magic.
Works for me, but it would be hard for someone who actually uses GlobalTransposeChanged for what it was meant for.

Is there an elegant way to do this, i.e. some sort of “global generic” event, where one can code event type and value(s)?

Hi @a_maleev, welcome to the family :wink:

For my understanding:
You have widgets in the global rackspace which are mapped to some plugin parameters, right?
Now you want to change that widgets depending on what song is active?

You could create widgets in a local rackspace which are linked to the global widgets.
Now when the local widget is changed it changes automatically the global widget, when the local widget
is not checked “Ignore Variations”.

This way you do not need any scripts.

Another way could be to send OSC messages in the on Song callback and react on that in the OSC callback.

Hi @a_maleev, welcome to the GP community :wink:

Perhaps you could post your global transpose callback for us to see what you are doing?
As @pianopaul mentioned, I also have the feeling that scripting is not mandatory here.

I have often done this. Virtual midi ports is another option (sending messages from the Song Part’s Midi Helper Tool)

Yes, the possibilities are endless :wink:

Thanks for the replies, they got me thinking, I might go another route too - “Send program change number when song activates”. It is declarative and I might be able to send the message to other MIDI devices, for ex. band mates, visual fx, etc. Downside - I have to make sure I don’t use the same message for different songs …

Here is my “On Song” script in the Global rackspace script.

Var i, apPresetCount, songIndex, apPresetIndex : Integer
Var songName, songArtist : String
Var W_BeatText : Widget
Var P_AudioPlayer : PluginBlock

Function GetAPPresetIndex(name : String) Returns Integer
    result = 0
    apPresetCount = GetPresetCount(P_AudioPlayer)
    For i = 0; i < apPresetCount; i = i + 1 Do
        If IndexOfSubstring(GetPresetName(P_AudioPlayer, i), name, false) >= 0 Then
           result = i 
        End
    End
End

Initialization
    Print("----- Init -----")
    apPresetCount = GetPresetCount(P_AudioPlayer)    
End

On BeatChanged(bar : Integer, beat : Integer)
    SetWidgetLabel(W_BeatText, "" + bar + ":" + beat)
End

On SystemEvent(newValue : Integer) Matching GlobalTransposeChanged
    // Dummy handler to react to a song change
    songIndex = GetCurrentSongIndex()
    songName = GetSongName(songIndex)
    songArtist = GetSongArtistName(songIndex)
    
    apPresetIndex = GetAPPresetIndex(songArtist + " - " + songName)
    If apPresetIndex > 0 Then
        SetPluginBypassed(P_AudioPlayer, false)
        SelectPreset(P_AudioPlayer, apPresetIndex)
    Else
        SetPluginBypassed(P_AudioPlayer, true)
    End
End

I am reloading my backing tracks to reflect the current song - it is a bit laggy (about 0.5-1s), but does the job, but I load 4-8 tracks for the separate instruments as I need the possibility to mute/lower/boost them. Had to resort to audio player presets, as the files to be played are not available for scripting (yet?)

I am planing to also display configurable visual hints, depending on the current bar. Possibly also automatic rackspace/variation changes …

It is a fun project - we play 1-2 times per week, we use ultimate-guitar backing tracks …