鼓组整体偏后、越到后面越乱,通常不是“分轨顺序”造成的:轨序影响的是哪条 MIDI 落到哪个音色轨道,时间轴偏掉则多半出在三处——MIDI 的时间基准(tick 分辨率与 tempo 事件)、输入音频的起点(前导静音)、推理时的切片长度。按这三个变量逐个排除,比反复调轨道顺序有效;只有确认时间基准、起点、切片都不动、错位仍只跟着某条轨道走时,才需要回头看分轨顺序。
先看偏移的形态再改参数:第 1 小节和第 16 小节偏差接近,多半是固定偏移,查导出 tempo、前导静音和导入时是否被工程速度覆盖;偏差随小节递增则是累积漂移,优先核对 MIDI 的 PPQ 与 tempo 事件是否和原始音频 BPM 一致。分轨顺序一般不改变时间轴,只改变轨道与音色的对应关系,只有在时间基准验证通过之后才值得排查。
确认输出 MIDI 的时间基准与速度信息
导入 DAW 后先不要开量化,直接读文件头部信息。ticks_per_beat 就是 PPQ,决定网格精度;set_tempo 是 tempo 元事件,单位是微秒/四分音符。下面这段只做读取,改文件名即可运行:
import mido
mid = mido.MidiFile("drums.mid")
print("ticks_per_beat:", mid.ticks_per_beat) # 常见 480 / 960
for track in mid.tracks:
for msg in track:
if msg.type == "set_tempo":
print("tempo meta:", msg.tempo, "->", mido.tempo2bpm(msg.tempo))
如果输出里一条 set_tempo 都没有,DAW 会按工程当前速度或默认值解释,整轨就表现为固定错拍。导入环节的设置也要对齐:多数 DAW 在导入 MIDI 时提供“导入文件中的 tempo”和“对齐到工程网格”两个开关,建议先选择使用文件自身的 tempo、不映射到工程速度,并关闭导入时自动量化或吸附。若 DAW 只有“跟随工程速度”一项,就在导入前把工程 BPM 设成与原始音频一致。验证方式是导入后不改任何设置,把播放头放到第 1 小节起点,看底鼓是否落在网格线上。
量出第一小节的偏移,再看到结尾是否变大
把网格切到 1/16 或更细,读每个音符起始的 tick 与最近网格线 tick 的差值,记录第 1、8、16 小节三处偏差。测量时不要顺手拖动音符,否则量到的是你修正后的结果。两种结果指向不同病因:三个值接近,属于固定偏移,去查导出是否有起始延迟、输入音频前导静音、切片首段是否丢了若干毫秒、导入时是否用了错误 tempo;偏差从小节 1 到小节 16 逐渐变大,属于累积漂移,常见原因是 tempo 事件与音频实际 BPM 不一致(比如音频 128、MIDI 写 120),或 PPQ 在某个环节被重新解释。累积漂移改节拍网格没有用,网格只能改显示,修不了已经写进 tick 的时间。
检查输入音频的起始静音与拍号设置
模型通常把第一个显著能量点当作第一拍或小节起点。音频开头若有几百毫秒静音,转出的鼓组可能因此整体滞后一个非整拍的量。用音频编辑器放大波形,把第一个有效瞬态之前的静音裁掉,前面保留几毫秒 pre-roll 以免削掉起音。定位静音区间可以先跑一条探测命令,阈值按素材调整:
ffmpeg -i input.wav -af silencedetect=noise=-40dB:d=0.1 -f null -
拍号要单独确认:工程写 4/4 而音频实际是 3/4,小节线会错位,但音符相对拍点未必偏。检查办法是开节拍器跟音频数小节,看第 8 小节的重拍是否仍落在工程第 8 小节。如果整轨统一偏后且偏移量固定,一般不是拍号问题,回到上一节的时间基准检查。
用同一段音频换不同切片长度重跑
对照跑法只允许一个变量变化:同一输入文件、同一采样率、同一模型与参数、同一导出设置,仅改切片长度,例如 10 秒、20 秒、30 秒,或按 4 小节、8 小节切。两次之间不要重新裁剪音频、不要改工程 BPM,否则测的就不是切片边界了。对比方式是把两次输出的 MIDI 导入同一个工程,用同一套网格解释,分别量第 1、8、16 小节偏差,并排成两列。重点看两件事:错位是否出现在固定时间点,例如每个切片末尾几拍开始偏,那通常与切片边界和上下文长度有关;两次偏差分布是否一致,如果一致,就说明切片长度不是主因,回到时间基准与输入起点继续查。
把结论落成一条可复现的排查记录
每次排查留一条记录,下次遇到同类问题可以直接对照,而不是从头试。模板如下,只填能通过文件、日志、命令或界面行为验证的项:
- 输入文件:格式、采样率、声道数、总时长
- 起点处理:是否有前导静音、裁掉多少毫秒、是否保留 pre-roll
- 拍号:工程拍号与音频实际拍号是否一致
- 切片:长度、是否重叠、其余参数保持不变的说明
- 输出 MIDI:PPQ、是否存在 set_tempo 事件、tempo 换算出的 BPM
- 偏差值:第 1、8、16 小节各自的 tick 差
- 结论归属:时间基准 / 输入起点 / 切片长度 / 待定
- 复现路径:从哪一步开始能稳定重现,哪一步之后就变了
结论栏写“待定”不算失败,比写一句“模型不准”有用得多。只有当你按上面步骤换过切片长度、核对过 tempo 事件、裁过前导静音,错位仍然只落在某一条轨道上时,才把分轨顺序列为下一轮排查对象。