Setlist Navigation & Scrolling from single CC

Hi all,

Just wanted to share this little script, maybe it’s useful to someone.

Objective
Navigate the setlist using a switcher connected to the Expression-Pedal input of a Keyboard. In other words, navigate the setlist from a single CC, where “0” → “Previous”, “127” → “Next” and “64” → “Nothing”. Continuous scrolling should be supported by holding next/previous over a longer period of time.

Parameters

  • CC number of the control to use for switching
  • Thresholds to fine-tune sensitivity
  • Scroll speed and delay before scrolling starts

Script

// Setlist Navigator
// Plug-In to navigate the setlist through CC commands

// Parameters
var controlCC("CC number"): Subrange Parameter 0..127 = 11
var lowerThreshold("Lower threshold CC value"): Subrange Parameter 0..63 = 20
var upperThreshold("Upper threshold CC value"): Subrange Parameter 64..127 = 107
var delayBeforeScrolling("Delay before scroll starts"): Subrange Parameter 1..8 = 2
var scrollSpeed("Scrolling Speed"): Subrange Parameter 1..10 = 2

// Variables & Initialization
var previousPressed: Boolean = false
var previousHandled: Boolean = false
var nextPressed: Boolean = false
var nextHandled: Boolean = false

var actionStarted: Boolean = false
var actionStartedAt: double = 0
var actionRunningForMilliseconds: double = 0
var lastScrollTime: double = 0

Initialization
    SetTimersRunning(true)
End

// Functions
Function handleNext()
    SongMoveDown()
    nextHandled = true
End

Function handlePrevious()
    SongMoveUp()
    previousHandled = true
End

Function handleScrolling(currentTime: double)
    var delayBeforeScrollingInMs: double = delayBeforeScrolling * 500
    var delayBetweenScrolls: double = 200 / scrollSpeed 
    
    var nextScrollTime: double = lastScrollTime + delayBetweenScrolls
    var canScroll: Boolean = currentTime > nextScrollTime
    
    If canScroll And actionRunningForMilliseconds > delayBeforeScrollingInMs Then
        select
            nextPressed Do
                handleNext()
            previousPressed Do
                handlePrevious()
        End
            
        lastScrollTime = currentTime
    End
End

Function setNextPressed(pressed: Boolean)
    nextPressed = pressed
End

Function setPreviousPressed(pressed: Boolean)
    previousPressed = pressed
End

Function startAction()
    actionStarted = true
    actionStartedAt = ClockTime()
    Print("Action started at " + actionStartedAt)
End

Function reset()
    nextPressed = false
    previousPressed = false
    actionStarted = false
    actionStartedAt = 0
    actionRunningForMilliseconds = 0
    lastScrollTime = 0
End

// Logic
On ControlChangeEvent(m : ControlChangeMessage)
    var incomingCC: Integer = GetCCNumber(m)
    var value: Integer = GetCCValue(m)
    
    If incomingCC == controlCC Then
        Select
            value > upperThreshold Do
                setNextPressed(true)
            value < lowerThreshold Do
                setPreviousPressed(true)
            true Do
                reset()
        End
        
        Select
            !nextHandled && nextPressed Do
                handleNext()
                startAction()
            !previousHandled && previousPressed Do
                handlePrevious()
                startAction()
            !nextPressed && !previousPressed Do
                nextHandled = false
                previousHandled = false
        End
    End
End

On TimerTick(milliseconds : double)
    var currentTime: double = ClockTime()
    If actionStarted Then
        actionRunningForMilliseconds = currentTime - actionStartedAt
        handleScrolling(currentTime)
    End
End

Let me know if anything can be improved, never wrote anything with GPScript before. **

Hardware**
In order to make it work, I reused an old guitar switcher pedal and wired it up with a couple of resistors like this:

  • R1 = 10k between Tip and Ring
  • R2 = 10k between Tip and Sleeve
  • “Next” Switch bypasses R1
  • “Previous” Switch bypasses R2

Please ignore the horrid soldering job… :wink:

Cheers, Daniel

1 Like