ableton-live-mcp-control
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAbleton Live MCP Control
Ableton Live MCP 控制
Skill by ara.so — MCP Skills collection.
This MCP server enables AI agents to control Ableton Live through arbitrary Python execution in Ableton's Live Object Model. It provides both high-level tools for common tasks and low-level access to the entire Ableton API. The server allows creating MIDI clips, inserting audio files, adding tracks/devices, analyzing audio signals, generating spectrograms, and automating mixing/mastering workflows.
由ara.so开发的Skill——MCP Skills合集。
这个MCP服务器允许AI Agent通过在Ableton的Live Object Model中执行任意Python代码来控制Ableton Live。它既提供了用于常见任务的高级工具,也提供了对整个Ableton API的底层访问权限。该服务器支持创建MIDI片段、插入音频文件、添加轨道/设备、分析音频信号、生成频谱图以及自动化混音/母带制作工作流。
Installation
安装
The MCP server requires Ableton Live (tested with Suite 12.3.8) on macOS or Windows.
Automated Setup (Recommended):
Set up the https://github.com/bschoepke/ableton-live-mcp MCP server for meManual Setup:
- Clone the repository:
bash
git clone https://github.com/bschoepke/ableton-live-mcp.git
cd ableton-live-mcp- Install dependencies:
bash
pip install -r requirements.txt-
Install the Ableton Live Remote Script:
- Copy the folder to Ableton's Remote Scripts directory:
RemoteScripts/MCP- macOS:
~/Music/Ableton/User Library/Remote Scripts/ - Windows:
%USERPROFILE%\Documents\Ableton\User Library\Remote Scripts\
- macOS:
- Copy the
-
Configure Ableton Live:
- Open Ableton Live
- Go to Preferences → Link/Tempo/MIDI
- Add "MCP" as a Control Surface
-
Add to your MCP settings file (e.g.,):
claude_desktop_config.json
json
{
"mcpServers": {
"ableton-live": {
"command": "python",
"args": ["-m", "ableton_live_mcp"],
"cwd": "/path/to/ableton-live-mcp"
}
}
}Important: Back up your Live Set before using this MCP, as it can edit your set directly.
MCP服务器需要在macOS或Windows系统上运行Ableton Live(已在Suite 12.3.8版本测试)。
自动安装(推荐):
Set up the https://github.com/bschoepke/ableton-live-mcp MCP server for me手动安装:
- 克隆仓库:
bash
git clone https://github.com/bschoepke/ableton-live-mcp.git
cd ableton-live-mcp- 安装依赖:
bash
pip install -r requirements.txt-
安装Ableton Live远程脚本:
- 将文件夹复制到Ableton的远程脚本目录:
RemoteScripts/MCP- macOS:
~/Music/Ableton/User Library/Remote Scripts/ - Windows:
%USERPROFILE%\Documents\Ableton\User Library\Remote Scripts\
- macOS:
- 将
-
配置Ableton Live:
- 打开Ableton Live
- 进入偏好设置 → 链接/速度/MIDI
- 添加“MCP”作为控制表面
-
添加到你的MCP配置文件(例如):
claude_desktop_config.json
json
{
"mcpServers": {
"ableton-live": {
"command": "python",
"args": ["-m", "ableton_live_mcp"],
"cwd": "/path/to/ableton-live-mcp"
}
}
}重要提示: 使用此MCP前请备份你的Live工程,因为它可以直接编辑你的工程文件。
Key MCP Tools
核心MCP工具
evaluate_python
evaluate_python
Execute arbitrary Python code in Ableton Live's environment.
python
undefined在Ableton Live环境中执行任意Python代码。
python
undefinedExample: Get the current tempo
示例:获取当前速度
result = evaluate_python("Live.Song.Song.tempo")
result = evaluate_python("Live.Song.Song.tempo")
Example: Create a new MIDI track
示例:创建新的MIDI轨道
code = """
song = Live.Song.Song
track = song.create_midi_track(-1)
track.name = 'My New Track'
"""
evaluate_python(code)
undefinedcode = """
song = Live.Song.Song
track = song.create_midi_track(-1)
track.name = 'My New Track'
"""
evaluate_python(code)
undefinedcreate_midi_clip
create_midi_clip
Create a MIDI clip with notes on a specified track.
python
undefined在指定轨道上创建带有音符的MIDI片段。
python
undefinedCreate a simple C major chord progression
创建简单的C大调和弦进行
create_midi_clip(
track_index=0,
clip_slot=0,
length_bars=4,
notes=[
{"pitch": 60, "start": 0.0, "duration": 1.0, "velocity": 100}, # C
{"pitch": 64, "start": 0.0, "duration": 1.0, "velocity": 100}, # E
{"pitch": 67, "start": 0.0, "duration": 1.0, "velocity": 100}, # G
]
)
undefinedcreate_midi_clip(
track_index=0,
clip_slot=0,
length_bars=4,
notes=[
{"pitch": 60, "start": 0.0, "duration": 1.0, "velocity": 100}, # C
{"pitch": 64, "start": 0.0, "duration": 1.0, "velocity": 100}, # E
{"pitch": 67, "start": 0.0, "duration": 1.0, "velocity": 100}, # G
]
)
undefinedinsert_audio_file
insert_audio_file
Insert an audio file into a track.
python
undefined将音频文件插入到轨道中。
python
undefinedInsert a vocal sample
插入人声采样
insert_audio_file(
track_index=1,
clip_slot=0,
file_path="/path/to/vocal.wav"
)
undefinedinsert_audio_file(
track_index=1,
clip_slot=0,
file_path="/path/to/vocal.wav"
)
undefinedadd_track
add_track
Add a new audio or MIDI track with optional devices.
python
undefined添加带有可选设备的新音频或MIDI轨道。
python
undefinedAdd a MIDI track with a synth
添加带有合成器的MIDI轨道
add_track(
track_type="midi",
name="Bass Synth",
devices=["Operator", "Reverb"]
)
undefinedadd_track(
track_type="midi",
name="Bass Synth",
devices=["Operator", "Reverb"]
)
undefinedget_live_set_info
get_live_set_info
Get comprehensive information about the current Live Set.
python
undefined获取当前Live工程的全面信息。
python
undefinedGet full Live Set details
获取完整的Live工程详情
info = get_live_set_info()
info = get_live_set_info()
Returns: tracks, scenes, tempo, time signature, devices, etc.
返回内容:轨道、场景、速度、拍号、设备等
undefinedundefinedcapture_audio
capture_audio
Capture audio from an "Agent Audio Tap" Max for Live device.
python
undefined从“Agent Audio Tap”Max for Live设备捕获音频。
python
undefinedCapture 10 seconds of audio from track 0
从轨道0捕获10秒音频
audio_data = capture_audio(
track_index=0,
device_index=0,
duration_seconds=10.0
)
audio_data = capture_audio(
track_index=0,
device_index=0,
duration_seconds=10.0
)
Returns: base64-encoded WAV data
返回:base64编码的WAV数据
undefinedundefinedget_device_parameters
get_device_parameters
Get all parameters for a device on a track.
python
undefined获取轨道上某个设备的所有参数。
python
undefinedGet parameters for the first device on track 0
获取轨道0上第一个设备的参数
params = get_device_parameters(
track_index=0,
device_index=0
)
undefinedparams = get_device_parameters(
track_index=0,
device_index=0
)
undefinedset_device_parameter
set_device_parameter
Set a device parameter value.
python
undefined设置设备参数值。
python
undefinedSet the cutoff frequency of a filter
设置滤波器的截止频率
set_device_parameter(
track_index=0,
device_index=0,
parameter_name="Filter Freq",
value=1200.0
)
undefinedset_device_parameter(
track_index=0,
device_index=0,
parameter_name="Filter Freq",
value=1200.0
)
undefinedCommon Patterns
常见使用模式
Creating a Complete Track with Instruments
创建包含乐器的完整轨道
python
undefinedpython
undefinedCreate a bass track with Operator synth
创建带有Operator合成器的贝斯轨道
code = """
song = Live.Song.Song
track = song.create_midi_track(-1)
track.name = 'Bass'
code = """
song = Live.Song.Song
track = song.create_midi_track(-1)
track.name = 'Bass'
Add Operator synth
添加Operator合成器
operator = track.devices[0] # Default instrument
operator.name = 'Bass Synth'
operator = track.devices[0] # 默认乐器
operator.name = 'Bass Synth'
Create a bass pattern
创建贝斯节奏型
clip = track.clip_slots[0].create_clip(4.0)
clip.name = 'Bass Pattern'
clip = track.clip_slots[0].create_clip(4.0)
clip.name = 'Bass Pattern'
Add notes
添加音符
for i in range(16):
if i % 4 == 0:
clip.set_notes(((36, i * 0.25, 0.25, 100, False),)) # C1 on downbeats
"""
evaluate_python(code)
undefinedfor i in range(16):
if i % 4 == 0:
clip.set_notes(((36, i * 0.25, 0.25, 100, False),)) # 重拍位置的C1
"""
evaluate_python(code)
undefinedAnalyzing Audio with Spectrograms
用频谱图分析音频
python
undefinedpython
undefinedFirst, add Agent Audio Tap device to a track in Ableton
首先,在Ableton的轨道中添加Agent Audio Tap设备
Then capture and analyze audio
然后捕获并分析音频
import base64
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
import base64
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
Capture audio
捕获音频
audio_b64 = capture_audio(track_index=0, device_index=0, duration_seconds=10.0)
audio_b64 = capture_audio(track_index=0, device_index=0, duration_seconds=10.0)
Decode audio
解码音频
audio_bytes = base64.b64decode(audio_b64)
audio_bytes = base64.b64decode(audio_b64)
Generate spectrogram
生成频谱图
code = """
import wave
import numpy as np
from scipy import signal
with wave.open('temp.wav', 'rb') as wf:
audio_data = np.frombuffer(wf.readframes(wf.getnframes()), dtype=np.int16)
sample_rate = wf.getframerate()
f, t, Sxx = signal.spectrogram(audio_data, sample_rate)
code = """
import wave
import numpy as np
from scipy import signal
with wave.open('temp.wav', 'rb') as wf:
audio_data = np.frombuffer(wf.readframes(wf.getnframes()), dtype=np.int16)
sample_rate = wf.getframerate()
f, t, Sxx = signal.spectrogram(audio_data, sample_rate)
Save or display spectrogram
保存或显示频谱图
"""
undefined"""
undefinedSetting Up a Mastering Chain
设置母带处理链
python
undefinedpython
undefinedCreate master processing chain
创建母带处理链
code = """
song = Live.Song.Song
master = song.master_track
code = """
song = Live.Song.Song
master = song.master_track
Add EQ Eight
添加EQ Eight
eq = master.devices.append(song.create_device('EQ Eight'))
eq = master.devices.append(song.create_device('EQ Eight'))
Add Compressor
添加压缩器
comp = master.devices.append(song.create_device('Compressor'))
comp.parameters[0].value = -12.0 # Threshold
comp = master.devices.append(song.create_device('Compressor'))
comp.parameters[0].value = -12.0 # 阈值
Add Limiter
添加限制器
limiter = master.devices.append(song.create_device('Limiter'))
limiter.parameters[1].value = -0.3 # Ceiling
"""
evaluate_python(code)
undefinedlimiter = master.devices.append(song.create_device('Limiter'))
limiter.parameters[1].value = -0.3 # 上限
"""
evaluate_python(code)
undefinedCreating MIDI Clips Programmatically
程序化创建MIDI片段
python
undefinedpython
undefinedGenerate a chord progression
生成和弦进行
code = """
import Live
song = Live.Song.Song
track = song.tracks[0]
clip = track.clip_slots[0].create_clip(8.0)
code = """
import Live
song = Live.Song.Song
track = song.tracks[0]
clip = track.clip_slots[0].create_clip(8.0)
Chord progression: C - Am - F - G
和弦进行:C - Am - F - G
chords = [
[(60, 64, 67), 0.0], # C major
[(57, 60, 64), 2.0], # A minor
[(53, 57, 60), 4.0], # F major
[(55, 59, 62), 6.0], # G major
]
notes = []
for chord, start_beat in chords:
for pitch in chord:
notes.append((pitch, start_beat, 2.0, 100, False))
clip.set_notes(tuple(notes))
clip.name = 'Chord Progression'
"""
evaluate_python(code)
undefinedchords = [
[(60, 64, 67), 0.0], # C大调
[(57, 60, 64), 2.0], # A小调
[(53, 57, 60), 4.0], # F大调
[(55, 59, 62), 6.0], # G大调
]
notes = []
for chord, start_beat in chords:
for pitch in chord:
notes.append((pitch, start_beat, 2.0, 100, False))
clip.set_notes(tuple(notes))
clip.name = 'Chord Progression'
"""
evaluate_python(code)
undefinedAutomating Mixing Parameters
自动化混音参数
python
undefinedpython
undefinedCreate automation for volume fadeout
创建音量淡出自动化
code = """
song = Live.Song.Song
track = song.tracks[0]
clip = track.clip_slots[0].clip
code = """
song = Live.Song.Song
track = song.tracks[0]
clip = track.clip_slots[0].clip
Create volume automation
创建音量自动化
envelope = clip.automation_envelope(track.mixer_device.volume)
envelope.insert_step(0.0, 0, 1.0) # Start at full volume
envelope.insert_step(7.0, 0, 0.0) # Fade to silence at bar 7
"""
evaluate_python(code)
undefinedenvelope = clip.automation_envelope(track.mixer_device.volume)
envelope.insert_step(0.0, 0, 1.0) # 开始时音量最大
envelope.insert_step(7.0, 0, 0.0) # 第7小节时淡出至静音
"""
evaluate_python(code)
undefinedWorking with Audio Effects
音频效果使用
python
undefinedpython
undefinedAdd and configure a reverb chain
添加并配置混响链
code = """
song = Live.Song.Song
track = song.tracks[1]
code = """
song = Live.Song.Song
track = song.tracks[1]
Add Reverb
添加混响
reverb = track.devices.append(song.create_device('Reverb'))
reverb.parameters[0].value = 3.5 # Decay time
reverb.parameters[1].value = 0.3 # Dry/Wet
reverb = track.devices.append(song.create_device('Reverb'))
reverb.parameters[0].value = 3.5 # 衰减时间
reverb.parameters[1].value = 0.3 # 干湿比
Add EQ after reverb
在混响后添加EQ
eq = track.devices.append(song.create_device('EQ Eight'))
eq = track.devices.append(song.create_device('EQ Eight'))
High-pass filter to clean up reverb
高通滤波器清理混响低频
eq.parameters[1].value = 300.0 # Frequency
"""
evaluate_python(code)
undefinedeq.parameters[1].value = 300.0 # 频率
"""
evaluate_python(code)
undefinedSidechain Compression Setup
侧链压缩设置
python
undefinedpython
undefinedSet up sidechain compression (kick to bass)
设置侧链压缩底鼓控制贝斯
code = """
song = Live.Song.Song
bass_track = song.tracks[1]
kick_track = song.tracks[0]
code = """
song = Live.Song.Song
bass_track = song.tracks[1]
kick_track = song.tracks[0]
Add Compressor to bass track
为贝斯轨道添加压缩器
comp = bass_track.devices.append(song.create_device('Compressor'))
comp = bass_track.devices.append(song.create_device('Compressor'))
Enable sidechain
启用侧链
comp.parameters[9].value = 1.0 # Sidechain enabled
comp.parameters[9].value = 1.0 # 侧链启用
Set sidechain source to kick track
设置侧链源为底鼓轨道
available_routings = comp.available_input_routing_types
for routing in available_routings:
if 'Audio From' in routing.display_name and kick_track.name in routing.display_name:
comp.input_routing_type = routing
break
available_routings = comp.available_input_routing_types
for routing in available_routings:
if 'Audio From' in routing.display_name and kick_track.name in routing.display_name:
comp.input_routing_type = routing
break
Configure compression
配置压缩参数
comp.parameters[0].value = -18.0 # Threshold
comp.parameters[1].value = 4.0 # Ratio
comp.parameters[2].value = 0.1 # Attack
comp.parameters[3].value = 0.2 # Release
"""
evaluate_python(code)
undefinedcomp.parameters[0].value = -18.0 # 阈值
comp.parameters[1].value = 4.0 # 比率
comp.parameters[2].value = 0.1 # 启动时间
comp.parameters[3].value = 0.2 # 释放时间
"""
evaluate_python(code)
undefinedWorking with Third-Party Plugins
第三方插件使用
python
undefinedpython
undefinedAdd VST/AU instruments
添加VST/AU乐器
code = """
song = Live.Song.Song
track = song.tracks[0]
code = """
song = Live.Song.Song
track = song.tracks[0]
Add Serum (example)
添加Serum示例
serum = track.devices.append(song.create_device('Serum'))
serum = track.devices.append(song.create_device('Serum'))
Add Keyscape for piano
添加Keyscape钢琴
keyscape = track.devices.append(song.create_device('Keyscape'))
"""
evaluate_python(code)
undefinedkeyscape = track.devices.append(song.create_device('Keyscape'))
"""
evaluate_python(code)
undefinedQuerying Live Set Information
查询Live工程信息
python
undefinedpython
undefinedGet detailed information about all tracks
获取所有轨道的详细信息
info = get_live_set_info()
info = get_live_set_info()
The response includes:
返回内容包括:
- tempo
- 速度
- time_signature
- 拍号
- tracks (name, type, devices, clip_slots)
- 轨道名称、类型、设备、片段槽
- scenes
- 场景
- master_track info
- 主轨道信息
- return_tracks
- 返回轨道
Example: Find all tracks with a specific device
示例:查找所有带有特定设备的轨道
code = """
song = Live.Song.Song
tracks_with_reverb = []
for i, track in enumerate(song.tracks):
for device in track.devices:
if 'Reverb' in device.name:
tracks_with_reverb.append((i, track.name))
break
result = tracks_with_reverb
"""
result = evaluate_python(code)
undefinedcode = """
song = Live.Song.Song
tracks_with_reverb = []
for i, track in enumerate(song.tracks):
for device in track.devices:
if 'Reverb' in device.name:
tracks_with_reverb.append((i, track.name))
break
result = tracks_with_reverb
"""
result = evaluate_python(code)
undefinedAudio Signal Analysis
音频信号分析
python
undefinedpython
undefinedAnalyze frequency content of a track
分析轨道的频率内容
code = """
import numpy as np
from scipy import signal as sp_signal
code = """
import numpy as np
from scipy import signal as sp_signal
Assuming audio is captured via Agent Audio Tap
假设音频是通过Agent Audio Tap设备捕获的
(audio_data would be from capture_audio tool)
audio_data来自capture_audio工具
def analyze_frequency_content(audio_data, sample_rate=44100):
# Compute FFT
fft = np.fft.rfft(audio_data)
freqs = np.fft.rfftfreq(len(audio_data), 1/sample_rate)
magnitudes = np.abs(fft)
# Find dominant frequencies
peaks, _ = sp_signal.find_peaks(magnitudes, height=np.max(magnitudes)*0.1)
dominant_freqs = freqs[peaks]
return {
'dominant_frequencies': dominant_freqs.tolist(),
'frequency_range': [freqs[0], freqs[-1]],
'peak_magnitude': float(np.max(magnitudes))
}def analyze_frequency_content(audio_data, sample_rate=44100):
# 计算FFT
fft = np.fft.rfft(audio_data)
freqs = np.fft.rfftfreq(len(audio_data), 1/sample_rate)
magnitudes = np.abs(fft)
# 查找主导频率
peaks, _ = sp_signal.find_peaks(magnitudes, height=np.max(magnitudes)*0.1)
dominant_freqs = freqs[peaks]
return {
'dominant_frequencies': dominant_freqs.tolist(),
'frequency_range': [freqs[0], freqs[-1]],
'peak_magnitude': float(np.max(magnitudes))
}Use this function after capturing audio
捕获音频后使用此函数
"""
undefined"""
undefinedConfiguration
配置
The MCP server connects to Ableton via OSC (Open Sound Control) on localhost.
Default settings:
- OSC receive port: 11000
- OSC send port: 11001
To change ports, modify the Remote Script configuration in Ableton or update the MCP server settings.
Environment Variables:
- No specific environment variables required
- Ensure Python path includes the MCP module directory
MCP服务器通过本地主机上的OSC(Open Sound Control)连接到Ableton。
默认设置:
- OSC接收端口:11000
- OSC发送端口:11001
如需修改端口,请在Ableton中修改远程脚本配置或更新MCP服务器设置。
环境变量:
- 无需特定环境变量
- 确保Python路径包含MCP模块目录
Troubleshooting
故障排除
MCP Not Connecting to Ableton
MCP无法连接到Ableton
- Verify the MCP Remote Script is installed in Ableton's Remote Scripts folder
- Check that "MCP" is selected as a Control Surface in Ableton Preferences
- Restart Ableton Live after installing the Remote Script
- Check firewall settings allow local OSC communication
- 确认MCP远程脚本已安装在Ableton的远程脚本文件夹中
- 检查Ableton偏好设置中已选择“MCP”作为控制表面
- 安装远程脚本后重启Ableton Live
- 检查防火墙设置允许本地OSC通信
Evaluation Errors
执行错误
python
undefinedpython
undefinedAlways wrap risky code in try/except when using evaluate_python
使用evaluate_python时始终将风险代码包裹在try/except中
code = """
try:
song = Live.Song.Song
# Your code here
except Exception as e:
result = f'Error: {str(e)}'
"""
undefinedcode = """
try:
song = Live.Song.Song
# 你的代码
except Exception as e:
result = f'Error: {str(e)}'
"""
undefinedAudio Capture Issues
音频捕获问题
- Ensure "Agent Audio Tap" Max for Live device is added to the track
- Verify the device is enabled and receiving audio
- Check that the track is not muted
- Confirm audio is actually playing during capture
- 确认轨道中已添加“Agent Audio Tap”Max for Live设备
- 验证设备已启用并正在接收音频
- 检查轨道未被静音
- 确认捕获期间音频正在播放
Device Not Found
设备未找到
python
undefinedpython
undefinedList all devices on a track first
先列出轨道上的所有设备
code = """
song = Live.Song.Song
track = song.tracks[0]
device_names = [d.name for d in track.devices]
result = device_names
"""
devices = evaluate_python(code)
undefinedcode = """
song = Live.Song.Song
track = song.tracks[0]
device_names = [d.name for d in track.devices]
result = device_names
"""
devices = evaluate_python(code)
undefinedParameter Changes Not Taking Effect
参数修改未生效
- Ensure parameter names match exactly (case-sensitive)
- Some parameters may have limited ranges - check min/max values
- Verify the device is enabled
- Use to see available parameters
get_device_parameters()
- 确保参数名称完全匹配区分大小写
- 部分参数可能有范围限制,请检查最小值/最大值
- 验证设备已启用
- 使用查看可用参数
get_device_parameters()
Live Set Corruption Prevention
防止Live工程损坏
- Always back up your Live Set before extensive MCP operations
- Test code on a duplicate/test project first
- Use version control for your Live Sets
- Save frequently during AI-assisted production sessions
- 在进行大量MCP操作前始终备份你的Live工程
- 先在副本/测试项目上测试代码
- 为你的Live工程使用版本控制
- 在AI辅助制作会话期间频繁保存
Advanced Usage
高级用法
Custom Python Libraries
自定义Python库
You can import and use additional Python libraries in :
evaluate_pythonpython
code = """
import numpy as np
import math你可以在中导入并使用额外的Python库:
evaluate_pythonpython
code = """
import numpy as np
import mathGenerate MIDI notes based on harmonic series
基于泛音列生成MIDI音符
fundamental = 220 # A3
harmonics = [fundamental * i for i in range(1, 9)]
fundamental = 220 # A3
harmonics = [fundamental * i for i in range(1, 9)]
Convert to MIDI note numbers
转换为MIDI音符编号
midi_notes = [int(round(69 + 12 * math.log2(f / 440))) for f in harmonics]
result = midi_notes
"""
notes = evaluate_python(code)
undefinedmidi_notes = [int(round(69 + 12 * math.log2(f / 440))) for f in harmonics]
result = midi_notes
"""
notes = evaluate_python(code)
undefinedBatch Processing Multiple Tracks
批量处理多个轨道
python
undefinedpython
undefinedApply same effect chain to multiple tracks
为多个轨道应用相同的效果链
code = """
song = Live.Song.Song
effect_chain = ['EQ Eight', 'Compressor', 'Reverb']
for i in range(4): # First 4 tracks
track = song.tracks[i]
for effect_name in effect_chain:
track.devices.append(song.create_device(effect_name))
"""
evaluate_python(code)
undefinedcode = """
song = Live.Song.Song
effect_chain = ['EQ Eight', 'Compressor', 'Reverb']
for i in range(4): # 前4个轨道
track = song.tracks[i]
for effect_name in effect_chain:
track.devices.append(song.create_device(effect_name))
"""
evaluate_python(code)
undefined