如何“减慢” MIDI 文件(最好在 Python 中)?

Posted

技术标签:

【中文标题】如何“减慢” MIDI 文件(最好在 Python 中)?【英文标题】:How to "slow down" a MIDI file (ideally in Python)? 【发布时间】:2009-09-06 00:35:53 【问题描述】:

我有一些 .MID 和 .KAR 格式的歌曲的背景音乐,但在每种情况下,它的播放速度都比我想要的要快。创建具有相同内容但速度较慢的 .MID 或 .KAR 文件的最简单方法是什么——比如说,一个减慢 20% 左右,另一个减慢 15%,三分之一减慢 25%,等等?

理想情况下,我更喜欢跨平台的 Python 脚本(因为这可以让我轻松地通过实验调整源代码以收敛到我想要的确切效果;-),但我会采用任何可以运行的免费解决方案Linux(Ubuntu 8.04,如果重要的话)和 Mac(Mac OS X 10.5,但首选 10.6 兼容性)。

【问题讨论】:

你看过OSC格式了吗? en.wikipedia.org/wiki/Open_Sound_Control 【参考方案1】:

正如 Vinko 所说,您可以编辑 midifile,但由于它是二进制格式,压缩到尽可能少的位数,因此需要帮助。

这是一个 MIDI 到文本的转换器(反之亦然):http://midicomp.opensrc.org/ 我最近一直在使用它。一旦将midifile作为文本,进行简单操作的文本处理(例如搜索带有“Tempo”的行)是非常简单的。在mac上没试过(在ubuntu 8.04上编译没问题)。

特别是关于 midifile 速度,放慢或加快播放速度真的很容易,因为事件的时间是根据“滴答声”指定的,其实际持续时间(以秒为单位)由 Vinko 引用中描述的速度参数确定。我相信拍号没有那么重要,主要是为了在 midi 音序器中打开时正确显示小节/节拍。

此外,除了 pyPortMidi,还有一些其他的 python midi 模块。

[嗯...似乎我只能在每个帖子的链接上发布,作为一个新用户。我会尝试在几个 cmets 或其他几个答案中发布指向 python 模块的链接...]

【讨论】:

用于读取、写入、创建/编辑等midi文件的Python模块:mxm.dk/products/public/pythonmidi> midi 文件读写类(此贴似乎是唯一来源):groups.google.com/group/alt.sources/msg/0c5fc523e050c35e> 我也找到了这个,虽然我没试过:groups.google.com/group/comp.lang.python/browse_thread/thread/…>【参考方案2】:

您可以按照http://www.sonicspot.com/guide/midifiles.html编辑文件

虽然可能已经有一个 MIDI 读/写库。其实看相关问题就知道了:Simple, Cross Platform MIDI Library for Python

设置节奏

此元事件设置 序列节奏 每四分音符微秒,即 编码为三个字节。通常是 在第一个轨道块中找到, 时间对齐同时发生 作为 MIDI 时钟消息来推广 更准确的同步。如果不 设置速度事件存在,120 节拍 假定每分钟。以下 公式可以用来翻译 速度从每微秒 每分钟节拍的四分音符和 返回。

MICROSECONDS_PER_MINUTE = 60000000 BPM = MICROSECONDS_PER_MINUTE / MPQN MPQN = MICROSECONDS_PER_MINUTE / BPM 元事件类型长度微秒/四分音符 255 (0xFF) 81 (0x51) 3 0-8355711

【讨论】:

嗯,看来我不会获得任何更直接的技术,所以感谢@Vinko。 SO 这么优秀,对吧? :-) 当你真的需要它时,它总是失败。【参考方案3】:

您可以使用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') 

偏移量就像每个音符的时间戳,持续时间是音符发声的时长,我相信对每个音符应用相同的比例因子有点像调整速度。

如果你和我一样,那么 7 年后你还在听同样的歌,可以试试看!否则,我希望这可以帮助像我一样今天醒来并且正在挠头试图轻松解决这个问题的其他人。

【讨论】:

fastScore = score.augmentOrDiminish(1.25) -- 将缩放持续时间和偏移量以及其他一些东西以使分数输出也正确。【参考方案4】:

由@dermen 在 Windows、Python 3.8 上测试了该版本。不得不稍微调整一下,但仍然有效!

import music21

fctr = 1.5 # scale (in this case stretch) the overall tempo by this factor
score = music21.converter.Converter()
score.parseFile('home.mid')
newscore = score.stream.augmentOrDiminish(fctr)
newscore.write('midi','song_slow.mid')

【讨论】:

【参考方案5】:

我和你的帖子有相似的兴趣。我刚刚遇到了这个看起来很有前途的库:

http://web.mit.edu/music21/

【讨论】:

请注意 link-only answers 是不鼓励的,所以答案应该是寻找解决方案的终点(而不是另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。 用一个新的乐谱替换每个乐谱开头的 tempo.MetronomeMark 对象应该可以解决问题。请注意,目前 music21 将量化任何 MIDI 文件。刚刚被添加到我们的待办事项列表中以使其成为可选。

以上是关于如何“减慢” MIDI 文件(最好在 Python 中)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中合并或连接两个midi文件

用于输出音频程序可读的 MIDI 文件或文本的 Python 接口

如何使用python根据音符音高分割midi文件?

如何使用 python 从头开始​​编写 Midi 文件

如何在 Python 中将 ABC 表示法的音乐文件转换为 midi 或 mp3 [关闭]

Python 编写 MIDI 文件