使用pretty-midi加载MIDI遇最大tick值错误,求解决方法
解决pretty-midi加载大tick MIDI文件的报错问题
出现这个错误是因为pretty-midi源码里硬编码了一个tick上限(默认是10^7),你的文件tick值超过了这个阈值,但VLC这类播放器不做这个严格检查,所以能正常播放。下面是几个可行的解决办法:
1. 直接修改pretty-midi的源码阈值
- 先查找到pretty-midi的安装路径,执行命令:
pip show pretty-midi,输出里的Location字段就是路径 - 找到该路径下的
pretty_midi/__init__.py文件并打开 - 搜索触发错误的代码行,找到类似
if largest_tick > 10**7:的判断,把10**7改成更大的数值(比如10**8),保存文件 - 重启Python环境后重新运行你的加载代码即可
2. 绕过pretty-midi的上层检查(无需改源码)
如果你不想动源码,可以直接调用底层解析逻辑,手动构建PrettyMIDI对象。示例代码如下:
import pretty_midi import mido # 用mido直接读取MIDI文件 mid = mido.MidiFile(midi_file) # 手动创建PrettyMIDI实例 pm = pretty_midi.PrettyMIDI(ticks_per_beat=mid.ticks_per_beat) # 遍历音轨转换为pretty-midi的Instrument对象 for i, track in enumerate(mid.tracks): instrument = pretty_midi.Instrument(program=0) # 可根据实际音轨的program调整 current_time = 0 note_start_map = {} for msg in track: current_time += mido.tick2second(msg.time, mid.ticks_per_beat, mid.tempo) if msg.type == 'note_on' and msg.velocity > 0: # 记录音符开始时间 note_start_map[msg.note] = current_time elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0): # 匹配对应的note_on事件,添加音符到乐器 if msg.note in note_start_map: note = pretty_midi.Note( velocity=msg.velocity, pitch=msg.note, start=note_start_map[msg.note], end=current_time ) instrument.notes.append(note) del note_start_map[msg.note] pm.instruments.append(instrument)
这个方法用mido(pretty-midi依赖的底层库)直接解析,自己处理事件转换,避开了tick上限检查。
3. 预处理MIDI文件
用MuseScore、FL Studio这类MIDI编辑工具打开有问题的文件,然后重新导出为标准MIDI格式。导出时可以调整分辨率(比如降低tick分辨率),或者让工具自动修复文件结构,导出后的文件就能被pretty-midi正常加载。
内容的提问来源于stack exchange,提问作者Xaver
相关产品推荐
相关产品推荐

