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)?

1 Like

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.

1 Like

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 …

@a_maleev I have the same problem and even thought of the same hack :smile: … but for some reason calling “SetGlobalTranspose(i)” in the Gig script results in a callback in the Global Rackspace (GR) script with value 0, no matter what i is. (Using 4.5.8, in case that’s a bug.)

So instead I use the “Local GP Port”, to which I send a CC on song change that I react on in the GR script. I guess this is what @rank13 also meant with “virtual midi ports”. An OSC message (@pianopaul) would have been more expressive, but I haven’t figured out how to loop back OSC - using the GP IP address as remote client IP address (see image) causes GP to hang.

Anyways, can anyone tell why song events available to the global rackspace script ?

Context : I want the MIDI file player song number to be synchronized with the global song number. Shouldn’t there be a built-in option for that, or am I missing something ?

Hi @saintmatthieu, nice to have you on board :wink:

Could you please show us the respective GPScript code involved in this? :thinking:

WIth virtual midi ports ce usually think of the built-in mechanism IAC (for Mac) and things like LoopMIDI (for Win).

You can even us the 127.0.0.1 localhost address, but you have to use a different “remote client” and “listening” port. OSC is basically a UDP communication, if you want to differentiate the sending and receiving direction, you have to use a different channel. :wink:

@David-san thanks for the speedy reply.

Could you please show use the respective GPScript code involved in this?

The Gig script :

On Song(oldSongIndex : integer, newSongIndex : integer)
    Print("SetGlobalTranspose(" + newSongIndex + ")")
    SetGlobalTranspose(newSongIndex)
End

The global rackspace script :

On SystemEvent(newTranspose : integer) Matching GlobalTransposeChanged
    Print("newTranspose = " + newTranspose)
End

switching from song index 0 to 1 I get

SetGlobalTranspose(1)
newTranspose = 0
newTranspose = 0

Don’t know why the callback gets called twice either. Using the UI instead of calling SetGlobalTranspose I get the expected callback value.

Well, I forgot about this, but it works so by design. If you try to modify the Global Transpose while in Setlist mode, it will be reset to the transport of your song. See the discussions, here:

It also explains why your callback is called twice. The first time because of your change, the second one because GP resets the transpose to make it match the one of the song.

Here’s another way to detect Song changes in the Global Rackspace. It works perfectly for my way of working.

I have a MIDI File Player in my Global Rackspace, and it is associated with a knob widget to select songs. In each Local Rackspace, I include a knob that is linked to the knob in the Global Rackspace, via the To Global Rackspace plugin. The local copy is locked and selects the correct song for that variation. (This means that you might need redundant Variations, if used by multiple songs, but this is low cost.)

You can now detect when that Widget changes, either in the Local or Global Rackspace.

It might not work for everybody, but I’m already using the MIDI File Player in this way.

Care to post an example? :slight_smile: