// TripleB, 05/2021
//
// 25-DEC-2021 added Playhead to Metronome Start Sync Control when switchung Rackspaces
// 08-JAN-2023 added LOWER CC 67
// 30-JUL-2023 added Next Song Injection
Var
UPPER : MidiInDevice // Handle to MIDI in devices setup by Rig Manager
LOWER : MidiInDevice
LOCALPORT : MidiInDevice
// -------------------------------------------------------------------------------------------------------
// Proceed to next Songpart, Loop if wanted
// Listen for matching CC
On ControlChangeEvent (c: ControlChangeMessage) matching 67 from LOWER // UPPER
Var currentPart, numParts : integer
partName : string
firstChar : string
// if(InSetlistView() && GetCCValue(c) > 64 && GetChannel(c) == 2) then // only handle in Setlist view!
if(InSetlistView() && GetCCValue(c) > 64 && GetChannel(c) == 1) then // only handle in Setlist view!
currentPart = GetCurrentSongPart()
numParts = GetSongPartCount()
//Print("Part " + IntToString(currentPart) + " of " + IntToString(numParts))
if currentPart < numParts -1 then // if we are before last Song Part just forward CC message
//InjectMidiEventViaRigManager(UPPER, c)
InjectMidiEventViaRigManager(LOWER, c)
else
//Print("Last") // otherwise directly jump to first song part
partName = GetSongPartName(currentPart)
//Print(partName)
firstChar = CopySubstring(partName, 0, 1)
if firstChar == "*" then
SetSongPart(0)
else
//Print("Last Songpart") // added 30-JUL-2023
InjectMidiEventViaRigManager(UPPER, MakeControlChangeMessageEx(56,127,2))
InjectMidiEventViaRigManager(UPPER, MakeControlChangeMessageEx(56,0,2))
end
end
else
//Print(“Not in Setlistview…”)
//InjectMidiEventViaRigManager(UPPER, c) // just forward CC message
InjectMidiEventViaRigManager(LOWER, c) // just forward CC message
end
End
// -------------------------------------------------------------------------------------------------------
// Inject a note off message (C1) to Local GP MIDI Port to enable/disable Playhead Sync to Metronome restart
On Rackspace(oldRackspaceIndex : integer, newRackspaceIndex : integer)
var ccm : MidiMessage
//Print("From: " + IntToString(oldRackspaceIndex) + " to: " + IntToString(newRackspaceIndex))
Print (“On Rackspace - Gig Script”)
// ccm = MakeNoteMessageEx(36, 0, 1) // Note Off C1
// InjectMidiEventViaRigManager(LOCALPORT, ccm)
End
// -------------------------------------------------------------------------------------------------------
Var
// Widgets from left/to right top/down blockwise
GPtoFrontButton : widget
//OnSongPrev, OnSongNext : Widget
GPShowGlobal : widget
UCButton : Widget
FCButton : Widget
CMButton : Widget
//Ui24RFlag : Widget
//MetronomeButton : widget --> Scriptlet
MetroSyncButton : widget // still here as used by Global Rack script...
PlayListBGM1Button : Widget
PlayListBGM2Button : Widget
PlayPauseButton : Widget
StopButton : Widget
SkipPrev, SkipNext : Widget
RSThrsKnob, RSThrsStr : widget
SEGainKnob, SEGainStr : Widget
SEThrsKnob, SEThrsStr : Widget
// Remaining Widgets which need defaults
GRDefaultsButton: Widget
GRMuteButton, GRMetronomeButton : Widget
GRMetronomeFader, GRFSEFader, GRRacksFader, GRMusicFader, GRMasterTrim : Widget
GRAuxLevel, GRBypassPBeq : Widget
/*GRWidthKnob,*/ GRBeatMode : Widget
USB_DIM : Widget
// internals for SE relative mode mapped Gain knob
myRamp : Ramp
step_width : double
rel_step : double
CCvalue : double
// MIDI blocks used
KeyLabMkII_MIDI : MidiInBlock
OnSong_MIDI : MidiOutBlock
LocalPort_MIDI : MidiInBlock
KeyLabSysExGlobal : MidiInBlock // used to insert SysEx MIDI ----> remove Event Blocking for SysEx!
// ---------------------------------------------------------------------------------------------------------
// Functions
// Main Function to create and send a System Exclusive Message for the desired colour LED
Function ResetCLED()
var
SysExMsg : String
SysExSend : SysexMessage
i : integer
now: double
for i := 0; i<16; i := i + 1 do
SysExMsg = "F0 00 20 6B 7F 42 02 00 16 " + IntToHexString(i+7*16) + " "
SysExMsg = SysExMsg + "00 03 03 F7"
SysExSend = SysExMsg
SendSysexInternalNow(KeyLabSysExGlobal, SysExSend)
now = TimeSinceStartup() // Little Guard Times
while TimeSinceStartup() < now + 10.0 do
end
end
end
// Set corresp. Threshold to text label widget
function SetThrsdB(target : widget, newValue : double)
var thres_dB : double
thrs_str : string
thres_dB = -30.0 + 30.0*newValue
thrs_str = DoubleToString(thres_dB, 1 ) + “dB”
//Print(thrs_str)
SetWidgetLabel(target, thrs_str)
end
// Relative CC Control helpers
function GetValues(value : integer) returns double
if value <= 63
then result = step_width * -1.0
else result = step_width
end
end
/*function AdjustWidget( m : ControlChangeMessage)
var widgetIndex : integer;
widgetValue : double
//widgetIndex = GetCCNumber(m) - 40 // Be careful you don't go out of range here or you'll crash GP
//Print ("Adjust OK")
If IsGeneratorEnabled(myRamp) == false
Then
rel_step = GetValues(GetCCValue(m))
End
myRamp.SetGeneratorLength(30); // 30ms
SetTimersRunning(true)
myRamp.EnableGenerator(True)
// CCvalue = GetValues(GetCCValue(m))
// widgetValue = GetWidgetValue(WidgetList[widgetIndex])
// SetWidgetValue(WidgetList[widgetIndex], widgetValue + rel_step)
CCvalue = GetValues(GetCCValue(m))
widgetValue = GetWidgetValue(SEGainKnob)
SetWidgetValue(SEGainKnob, widgetValue + rel_step)
end
*/
// ---------------------------------------------------------------------------------------------------------
// init all widgets
Initialization
SetGeneratorOneShot(myRamp, true) // Generator will only run once when triggered
// Also, check the SetGeneratorCoarseness function
// which can be used to control how often we get called back
// Choose values wisely! You’re trading accuracy against CPU cycles
step_width = 0.01
rel_step = 0
SetThrsdB(SEThrsStr, GetWidgetValue(SEThrsKnob))
SetThrsdB(RSThrsStr, GetWidgetValue(RSThrsKnob))
SetThrsdB(SEGainStr, GetWidgetValue(SEGainKnob))
End
// ---------------------------------------------------------------------------------------------------------
// Callbacks
// Get OSC Message
On OSCMessageReceived(message : OSCMessage) Matching “/KeyLabMK2Leds”
var
i : integer
msg : String
msg = OSC_GetArgAsString(message, 0)
Print(“KeyLabMkIILEDs: '” + msg + “'”)
if msg == “ResetPads” then ResetCLED(); end // react on dedicated Message…
End
// This gets called by the ramp generator as time passes
on TimePassing(timeX : integer, amplitudeY : double) from myRamp
rel_step = rel_step + CCvalue
//Print (rel_step)
//Print("X = " + timeX + " Y = " + amplitudeY)
end
/*
// Just doing three widgets here – adjust this and knoblist array to suit
On ControlChangeEvent(m : ControlChangeMessage) Matching 40 from KeyLabMkII_MIDI
AdjustWidget(m)
End
*/
// ---------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------
// Upper Rack / Mixer & Playbacks by Music
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from StopButton
var retVal : integer
if newValue == 1.0 then
retVal := Shell(“osascript -e ‘tell Application "Music" to stop’”)
SetWidgetValue(StopButton, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from PlayPauseButton
var retVal : integer
if newValue == 1.0 then
retVal := Shell(“osascript -e ‘tell Application "Music" to playpause’”)
SetWidgetValue(PlayPauseButton, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from SkipPrev
var retVal : integer
if newValue == 1.0 then
retVal := Shell(“osascript -e ‘tell Application "Music" to play (previous track)’”)
SetWidgetValue(SkipPrev, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from SkipNext
var retVal : integer
if newValue == 1.0 then
retVal := Shell(“osascript -e ‘tell Application "Music" to play (next track)’”)
SetWidgetValue(SkipNext, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from PlayListBGM1Button
var retVal : string
if newValue == 1.0 then
retVal := ShellEx(“osascript ‘/Users/alexander/Documents/Gig Performer/AppleScript/Playlist-BGM1.scpt’”)
Print("Playing: " + retVal)
SetWidgetValue(PlayListBGM1Button, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from PlayListBGM2Button
var retVal : string
if newValue == 1.0 then
retVal := ShellEx(“osascript ‘/Users/alexander/Documents/Gig Performer/AppleScript/Playlist-BGM2.scpt’”)
Print("Playing: " + retVal)
SetWidgetValue(PlayListBGM2Button, 0.0)
end
End
// ---------------------------------------------------------------------------------------------------------
// Screen Control Buttons
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from GPtoFrontButton
var retVal : string
if newValue == 1.0 then
//retVal := ShellEx(“osascript ‘/Users/alexander/Music/Gig Performer/AppleScript/GP-to-Front-GP4.scpt’”)
GPWindowToFront()
SetWidgetValue(GPtoFrontButton, 0.0)
//Print(“GPtfr”)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from GPShowGlobal
if newValue == 1.0 then
ShowGlobalRackspace(true)
else
ShowGlobalRackspace(false)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from UCButton
var retVal : string
if newValue == 1.0 then
/*
if GetWidgetValue(Ui24RFlag) < 0.5 then
retVal := ShellEx(“osascript -e ‘tell application "UniversalControl" to activate’”)
else
retVal := ShellEx(“osascript ‘/Users/alexander/Documents/Gig Performer/AppleScript/Open Ui24R.scpt’”)
end
*/
retVal := ShellEx(“osascript ‘/Users/alexander/Documents/Gig Performer/AppleScript/Open Ui24R.scpt’”)
SetWidgetValue(UCButton, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from FCButton
var retVal : string
if newValue == 1.0 then
// retVal := ShellEx(“osascript -e ‘tell application "Focusrite Control" to activate’”)
retVal := ShellEx(“osascript -e ‘tell application "Bandhelper" to activate’”)
SetWidgetValue(FCButton, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from CMButton
var retVal : string
if newValue == 1.0 then
retVal := ShellEx(“osascript ‘/Users/alexander/Documents/Gig Performer/AppleScript/FC Clear Meters.scpt’”)
SetWidgetValue(CMButton, 0.0)
end
End
// Set defaults to some controls
On WidgetValueChanged(newValue : double) from GRDefaultsButton
SetWidgetValue(GRMetronomeButton, 0.0) // turn off Metronome (incl Playhead)
SetWidgetValue(StopButton, 1.0)
EnablePlayhead(false)
SetWidgetValue(GRMetronomeFader, 0.2229719) // -20dB
SetWidgetValue(MetroSyncButton, 1.0)
SetWidgetValue(GRBeatMode, 1.0)
SetWidgetValue(GRFSEFader, 0.7074653) // set all faders to 0dB
SetWidgetValue(GRRacksFader, 0.7074653)
SetWidgetValue(GRMuteButton, 1.0) // Mute Apple Music
SetWidgetValue(GRMusicFader, 0.2229719) // -20dB
SetWidgetValue(GRBypassPBeq, 1.0) // disable SSL EQ
SetWidgetValue(GRAuxLevel, 0.2229719) // AUX Input -20dB
SetWidgetValue(GRBypassPBeq, 1.0)
SetWidgetValue(GRMasterTrim, 1.0)
SetWidgetValue(USB_DIM, 0.445)
//SetWidgetValue(GRWidthKnob, 0.5) // default Stereo Pan
End
/*
On WidgetValueChanged(newValue : double) from GRMusicFader
Print(newValue)
End
*/
// ---------------------------------------------------------------------------------------------------------
// OnSong Control Buttons
/*
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from OnSongPrev
var retVal : string
if newValue == 1.0 then
SendNowExternal(OnSong_MIDI, MakeNoteMessageEx(D#3, 100, 1))
SetWidgetValue(OnSongPrev, 0.0)
end
End
// Called when a widget value has changed
On WidgetValueChanged(newValue : double) from OnSongNext
var retVal : string
if newValue == 1.0 then
SendNowExternal(OnSong_MIDI, MakeNoteMessageEx(G3, 100, 1))
SetWidgetValue(OnSongNext, 0.0)
end
End
*/
// ---------------------------------------------------------------------------------------------------------
// Calculate SE Gain
On WidgetValueChanged(newValue : double) from SEGainKnob
SetThrsdB(SEGainStr, newValue)
End
// ---------------------------------------------------------------------------------------------------------
// Calculate Threshold LoudMax for SE
On WidgetValueChanged(newValue : double) from SEThrsKnob
SetThrsdB(SEThrsStr, newValue)
End
// ---------------------------------------------------------------------------------------------------------
// Calculate Threshold LoudMax for Rackspace
On WidgetValueChanged(newValue : double) from RSThrsKnob
SetThrsdB(RSThrsStr, newValue)
End
// ---------------------------------------------------------------------------------------------------------
// wrapper for metronone
//On WidgetValueChanged(newValue : double) from MetronomeButton
// if newValue >= 0.5 then
// EnableMetronome(true)
// EnablePlayhead(true)
// else
// EnableMetronome(false)
// EnablePlayhead(false)
// end
//End
// ---------------------------------------------------------------------------------------------------------
// Reset Playhead Start to sync/w Metronome when leaving Rackspace…
//On NoteEvent(m : NoteMessage) matching C1 from LocalPort_MIDI
//Print("Sync Playhead to Metronome omn Retart")
// SetWidgetValue(MetroSyncButton, 1.0)
//end
// ---------------------------------------------EOF---------------------------------------------------------