Files
ableton-mcp-ai/patch_runtime2.py

109 lines
4.3 KiB
Python

import sys
import os
path = r'C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\AbletonMCP_AI\abletonmcp_runtime.py'
with open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
start_idx = -1
end_idx = -1
for i, line in enumerate(lines):
if line.startswith(' def _create_arrangement_audio_pattern('):
start_idx = i
if line.startswith(' def _get_clip_info('):
end_idx = i
break
if start_idx != -1 and end_idx != -1:
new_method = ''' def _create_arrangement_audio_pattern(self, track_index, file_path, positions, name=""):
"""Create one or more arrangement audio clips from an absolute file path."""
try:
if track_index < 0 or track_index >= len(self._song.tracks):
raise IndexError("Track index out of range")
track = self._song.tracks[track_index]
if not hasattr(track, "create_audio_clip"):
raise RuntimeError("Track does not support arrangement audio clips")
resolved_path = os.path.abspath(str(file_path or ""))
if not resolved_path or not os.path.isfile(resolved_path):
raise IOError("Audio file not found: " + resolved_path)
if isinstance(positions, (int, float)):
positions = [positions]
elif not isinstance(positions, (list, tuple)):
positions = [0.0]
cleaned_positions = []
for position in positions:
try:
cleaned_positions.append(float(position))
except Exception:
continue
if not cleaned_positions:
cleaned_positions = [0.0]
created_positions = []
for index, position in enumerate(cleaned_positions):
success = False
created_clip = None
for attempt in range(3):
try:
created_clip = track.create_audio_clip(resolved_path, float(position))
except Exception as e:
self.log_message("Warning: Clip creation error at attempt " + str(attempt+1) + ": " + str(e))
import time
time.sleep(0.1)
clip_persisted = False
for clip in getattr(track, "arrangement_clips", getattr(track, "clips", [])):
if hasattr(clip, "start_time") and abs(float(clip.start_time) - float(position)) < 0.05:
clip_persisted = True
created_clip = clip
break
if clip_persisted:
success = True
break
self.log_message("Warning: Clip at " + str(position) + " not persisted on attempt " + str(attempt+1))
time.sleep(0.1)
if not success:
self.log_message("Error: Failed to persist clip at " + str(position) + " after 3 attempts")
continue
clip_name = str(name or "").strip()
if clip_name:
if len(cleaned_positions) > 1:
clip_name = clip_name + " " + str(index + 1)
try:
if created_clip is not None and hasattr(created_clip, "name"):
created_clip.name = clip_name
except Exception:
pass
created_positions.append(float(position))
return {
"track_index": int(track_index),
"file_path": resolved_path,
"created_count": len(created_positions),
"positions": created_positions,
"name": str(name or "").strip(),
}
except Exception as e:
self.log_message("Error creating arrangement audio pattern: " + str(e))
raise
'''
lines = lines[:start_idx] + [new_method] + lines[end_idx:]
with open(path, 'w', encoding='utf-8') as f:
f.writelines(lines)
print('Restored and patched successfully')
else:
print('Failed to find boundaries')