You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用python-mido转换Ableton Live 11导出MIDI的时间戳与BPM计算问题

问题解答:Ableton导出MIDI文件调制轮数据时间转换错误问题

问题原因解释

1. 参数误用:混淆了两个完全不同的MIDI参数

你之前的计算逻辑错误核心是误用了time_signature元消息里的clocks_per_click参数,该参数的作用是定义节拍器每一次点击对应的MIDI时钟滴答数,仅用于节拍器同步场景,和MIDI文件内事件的时间刻度转换毫无关系。
你应该使用的是**MIDI文件头自带的ticks_per_beat(每四分音符脉冲数,简称PPQN)**参数,这个参数是所有标准MIDI文件都内置的属性,不需要读取任何轨道内的元消息即可获取。

2. 计算逻辑错误

你代码里的quarter_note_seconds = beat_seconds / 4是完全错误的:BPM的定义就是「每分钟的拍数」,通用MIDI规范里的拍默认对应四分音符,因此beat_seconds = 60 / bpm本身就是单个四分音符的秒数,不需要额外除以4。
你之前代入24得到正确结果,只是两个错误叠加后刚好和测试文件的场景匹配,属于巧合,不具备通用性。

正确的时间转换方案(无需依赖set_tempo元消息)

因为你已经可以通过参数传入正确的BPM值,只需要按以下逻辑计算即可:

import mido

# 读取MIDI文件
mid = mido.MidiFile('目标MIDI文件路径.mid')
# 从文件头直接读取ticks_per_beat
ticks_per_beat = mid.ticks_per_beat
# 你传入的BPM参数
input_bpm = 120

# 单个四分音符对应的秒数
quarter_note_sec = 60 / input_bpm
# 单个MIDI tick对应的秒数
tick_sec = quarter_note_sec / ticks_per_beat

current_total_sec = 0
mod_wheel_table = []
for track in mid.tracks:
    for msg in track:
        # 累加当前消息的时间偏移
        current_total_sec += msg.time * tick_sec
        # 筛选调制轮控制消息(控制器编号固定为1)
        if msg.type == 'control_change' and msg.control == 1:
            mod_wheel_table.append([current_total_sec, msg.value])

最终输出的mod_wheel_table就是秒级时间戳+调制轮数值的二元列表,可直接导出为两列表格使用。


内容的提问来源于stack exchange,提问作者Joël Tuberosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:06:04