QLab Script - go ahead make MIDI

Contents

Table of Contents

This is an "external script" - see QLab Scripts and Macros

 
# Go ahead make MIDI 
 
--
 
set theExplanation to "This script will create a series of MIDI cues in the current QLab workspace which increment the parameter you specify.
 
For example, you can generate quickly a series of program change cues for recalling scenes on a mixing desk, " & ¬
    "or a series of note on cues for triggering a sampler or some other device."
 
--
 
(* This script is not designed to be run from within QLab!
 
v1.0: 11/01/10 Rich Walsh
 
<<< Last tested with: QLab 2.2.6; Mac OS 10.5.8 & 10.6.2 >>> *)
 
-- ###FIXME### QLab and/or the "script runner" is, generally, increasingly unresponsive to scripts the more cues there are in a workspace
 
-- Declarations
 
global dialogTitle
set dialogTitle to "Go ahead make MIDI"
 
set kindChoices to {"note on: fixed note number, incrementing velocity", "note on: fixed velocity, incrementing note number", ¬
    "control change: fixed controller number, incrementing value", "control change: fixed value, incrementing controller number", "program change"}
set kindCommands to {"Note On", "Note On", "Control Change", "Control Change", "Program Change"}
set kindByteOne to {"fixed", "variable", "fixed", "variable", "variable"}
set kindByteTwo to {"variable", "fixed", "variable", "fixed", ""}
set kindQuestionOne to {"Making note on cues with incrementing velocity." & return & return & "Enter the fixed note number:", ¬
    "Making note on cues with incrementing note number." & return & return & "Enter the note number for the first cue:", ¬
    "Making control change cues with incrementing value." & return & return & "Enter the fixed controller number:", ¬
    "Making control change cues with incrementing controller number." & return & return & "Enter the controller number for the first cue:", ¬
    "Making program change cues." & return & return & "Enter the program change number for the first cue:"}
set kindQuestionTwo to {"Making note on cues with incrementing velocity." & return & return & "Enter the velocity for the first cue:", ¬
    "Making note on cues with incrementing note number." & return & return & "Enter the fixed velocity:", ¬
    "Making control change cues with incrementing value." & return & return & "Enter the value for the first cue:", ¬
    "Making control change cues with incrementing controller number." & return & return & "Enter the fixed value:", ""}
set kindQuestionInc to {"Making note on cues with incrementing velocity." & return & return & "Enter the increment:", ¬
    "Making note on cues with incrementing note number." & return & return & "Enter the increment:", ¬
    "Making control change cues with incrementing value." & return & return & "Enter the increment:", ¬
    "Making control change cues with incrementing controller number." & return & return & "Enter the increment:", ¬
    "Making program change cues." & return & return & "Enter the increment:"}
set kindQuestionMany to {"Making note on cues with incrementing velocity." & return & return & "Enter the number of cues to create (maximum ", ¬
    "Making note on cues with incrementing note number." & return & return & "Enter the number of cues to create (maximum ", ¬
    "Making control change cues with incrementing value." & return & return & "Enter the number of cues to create (maximum ", ¬
    "Making control change cues with incrementing controller number." & return & return & "Enter the number of cues to create (maximum ", ¬
    "Making program change cues." & return & return & "Enter the number of cues to create (maximum "}
