如何在Python中“减慢”MIDI文件的速度?

20 投票
5 回答
7727 浏览
提问于 2025-04-15 14:06

我有一些背景音乐的歌曲,格式是 .MID 和 .KAR,但它们播放的速度比我想要的快了一些。我想知道有没有简单的方法可以制作出内容相同但速度更慢的 .MID 或 .KAR 文件,比如慢20%、15%或25%等等。

理想情况下,我希望能有一个跨平台的Python脚本(这样我可以轻松调整代码,达到我想要的效果;-),但只要是能在Linux(如果重要的话,我用的是Ubuntu 8.04)和Mac(我用的是Mac OS X 10.5,但如果能兼容10.6就更好了)的免费解决方案都可以。

5 个回答

5

你可以使用 music21 来实现这个功能,不过我只在 OSX 10.10.1 上测试过。

import music21

fctr = 1.25 # scale (in this case stretch) the overall tempo by this factor
score = music21.converter.parse('song.mid')
newscore = score.scaleOffsets(fctr).scaleDurations(fctr)

newscore.write('midi','song_slow.mid') 

偏移量就像每个音符的时间戳,而持续时间则是音符发声的时长。我觉得对每个音符应用相同的缩放因子,就像是在调整节奏一样。

如果你和我一样,七年后还在听同样的歌曲,那就可以试试这个!否则,我希望这能帮助到其他今天像我一样,想轻松解决这个问题的人。

15

正如Vinko所说,你可以编辑midifile文件,但因为它是二进制格式,尽量把数据压缩到最小,所以有一些工具会比较有帮助。

这是一个可以把MIDI文件转换成文本(反之亦然)的工具:
http://midicomp.opensrc.org/
我最近用得挺多的。把MIDI文件转换成文本后,做一些简单的文本处理(比如搜索包含“Tempo”的行)就变得很简单了。我在Ubuntu 8.04上编译没问题,但还没在Mac上试过。

关于MIDI文件的节奏,调整播放速度其实很简单,因为事件的时间是用“ticks”来表示的,而这些ticks的实际时间长度是由Vinko提到的节奏参数决定的。我觉得时间签名不是特别重要,主要是为了在MIDI音序器中正确显示小节和节拍。

另外,除了pyPortMidi,还有其他一些Python的MIDI模块。

[嗯……似乎作为新用户我每次只能发一个链接。我会在接下来的评论或回答中发一些Python模块的链接...]

9

你可以按照这个链接的内容来编辑文件:http://www.sonicspot.com/guide/midifiles.html

不过,可能已经有现成的MIDI读写库了。其实,只要看看相关的问题就能发现:简单的跨平台MIDI库适用于Python

设置节奏

这个元事件用于设置序列的节奏,单位是每四分音符的微秒数,这个信息是用三个字节来编码的。通常它会出现在第一个轨道块中,并且时间上与MIDI时钟消息同时发生,以便更准确地同步。如果没有设置节奏的事件,默认的节奏是每分钟120拍。下面的公式可以用来将微秒每四分音符的节奏转换为每分钟的拍子,反之亦然。

MICROSECONDS_PER_MINUTE = 60000000

BPM = MICROSECONDS_PER_MINUTE / MPQN
MPQN = MICROSECONDS_PER_MINUTE / BPM
Meta Event  Type    Length  Microseconds/Quarter-Note
255 (0xFF)  81 (0x51)   3   0-8355711

撰写回答