I’ve finally started the process of transitioning my stage setup, from my one Nord Modular G2X synth to a virtual-only GP5 setup. It’s going to take me months to translate all 45+ of my ‘80s band’s songs, from G2X performances (multis) to GP Songs, but it’s incredibly exciting! The G2X has fantastic modular flexibility for routing and switching, and now I’m seeing that GP does too, it’s just different and it’s been fascinating figuring out to do these things the GP way.
The song I’m currently working on is the only one in our live set that has been using only a GP5 rackspace for sounds (Pigments and Kontakt), triggered by the G2X which pre-processes all the MIDI channel routings and controller conversions. The bass notes can be doubled with either a Bari Sax note or a Strings note (both in a Kontakt multi), or they can be just bass. The G2X takes care of the switching between these three doubling modes by testing the position of the expression pedal: with the pedal in the first 10% of its range, I get bass notes only; the remaining range of the pedal is split in half to double the bass with Bari Sax (first half) or Strings (second half). It’s been challenging to do this in GP5, and I’ve finally finished a GPScript that works beautifully. [NOTE: technically I’m turning MidiIn blocks on and off, not plugins, as there’s only one plugin involved (Kontakt, holding a Multi), so I need to enable/disable the blocks that feed MIDI to individual instruments within the Multi.]
var KeyLabExpression : MidiInBlock
BariOver1 : MidiInBlock
BariOver2 : MidiInBlock
BariOver3 : MidiInBlock
StringsOver1 : MidiInBlock
StringsOver2 : MidiInBlock
StringsOver3 : MidiInBlock
Function StringNotesOff()
//+10 is the amount these MidiInBlocks are transposed
SendNow(StringsOver1, MakeNoteOffMessageEx(51+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(53+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(54+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(55+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(56+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(57+10, 1, 9))
SendNow(StringsOver2, MakeNoteOffMessageEx(58+10, 1, 9))
SendNow(StringsOver3, MakeNoteOffMessageEx(60+10, 1, 9))
SendNow(StringsOver3, MakeNoteOffMessageEx(61+10, 1, 9))
SendNow(StringsOver3, MakeNoteOffMessageEx(62+10, 1, 9))
SendNow(StringsOver3, MakeNoteOffMessageEx(63+10, 1, 9))
//Print("Sent NOTE OFFs")
/* the AllNotesOff() messages don't do anything, and Panic() turns off EVERYTHING
AllNotesOff(StringsOver1)
AllNotesOff(StringsOver2)
AllNotesOff(StringsOver3)
//Print("Sent ALLNOTEOFFs")
//Panic()
*/
End
On ControlChangeEvent (c : ControlChangeMessage) Matching 11 From KeyLabExpression
var m : int = GetCCValue(c)
var i : int = 0
If InSetlistView() Then
i = GetCurrentSongPartIndex()
Elsif InWiringView() Then
i = GetCurrentVariation()
End
SendNow(KeyLabExpression, c)
//Print(IntToString(m))
//Print(IntToString(GetCurrentSongPartIndex()))
//Print(IntToString(i))
//OpenLogWindow()
If i > 0 or m < 90 Then //very small first pedal range gives big numbers!
SetPluginBypassed(StringsOver1, True)
SetPluginBypassed(StringsOver2, True)
SetPluginBypassed(StringsOver3, True)
SetPluginBypassed(BariOver1, True)
SetPluginBypassed(BariOver2, True)
SetPluginBypassed(BariOver3, True)
Elsif m < 124 Then // up to about half of pedal range (standing flat)
StringNotesOff()
SetPluginBypassed(BariOver1, False)
SetPluginBypassed(BariOver2, False)
SetPluginBypassed(BariOver3, False)
Sleep(10) // seems to be the minimum time to keep plugins alive long enough for NoteOffs
SetPluginBypassed(StringsOver1, True)
SetPluginBypassed(StringsOver2, True)
SetPluginBypassed(StringsOver3, True)
Else // final half of pedal range
SetPluginBypassed(StringsOver1, False)
SetPluginBypassed(StringsOver2, False)
SetPluginBypassed(StringsOver3, False)
SetPluginBypassed(BariOver1, True)
SetPluginBypassed(BariOver2, True)
SetPluginBypassed(BariOver3, True)
End
//NOTE: refactor the plugin-bypass calls into a function
End
There were challenges. First of all, my new controller, the Arturia KeyLab mk3 61, spits out my Yamaha FC-7 expression pedal’s values in a logarithmic curve: the first 10% of the pedal’s range goes quickly from 0 to 90, the next 45% goes from 91 to 123, and the final 45% is squeezed into only four values, 124-127. This was difficult to set up with widget scaling, but super easy in a script. Secondly, the two Kontakt instruments behave differently. The Bari Sax is monophonic, which fortunately means that a note cuts out immediately when its MIDI In block is set to bypassed. But the Strings instrument, being polyphonic, does not do that – if a note is still being held when I switch its MIDI In block to bypassed, I get a stuck note. This had to be fixed in a script, and it took some doing. AllNotesOff() has no effect on the Strings instrument, so I had to send a NoteOff message for each note that could be played from the keyboard (fortunately only 13 notes). But this didn’t work because the NoteOff messages were not arriving until the plugin had already been set to bypassed. So I had to add the Sleep(10) call to keep the plugin alive long enough to receive the NoteOffs.
I’ve gotta say, GPScript is incredible! And great work on the documentation! I’m blown away, I really didn’t think GP would be able to do all the things I do on the G2X, but now I’m confident that it can. Amazing. GP5 rocks!