Checking MIDI Tracks with AppleScript in Logic Pro

Hello and thank you so much for your help! Something is wrong in my AppleScript, I get "Expected “then”, etc. but found identifier.". I'm trying to check midi tracks, if they have a region but that region is empty > delete the track, if it's not empty > rename the track based on that region's name.


tell application "Logic Pro"
    set doc to window 1
    set tracks to tracks of doc
    repeat with track in tracks
        set regions to regions of track
        set region to item 1 of regions
        if class of region is MIDI region and number of events of region is 0 then
            delete track
        else if class of region is MIDI region then
            set name of track to name of region
        end if
    end repeat
    save doc
end tell

UPDATE: Some empty regions are actually not empty as they have modulation data....so I'd need to look for regions that have 0 notes as a condition instead of empty regions....

Using UI Browser, I see that a region in Logic is UI element 1 of UI element 3 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 3 of window 1

So if I want to check all regions, do I need to write UI element 3 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 3 of window in the AppleScript? OUUUUUUUCH How do you guys know what to write?

You'll need someone who has Logic Pro installed and can look at its AppleScript dictionary, (if it has one, as your first snippet seems to imply).

UIBrowser is a guide to something quite different, which wouldn't enable you to directly delete or enable tracks – it would just let you simulate keystroke and mouse-click actions applied to the UI.

The immediate problem seems to be that MIDI region is not recognised as the name of a class.

Without a copy of Logic Pro to hand, I can't tell whether your

set doc to window 1

is plausible, but it looks unusual. Windows sometimes have a document property, but a window is not a document.

1 Like

It doesn't. :cry:

I actually had no idea AS could interact with regions at all!

Ah ...

Might this be a route ?

1 Like

If it can then it does have an AppleScript sdef (dictionary).

Drop it on Script Debugger and see...

I've never delved into midi scripting, but as I understand it, that's only available via the dedicated midi fx plugin and doesn't have wider implications.

Oh well... very sad...

I've been able to do what I needed in Python, removing the tracks that have 0 notes in the MIDI file but would love to better understand AppleScript in Logic Pro.

1 Like

Could you explain the Python method briefly?

I wasn't aware of the possibility! Anything else you can do with it in Logic?

Right now, I'm having issues with the ScriptBridge module in Python that seems to let me interact with Logic...

So, for this particular case, I'm working on the MIDI file only:

import os
import tkinter as tk
from tkinter import filedialog
from mido import MidiFile, MetaMessage, Message
import subprocess

# Create a file selection prompt
root = tk.Tk()
root.withdraw()
midi_file_path = filedialog.askopenfilename(filetypes=[("MIDI files", "*.mid")])

# Open the MIDI file and create an output MIDI file
midi_in = MidiFile(midi_file_path)
midi_out = MidiFile()

# Iterate through the tracks in the input MIDI file
for track in midi_in.tracks:
    # Create a new track in the output MIDI file
    out_track = midi_out.add_track()

    # Iterate through the messages in the input track
    for message in track:
        # If the message is not a control message or pitch bend message, add it to the output track
        if not (message.type in ['control_change', 'pitchwheel']):
            out_track.append(message)

# Get the base name and directory of the input MIDI file
midi_dir = os.path.dirname(midi_file_path)
midi_base = os.path.basename(midi_file_path)

# Create the path for the output MIDI file
out_path = os.path.join(midi_dir, "No Automations_" + midi_base)

# Save the output MIDI file
midi_out.save(out_path)

# Open the output MIDI file with Logic Pro X
subprocess.call(['open', '-a', '/Applications/Logic Pro X.app', out_path])
2 Likes

Is there a resource for all things Python/Logic? Interested to see what else is possible.

No Python here, but perhaps of interest.

Logic Pro X - SCRIPTER - MIDI to Plugin Parameters - YouTube

1 Like

It seems that you could fully control Logic with Python via a module called ScriptBridge Apple Developer Documentation, but I can't install it and don't understand why....

ERROR: Could not find a version that satisfies the requirement scriptbridge (from versions: none)

ERROR: No matching distribution found for scriptbridge"

Examples:

import ScriptBridge

# Connect to Logic Pro
logic = ScriptBridge.app("Logic Pro")

# Get the current project
project = logic.project()

# Get the list of tracks in the project
tracks = project.tracks()

# Print the names of the tracks
for track in tracks:
    print(track.name())

# Create a new track
new_track = project.create_track()

# Set the name of the track
new_track.name.set("My New Track")

# Add a new audio region to the track
new_region = new_track.create_region(0, 10)

# Set the name of the region
new_region.name.set("My New Region")

# Play the project
logic.play()

The Scripting Bridge brings AppleScriptObjC to AppleScript.

Where are your examples coming from?

The most authoritative place on macOS scripting is the Script Debugger Forum.

I'd ask there.

Oh maybe Scripting Bridge is diff than ScriptBridge...that's ideas from ChatGPT!...

There have been 3rd party scripting bridges over the years (JavaScript, Python, Ruby), and there's no telling where the code examples you have came from...

My knowledge of Python is only a smattering, so I'm not even able to evaluate what you've got.

1 Like

Hi @hnt007,

Your Python script is working directly with a MIDI-file (*.mid) After it does it's chore, it opens that file in Logic.

No scripting of a Mac app without a scripting dictionary, as CStone points out.

2 Likes

Hello!

Well the trick is to use script to run shortcuts once the app is activated or you can also use UI elements :+1:

ChatGPT gives unreal answers half of the time. You should probably delete that example. It causes more confusion.