set channelChoices to {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"}
set howManyPossible to 1000 -- Limit series with increment of 0 to 1,000 cues!
 
-- Preamble
 
display dialog theExplanation & return & return & "Are you sure you wish to proceed?" with title dialogTitle with icon 1 ¬
    buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel"
 
-- Check QLab is running
 
tell application "System Events"
    set qLabIsRunning to count (every process whose name is "QLab")
end tell
if qLabIsRunning is 0 then
    display dialog "QLab is not running." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
    return
end if
 
tell application "QLab"
 
    activate
 
    -- Test for a workspace
 
    tell application "QLab"
        try
            get selected of front workspace
        on error
            display dialog "There is no workspace open in QLab." with title dialogTitle with icon 0 ¬
                buttons {"OK"} default button "OK" giving up after 5
            return
        end try
    end tell
 
    tell front workspace
 
        -- Find out what we're doing
 
        set theKind to my pickFromList(kindChoices, "Choose which kind of series would you like to make:")
 
        repeat with i from 1 to count kindChoices
            if theKind is item i of kindChoices then
                set theCommand to item i of kindCommands
                set byteOne to item i of kindByteOne
                set byteTwo to item i of kindByteTwo
                set questionOne to item i of kindQuestionOne
                set questionTwo to item i of kindQuestionTwo
                set questionInc to item i of kindQuestionInc
                set questionMany to item i of kindQuestionMany
                exit repeat
            end if
        end repeat
 
        set theChannel to my pickFromList(channelChoices, "Choose the MIDI channel for the cues:")
 
        set byteOneStart to my enterValidInteger(questionOne, 0, 127)
        set currentByteOne to byteOneStart
        set byteOneIncrement to 0
 
        if byteOne is "variable" then
            set byteOneIncrement to my enterValidInteger(questionInc, -byteOneStart, (127 - byteOneStart))
            if byteOneIncrement < 0 then
                set howManyPossible to 1 - (round (byteOneStart / byteOneIncrement) rounding up)
            else if byteOneIncrement > 0 then
                set howManyPossible to 1 + (round ((127 - byteOneStart) / byteOneIncrement) rounding down)
            end if
        end if
 
        if byteTwo is not "" then
            set byteTwoStart to my enterValidInteger(questionTwo, 0, 127)
        else
            set byteTwoStart to 0
        end if
        set currentByteTwo to byteTwoStart
        set byteTwoIncrement to 0
 
        if byteTwo is "variable" then
            set byteTwoIncrement to my enterValidInteger(questionInc, -byteTwoStart, (127 - byteTwoStart))
            if byteTwoIncrement < 0 then
                set howManyPossible to 1 - (round (byteTwoStart / byteTwoIncrement) rounding up)
            else if byteTwoIncrement > 0 then
                set howManyPossible to 1 + (round ((127 - byteTwoStart) / byteTwoIncrement) rounding down)
            end if
        end if
 
        set howMany to my enterValidInteger(questionMany & howManyPossible & "):", 1, howManyPossible)
 
        set customNaming to text returned of (display dialog "Enter a base string for naming the cues, or press return to use the default naming option:" with title ¬
            dialogTitle default answer "" buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel")
        if customNaming is not "" then
            if last character of customNaming is not " " and byteOneIncrement is not 0 and byteTwoIncrement is not 0 then
                set customNaming to customNaming & " "
            end if
        end if
 
        -- Do it
 
        display dialog "One moment caller..." with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 1
 
        repeat howMany times
            make type "MIDI"
            set newCue to last item of (selected as list)
            set channel of newCue to theChannel
            set byte one of newCue to currentByteOne
            set nameString to "Channel " & theChannel & " | " & theCommand & " | " & currentByteOne
            if theCommand is "Note On" then
                set command of newCue to note_on
                set byte two of newCue to currentByteTwo
                set nameString to nameString & " @ " & currentByteTwo
            else if theCommand is "Control Change" then
                set command of newCue to control_change
                set byte two of newCue to currentByteTwo
                set nameString to nameString & " @ " & currentByteTwo
            else if theCommand is "Program Change" then
                set command of newCue to program_change
            end if
            if customNaming is "" then
                set q name of newCue to nameString
            else if byteOneIncrement is not 0 then
                set q name of newCue to customNaming & currentByteOne
            else if byteTwoIncrement is not 0 then
                set q name of newCue to customNaming & currentByteTwo
            else
                set q name of newCue to customNaming
            end if
            set currentByteOne to currentByteOne + byteOneIncrement
            set currentByteTwo to currentByteTwo + byteTwoIncrement
        end repeat
 
    end tell
 
    activate
    display dialog "Done." with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 60
 
end tell
 
-- Subroutines
 
on pickFromList(theChoice, thePrompt)
    tell application "QLab"
        choose from list theChoice with prompt thePrompt with title dialogTitle default items item 1 of theChoice
        if the result is not false then
            return item 1 of the result
        else
            error number -128
        end if
    end tell
end pickFromList
 
on enterValidInteger(thePrompt, lowRange, highRange)
    tell application "QLab"
        set theQuestion to ""
        set validityCounter to false
        repeat until theQuestion is not ""
            set theQuestion to text returned of (display dialog thePrompt with title dialogTitle default answer "" buttons {"Cancel", "OK"} ¬
                default button "OK" cancel button "Cancel")
            try
                set theAnswer to theQuestion as integer
                if theAnswer < lowRange or theAnswer > highRange then
                    set theQuestion to ""
                end if
            on error
                set theQuestion to ""
            end try
            if validityCounter is false then
                set thePrompt to "Invalid response! " & return & return & thePrompt
                set validityCounter to true
            end if
        end repeat
        return theAnswer
    end tell
end enterValidInteger
 
(* END: Go ahead make MIDI *)