tell application "System Events" to tell (first application process whose bundle identifier is "com.figure53.QLab.5")
tell (first pop up button whose description is "patch")
click
set theNames to (get name of menu items of menu 1) as list
set defaultValue to (get value)
end tell
end tell
tell application "System Events" to tell (first application process whose bundle identifier is "com.figure53.QLab.5")
set menuElements to {}
tell group 1 of splitter group 1 of window 1
try
click (first button whose description is "Settings")
end try
tell (first pop up button whose description is "patch")
click
set theNames to (get name of menu items of menu 1) as list
set defValue to (get value)
click menu item defValue of menu 1
repeat with i from 1 to count of theNames
if ((item i of theNames) as text) contains (" - ") then
copy item i of theNames to end of menuElements
end if
end repeat
return menuElements
end tell
end tell
end tell
If the return variable is empty, then the display dialog should say "no midi patches".
It is all!
Yours,
Kalman
Begin forwarded message:From: "'Rich Walsh' via QLab" <ql...@googlegroups.com>Subject: Re: [QLab] midi menu listDate: 10 August 2025 at 17:50:57 BSTReply-To: ql...@googlegroups.comIt’s a bit obvious, but can’t you just filter the list?
tell application "System Events" to tell (first application process whose bundle identifier is "com.figure53.QLab.5")
tell group 1 of splitter group 1 of window 1 -- This would have been a useful line for you to have included, as without it your script does not work!
tell (first pop up button whose description is "patch")click
set theNames to name of menu items of menu 1 whose name begins with "Patch "
end tellend tellend tell
theNamesRich
--
Contact support anytime: sup...@figure53.com
User Group Code of Conduct: https://qlab.app/code-of-conduct/
Instagram: https://www.instagram.com/Figure53
Bluesky: https://bsky.app/profile/qlab.app
---
You received this message because you are subscribed to the Google Groups "QLab" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qlab+uns...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/qlab/c2f5b811-3ec3-4cf8-a5b9-26aad1397b92n%40googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/qlab/685c183c-20d8-4c61-949e-8d8d931b87a0n%40googlegroups.com.
use AppleScript version "2.4"
use scripting additions
use framework "CoreMIDI"
set countDevices to current application's MIDIGetNumberOfDestinations()
countDevices
#!/usr/bin/env swiftimport CoreMIDIimport Foundationfunc getDisplayName(_ obj: MIDIObjectRef) -> String? {var param: Unmanaged<CFString>?let status = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, ¶m)guard status == noErr, let name = param?.takeRetainedValue() else {return nil}return name as String}func isOffline(_ obj: MIDIObjectRef) -> Bool {var offline: Int32 = 0let status = MIDIObjectGetIntegerProperty(obj, kMIDIPropertyOffline, &offline)return status == noErr && offline != 0}func listActiveMIDIDestinations() {let count = MIDIGetNumberOfDestinations()var activeDestinations: [String] = []for i in 0..<count {let endpoint = MIDIGetDestination(i)if endpoint != 0 {if !isOffline(endpoint) {if let name = getDisplayName(endpoint) {activeDestinations.append(name)}}}}if activeDestinations.isEmpty {print("No active MIDI destinations found")} else {for name in activeDestinations {print("\(name)")}}}listActiveMIDIDestinations()
do shell script quoted form of (POSIX path of (path to desktop) & "listActiveMIDIDestinations.swift")
<string>midiPatches</string><dict><key>$class</key><dict><key>CF$UID</key><integer>128</integer></dict><key>NS.objects</key><array><dict><key>CF$UID</key><integer>209</integer></dict></array></dict><dict><key>$class</key><dict><key>CF$UID</key><integer>220</integer></dict><key>deviceDescription</key><dict><key>CF$UID</key><integer>212</integer></dict><key>name</key><dict><key>CF$UID</key><integer>211</integer></dict><key>uniqueID</key><dict><key>CF$UID</key><integer>210</integer></dict></dict><string>8DF8CA42-FB59-42F0-BFCE-DC6136767C24</string><string>Patch 1</string><dict><key>$class</key><dict><key>CF$UID</key><integer>205</integer></dict><key>NS.keys</key><array><dict><key>CF$UID</key><integer>213</integer></dict><dict><key>CF$UID</key><integer>214</integer></dict><dict><key>CF$UID</key><integer>215</integer></dict><dict><key>CF$UID</key><integer>5</integer></dict></array><key>NS.objects</key><array><dict><key>CF$UID</key><integer>216</integer></dict><dict><key>CF$UID</key><integer>217</integer></dict><dict><key>CF$UID</key><integer>218</integer></dict><dict><key>CF$UID</key><integer>219</integer></dict></array></dict><string>manufacturer</string><string>longName</string><string>name</string><string>Apple Inc.</string><string>IAC Driver IAC Bus 1</string><string>IAC Bus 1</string><integer>-1021912664</integer><dict><key>$classes</key><array><string>MIDIPatch</string><string>F53PasteboardObject</string><string>NSObject</string></array><key>$classname</key><string>MIDIPatch</string></dict>
how does Qlab read out what midi patches exist in the MAC system? How can I access this data without opening the Qlab app?
Querying the timecode tab of the cue list will give you the answer.
--
Contact support anytime: sup...@figure53.com
User Group Code of Conduct: https://qlab.app/code-of-conduct/
Instagram: https://www.instagram.com/Figure53
Bluesky: https://bsky.app/profile/qlab.app
---
You received this message because you are subscribed to the Google Groups "QLab" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qlab+uns...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/qlab/a71d709c-48a5-43a7-bbf9-84d28baba73cn%40googlegroups.com.
I would hazard a guess that QLab is not using AppleScript to retrieve the list of MTC sources available.
To view this discussion visit https://groups.google.com/d/msgid/qlab/8732AA82-BA29-4C2B-9619-62C3FA223DB9%40mac.com.
-- Assuming you have the Inspector showing the Timecode tab for a Cue List
tell application "System Events" to tell application process "QLab"
click pop up button 2 of group 1 of splitter group 1 of window 1
set availableChoices to name of menu items of menu 1 of pop up button 2 of group 1 of splitter group 1 of window 1
click (first menu item of menu 1 of pop up button 2 of group 1 of splitter group 1 of window 1 whose selected is true)
end tell
set sortedList to (item 1 of availableChoices as list) & bubbleSort(items 2 thru -1 of availableChoices)
tell application id "com.figure53.QLab.5"
set theChoice to choose from list sortedList with prompt "Choose MTC destination:"
if theChoice is false then error number -128 -- User cancelled
set mtc sync source name of current cue list of front workspace to theChoice as text
end tell
-- Subroutines
on bubbleSort(theList) -- Standard bubble sort subroutine
set listLength to count theList
set itemsSwapped to true
repeat while itemsSwapped
set itemsSwapped to false
repeat with i from 1 to listLength - 1
set itemOne to item i of theList
set itemTwo to item (i + 1) of theList
if itemOne > itemTwo then
set item i of theList to itemTwo
set item (i + 1) of theList to itemOne
set itemsSwapped to true
end if
end repeat
end repeat
return theList
end bubbleSort
#!/usr/bin/env swiftimport CoreMIDIimport Foundationfunc getDisplayName(_ obj: MIDIObjectRef) -> String? {var param: Unmanaged<CFString>?let status = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, ¶m)guard status == noErr, let name = param?.takeRetainedValue() else {return nil}return name as String}func isOffline(_ obj: MIDIObjectRef) -> Bool {var offline: Int32 = 0let status = MIDIObjectGetIntegerProperty(obj, kMIDIPropertyOffline, &offline)return status == noErr && offline != 0}
func listActiveMIDISources() {let count = MIDIGetNumberOfSources()var activeSources: [String] = []
for i in 0..<count {
let endpoint = MIDIGetSource(i)
if endpoint != 0 {if !isOffline(endpoint) {if let name = getDisplayName(endpoint) {
activeSources.append(name)}}}}if activeSources.isEmpty {
print("No active MIDI destinations found")} else {
for name in activeSources {print("\(name)")}}}listActiveMIDISources()
set availableChoices to paragraphs of (do shell script quoted form of (POSIX path of (path to desktop) & "listActiveMIDISources.swift"))
set sortedList to {"None"} & bubbleSort(availableChoices)
tell application id "com.figure53.QLab.5"
set theChoice to choose from list sortedList with prompt "Choose MTC destination:"
if theChoice is false then error number -128 -- User cancelled
set mtc sync source name of current cue list of front workspace to theChoice as text
end tell
-- Subroutines
on bubbleSort(theList) -- Standard bubble sort subroutine
set listLength to count theList
set itemsSwapped to true
repeat while itemsSwapped
set itemsSwapped to false
repeat with i from 1 to listLength - 1
set itemOne to item i of theList
set itemTwo to item (i + 1) of theList
if itemOne > itemTwo then
set item i of theList to itemTwo
set item (i + 1) of theList to itemOne
set itemsSwapped to true
end if
end repeat
end repeat
return theList
end bubbleSort
On 2 Sep 2025, at 13:57, Kalman Tarr <tarr....@gmail.com> wrote:
Hello Sam and Rich,
I understand the comment about the group's goal. I don't want to violate the basic principles. With your help, I learned a lot about scripting. As I wrote, I really like it! I try to approach a solution from several sides, examining the possibilities. This is where I fall.
Since I don't have a deep knowledge of the relationship between MAC OS and scripting languages, I admit that I'm asking stupid questions.
Sorry for that.
Why don't I start at the beginning? Because I've already solved the core of the problem. However, there are possible issues that apply to the creation of internal subroutines.
Well. Let me give you an example: we use an audio cue with markers. These markers need to give an instruction to an external device. In this case, a light control device. There, a light change needs to be performed. My solution: create a TimeCode cue.
First of all, two patches need to be set in the Settings Window MIDI interface. One that provides control between the two devices, the other is the internal patch (IAC driver).
Next, the script creates a MIDI cue series according to the number of markers.
MIDI cue
On the Settings tab, the passing patch must be set. Figure 1
On the Trigger tab, the timecode trigger must be set according to the markers. Figure 2
Of course, the settings shown on the main cue list timecode tab of the workspace. Figure 3
The task is to create the above work in a script.
When you start the timecode cue at the same time as the audio cue, it fires the MIDI cues one after the other.
This was the task. I hope my description is understandable. Sorry for the non-English terms.
I apologize again if I ask inappropriate questions.
Thanks for all the help, both of you!
Best regards.
Kalmanfig1
:
<MIDISettingsTab.jpg>fig2:
<MIDITriggerTab.png>fig3:<CL-TimeCodeTab.png>