GPScript Callback on View Change

Hi! I’d like my foot controller to switch song parts regardless of whether or not i’m in panel or setlist view. I’ve got a little GPScript that kind of works (relevant part posted), by checking for 200ms if the switch from panel view to setlist view has happened, but it seems to be unreliable, even if I increase the while loop time to long values.

Any good way to do this?

On ControlChangeEvent(m : ControlChangeMessage) Matching 1 from Switcher
    ccVal = GetCCValue(m)
    If InPanelView() Then
        SwitchToSetlistView()
        dateTime = ClockTime() 
    while(dateTime + 200 >= ClockTime()) Do
        If InSetlistView() Then
            SetSongPart(ccVal)
            OSC_SendStringSpecific("/live/select_song_part",GetSongPartName(GetCCValue(m)),"192.168.1.100",9001)
        End
     End
1 Like

What is the problem you want to fix?

When I try to switch song parts, but I’m in panel view, I get the message “song parts can only be switched from setlist view”

That’s true, song parts are changed from the Setlist view. Why do you need the Panel view to change the song parts?

I suppose it’s fairly specific to my setup. I do a lot of improvised live looping, but I often times work within a template. So, I’ll be in a ‘song’, which has pre-selected sounds, but sometimes I like to break out of the ‘song’ and switch to alternate rackspaces, which I do by using an iPad to select a different rackspace from PanelView. After selecting these ‘non-song’ rackspaces, I still want to be able to jump to the next song part and pick up where I left off. A callback function on view change would allow me to do this, but I didn’t see one in the documentation, and my loop thing only works half of the time.

You have toggle Panel/Setlist view from the System Actions: System Actions

When you toggle back to the Setlist view, you’ll placed on the Song Part from which you toggled to the Panel view in the first place.

1 Like

Well, yeah, I’ve got that part, but the problem is that I want one button press to both switch to the Setlist view, and move to the next song part. Because it takes the computer a moment to switch to setlist view, the line of code to ‘switch song part’ is read while GP4 is switching, and hence it doesn’t work. If there was a callback, then I could switch song part after the callback is triggered, but without that, I have no way (other than a hacky timer script) to both switch to setlist view and jump to the next part.

Hm… That’s really a corner case. Would it make sense for you to create a new Setlist that will include all your Rackspaces as songs and variations as song parts? There is a little legacy trick that you could use, so you don’t enter Panel view at all.

Meh that’s kind of a pain in the ass. I can just program my controller to send a different message on button release (so on press, it switches view, on release it triggers the song part), that should get me there.

How about creating a global variable called something like “GoToSongPartOnSetlistEntry” that is normally 99999, but you set it to the song part you want to go to in your script in the original post if you’re not in setlist mode when you push your foot pedal.

Then in the OnSetlistModeChanged callback (or whatever the proper callback is) you check the GoToSongPartOnSetlistEntry variable, and if it’s 99999 you do nothing, but if it’s a lower number you switch to that song part and then reset your variable back to 99999.

Hm I don’t quite follow, but I’ll try that out. I don’t get why a while loop doesn’t work:

Elsif InPanelView() Then
SwitchToSetlistView()
time = ClockTime() + 2
While time > ClockTime() Do
SetSongPart(ccVal)
End

This seems to work once, but then freeze GP4 the next time it’s called.

Also, the ClockTime() method seems to return seconds, not MS.

Oops. I don’t see one. I use the external API, which does have one, so I assumed there was a GP Script equivalent.

Does the OnSong() callback get called when you re-enter setlist mode?

Or a bit of a hack, add a Widget and link it to the System Action “TogglePanelSetlistView.” When GP goes into SetList mode the widget will toggle on, so you could do the callback based on that.

On Song does not get called, and unfortunately the idea with the widget system action thing also wouldn’t work, because I still can’t switch song parts, because there’s still no callback after the switch to setlist view actually happens.

I don’t get why a while loop doesn’t work:

Elsif InPanelView() Then
SwitchToSetlistView()
time = ClockTime() + 2
While time > ClockTime() Do
SetSongPart(ccVal)
End

This seems to work once, but then freeze GP4 the next time it’s called.

Also, the ClockTime() method seems to return seconds, not MS.

@datalooper this is what this option does (Setlist options):

If you have the ‘Next Song Part’ in these options mapped to your controller, the above option should do what you are looking for.

That is definitely cool, and I can probably work with that, but it would be nice to be able to switch to a specific part rather than just next/prev if possible.

That switch must be done on the GUI thread and so the amount of time it takes will depend on what other GUI activity is in progress.

The only reason that function exists was to make it convenient for users to use hardware to switch modes with a button so as to continue editing - it was never intended to be used as part of a performance so a callback wasn’t considered. A call to switch the view should be the last item in a callback as statements following that call will execute before the switch due to the asynchronous nature of the call.

Yeah that all makes sense. Well, I vote for a callback, but I get that it’s an edge case and probably a low or no priority thing. Nonetheless, you are all awesome, and the fact that this thread is 15 messages deep in 24 hours is a testament to how amazing this community is.

Looking at the existing callbacks, when you switch to Setlist mode the On Songpart callback will be triggered. Therefore, I would get rid of any timer/delay concept and use this callback as the confirmation that you have successfully switched to setlist mode.

The basic logic is:

  • When your Switcher CC message is received, check if you are in Setlist mode.
  • If not in Setlist mode, store the pending song part index and switch to Setlist mode. Otherwise, if already in Setlist mode, switch to the received song part index.
  • When the next Songpart callback is triggered, check if there is a pending song part change. If so, switch to this song part index.

I don’t have any midi mapping in Options for the song part selection, as it is all managed by the script. All that’s needed is to give your controller a Rig Manager alias of ‘Switcher’.

Gig Script:

Var
    Switcher : MidiInDevice
    PendingPart : Integer = -1

On ControlChangeEvent(m : ControlChangeMessage) Matching 1 from Switcher
    PendingPart = GetCCValue(m)
    If !InSetlistMode() Then
        SwitchToSetlistView()
    Else
        SetSongPart(PendingPart)
        PendingPart = -1
    End
End

On Songpart(oldSongpartIndex : integer, newSongpartIndex : integer)
    If PendingPart >= 0 Then
        SetSongPart(PendingPart)
        PendingPart = -1
    End
End
2 Likes

Oh yeah! You are amazing. I did not realize song part got called. That’s perfect. Damn you are all awesome. Now I can just think about the music :slight_smile:

2 Likes

Yep, the commitment, generosity and enthusiasm of this user community never ceases to amaze me.