QLab Script - Capture MIDI with MIDIPipe

This is an "external script" and script relies on a third-party application - see QLab Scripts and Macros

In this case, you will need to create a "pipe" in MIDIPipe that contains a "MIDI In" and an "AppleScript Trigger". Direct your "MIDI In" to the source of the MIDI and put this script in the "AppleScript Trigger". Generate some MIDI and watch the cues magically appear in QLab (hopefully). Good luck.

# Capture MIDI with MidiPipe 

--

# This script must be run in MidiPipe (http://www.subtlesoft.square7.net/MidiPipe.html).

# It will create a MIDI cue in QLab for each MIDI event processed by MidiPipe (including SysEx). There is no facility for capturing timing: just single events.
# If the MIDI stream is invalid (try putting "ABCDEF" in a MIDI SysEx Cue!) then the cues made from it will be invalid too. THERE IS NO ERROR CHECKING.

# Note: the script will not detect MSC as a distinct entity from general SysEx.

# YOU WILL NEED TO SET THE VARIABLE userQLabVersion APPROPRIATELY

--

# This script is not designed to be run from within QLab!
#
# v1.0: 04/02/10 Rich Walsh (proof of concept)
# v2.0: 24/05/13 First attempt at making this work for QLab 2 or 3; general tidying
#
# <<< Last tested with: QLab 2.3.9 / QLab 3.0.4; Mac OS 10.8.3; MidiPipe 1.4.6 >>> 

on runme(theMIDIMessage)

    (* !!!! YOU MUST CHOOSE YOUR VERSION OF QLAB BELOW !!!! *)
 
    set userQLabVersion to item 1 of {2, 3} -- Change this to "item 1" for QLab 2 or "item 2" for QLab 3; do NOT edit the contents of the list, just the item number
 
    (* - *)
 
    set qLabID to "com.figure53.QLab." & userQLabVersion
 
    set countMIDI to count theMIDIMessage
    set systemByte to item 1 of theMIDIMessage
 
    using terms from application "QLab 3" -- You will need a copy of QLab 3 on your system in order to compile the script
        (* You should be prompted to identify "QLab 3" when compiling in AppleScript Editor before pasting into MidiPipe *)
 
        tell application id qLabID
            tell front workspace
 
                if systemByte < 240 and countMIDI > 1 and countMIDI  3 then -- Standard messages
 
                    try
 
                        set theCommand to systemByte div 16
                        set theChannel to (systemByte mod 16) + 1
                        set byteOne to item 2 of theMIDIMessage
                        if countMIDI = 3 then
                            set byteTwo to item 3 of theMIDIMessage
                        else
                            set byteTwo to 0
                        end if
                        set byteCombo to byteTwo * 128 + byteOne
 
                        make type "MIDI" -- If the try gets this far we should be OK to make a new cue without making a mess
                        set newCue to last item of (selected as list)
 
                        if userQLabVersion = 3 then
                            set message type of newCue to voice
                        end if
 
                        set channel of newCue to theChannel
                        set byte one of newCue to byteOne
                        set byte two of newCue to byteTwo
 
                        if theCommand is 8 then -- Note Off ($8N)
                            set command of newCue to note_off
                            set nameString to "Channel " & theChannel & " | Note Off | " & byteOne & " @ " & byteTwo
                        else if theCommand is 9 then -- Note On ($9N)
                            set command of newCue to note_on
                            set nameString to "Channel " & theChannel & " | Note On | " & byteOne & " @ " & byteTwo
                        else if theCommand is 10 then -- Key Pressure ($AN)
                            set command of newCue to key_pressure
                            set nameString to "Channel " & theChannel & " | Key Pressure | " & byteOne & " @ " & byteTwo
                        else if theCommand is 11 then -- Control Change ($BN)
                            set command of newCue to control_change
                            set nameString to "Channel " & theChannel & " | Control Change | " & byteOne & " @ " & byteTwo
                        else if theCommand is 12 then -- Program Change ($CN) - one data byte
                            set command of newCue to program_change
                            set nameString to "Channel " & theChannel & " | Program Change | " & byteOne
                        else if theCommand is 13 then -- Channel Pressure ($DN) - one data byte
                            set command of newCue to channel_pressure
                            set nameString to "Channel " & theChannel & " | Channel Pressure | " & byteOne
                        else if theCommand is 14 then -- Pitch Bend ($EN)
                            set command of newCue to pitch_bend
                            set nameString to "Channel " & theChannel & " | Pitch Bend | " & (byteCombo - 8192)
                        end if
 
                        set q name of newCue to nameString
 
                    end try
 
                else if systemByte = 240 then -- 240=$F0 so SysEx
 
                    try
 
                        set nameString to ("SysEx | " & (countMIDI - 2) as string) & " byte"
                        if (countMIDI - 2) > 1 then
                            set nameString to nameString & "s"
                        end if
                        set theSysEx to ""
                        repeat with i from 2 to (countMIDI - 1)
                            set theSysEx to theSysEx & space & my decToHexOneByte(item i of theMIDIMessage)
                        end repeat
 
                        if userQLabVersion = 3 then
                            make type "MIDI" -- If the try gets this far we should be OK to make a new cue without making a mess
                            set newCue to last item of (selected as list)
                            set message type of newCue to sysex
                        else
                            make type "MIDI SysEx" -- If the try gets this far we should be OK to make a new cue without making a mess
                            set newCue to last item of (selected as list)
                        end if
 
                        set sysex message of newCue to theSysEx
                        set q name of newCue to nameString
 
                    end try
 
                end if
 
            end tell
        end tell
 
    end using terms from
 
end runme
 
on decToHexOneByte(decNumber)
    set hexCharacters to {"A", "B", "C", "D", "E", "F", "0"}
    set nibbleOne to decNumber div 16
    set nibbleTwo to decNumber mod 16
    if nibbleOne > 9 then
        set nibbleOne to item (nibbleOne - 9) of hexCharacters
    end if
    if nibbleTwo > 9 then
        set nibbleTwo to item (nibbleTwo - 9) of hexCharacters
    end if
    set hexString to (nibbleOne & nibbleTwo) as string
    return hexString
end decToHexOneByte
 
(* END: Capture MIDI with MidiPipe *)