简体   繁体   English

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

[英]How to "slow down" a MIDI file (ideally in Python)?

I have background music for some songs available in both.MID and.KAR formats, but in each case it's being played somewhat faster than I'd like.我有一些歌曲的背景音乐,有.MID 和.KAR 两种格式,但在每种情况下,它的播放速度都比我想要的要快。 What's the simplest way to create either.MID or.KAR files with the same content but at a slower tempo -- say, one slowed down by 20% or so, another by 15%, a third by 25%, and so on?创建具有相同内容但速度较慢的 .MID 或 .KAR 文件的最简单方法是什么——比如说,一个减慢 20% 左右,另一个减慢 15%,第三个减慢 25%,等等?

Ideally, I'd prefer a cross-platform Python script (since that would allow me to easily experimentally tweak the source to converge to the exact effect I want;-), but I'll take any free solution that runs in Linux (Ubuntu 8.04 if it matters) and Mac (Mac OS X 10.5, but 10.6 compatibility preferred).理想情况下,我更喜欢跨平台的 Python 脚本(因为这可以让我轻松地通过实验调整源代码以收敛到我想要的确切效果;-),但我会采用在 Linux(Ubuntu)中运行的任何免费解决方案8.04(如果重要的话)和 Mac(Mac OS X 10.5,但首选 10.6 兼容性)。

As Vinko says, you can edit the midifile, but since it's a binary format, squeezed into the least number of bits possible, it helps to have help.正如 Vinko 所说,您可以编辑 midifile,但由于它是一种二进制格式,压缩到尽可能少的位数,因此获得帮助会有所帮助。

This is a midi-to-text converter (and vice-versa):这是一个 midi 到文本的转换器(反之亦然):
http://midicomp.opensrc.org/ http://midicomp.opensrc.org/
I've been using it quite a bit lately.我最近一直在使用它。 it's pretty trivial to do text processing (eg searching for line with "Tempo") for simple operations once you have the midifile as text.一旦您将 midifile 作为文本,进行文本处理(例如搜索带有“Tempo”的行)以进行简单操作就非常简单了。 haven't tried on mac (compiled with no problem on ubuntu 8.04).没有在 mac 上试过(在 ubuntu 8.04 上编译没有问题)。

Regarding midifile tempo specifically, it's really easy to slow down or speed up playback since the timing of events is specified in terms of "ticks", whose real duration in seconds is determined by the tempo parameter described in Vinko's quote.特别是关于 midifile 速度,放慢或加快播放速度真的很容易,因为事件的时间是根据“节拍”指定的,其实际持续时间(以秒为单位)由 Vinko 的引述中描述的速度参数决定。 I believe time signature is not so relevant, and is mainly for displaying bars/beats correctly when opened in a midi sequencer.我相信时间签名不是那么相关,主要是为了在 midi 音序器中打开时正确显示小节/节拍。

Also, aside from pyPortMidi, there are a couple of other python midi modules around.此外,除了 pyPortMidi 之外,还有一些其他的 python midi 模块。

[hmmm... it seems i can only post on link per post, being a new user. [嗯...作为新用户,我似乎只能在每个帖子上发布链接。 i'll try posting the links to the python modules in a couple comments or another couple answers...]我将尝试在一些评论或其他几个答案中发布指向 python 模块的链接...]

You could edit the file, as per http://www.sonicspot.com/guide/midifiles.html您可以根据http://www.sonicspot.com/guide/midifiles.html编辑文件

Although there probably is a MIDI reading/writing library already.虽然可能已经有一个 MIDI 读/写库。 In fact, it was a matter of seeing the related questions: Simple, Cross Platform MIDI Library for Python事实上,这是看到相关问题的问题: Simple, Cross Platform MIDI Library for Python

Set Tempo设定节奏

This meta event sets the sequence tempo in terms of microseconds per quarter-note which is encoded in three bytes.此元事件以每四分音符微秒为单位设置序列速度,以三个字节编码。 It usually is found in the first track chunk, time-aligned to occur at the same time as a MIDI clock message to promote more accurate synchronization.它通常出现在第一个轨道块中,时间对齐与 MIDI 时钟消息同时发生,以促进更准确的同步。 If no set tempo event is present, 120 beats per minute is assumed.如果不存在设定速度事件,则假定每分钟 120 次节拍。 The following formula's can be used to translate the tempo from microseconds per quarter-note to beats per minute and back.以下公式可用于将速度从每四分音符的微秒转换为每分钟的节拍数并返回。

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

You can use music21 to do this, though I have only tested it on OSX 10.10.1.您可以使用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') 

Offsets are like the timestamps of each note, and durations is how long the note is sounded, I believe applying the same scale factor to each is kind of like adjusting the tempo.偏移量就像每个音符的时间戳,持续时间是音符发出的时间,我相信对每个音符应用相同的比例因子有点像调整速度。

If you are like me then you are listening to the same songs 7 years later and can give this a try, Otherwise.如果你像我一样,那么 7 年后你还在听同样的歌曲,可以试一试,否则。 I hope this helps someone else who woke up today like me and was scratching my head trying to solve this problem easily.我希望这可以帮助像我一样今天醒来并且正在挠头试图轻松解决这个问题的其他人。

tested the version by @dermen on Windows, Python 3.8. @dermen 在 Windows、Python 3.8 上测试了该版本。 Had to tweak it a bit, but still works!不得不稍微调整一下,但仍然有效!

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')

I have a similar interest as your post.我和你的帖子有相似的兴趣。 I just came across this library which looks very promising:我刚刚遇到这个看起来很有前途的库:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM