在 Python MIDI MIDO 读取/保存文件中转换时间/刻度
Posted
技术标签:
【中文标题】在 Python MIDI MIDO 读取/保存文件中转换时间/刻度【英文标题】:Convert time/tick in Python MIDI MIDO read/save file 【发布时间】:2017-08-19 13:37:03 【问题描述】:以下程序使用 MIDO 读取“g1.mid”,然后将其保存到“g1_new.mid”。我的问题是:在读取文件时,“msg.time”是一个浮点值,但在保存文件时,“消息中的时间”是一个整数。在这种情况下,我们如何将 'msg.time' 转换为 'tick in message'?
from mido import MidiFile
from mido import Message, MidiTrack
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
for msg in MidiFile('g1.mid'):
if (not msg.is_meta):
if (msg.type == 'note_on'):
# how to convert msg.time to tick to fill in '?'
track.append(Message('note_on', note=msg.note, velocity=msg.velocity, time=?))
elif (msg.type == 'note_off'):
# how to convert msg.time to tick to fill in '?'
track.append(Message('note_off', note=msg.note, velocity=msg.velocity, time=?))
elif (msg.type == 'program_change'):
track.append(Message('program_change', program=msg.program, channel=msg.channel))
mid.save('g1_new.mid')
注意:这段代码在一个关于音乐生成的项目中。
【问题讨论】:
【参考方案1】:当您迭代 MidiFile
对象本身时,时间戳会被显式转换:
class MidiFile(object):
...
def __iter__(self):
...
tempo = DEFAULT_TEMPO
for msg in merge_tracks(self.tracks):
# Convert message time from absolute time
# in ticks to relative time in seconds.
if msg.time > 0:
delta = tick2second(msg.time, self.ticks_per_beat, tempo)
else:
delta = 0
yield msg.copy(time=delta)
if msg.type == 'set_tempo':
tempo = msg.tempo
因此,只需直接遍历 mid.tracks
(或合并的轨道)即可。
【讨论】:
亲爱的 CL:该程序可以在“for msg in merge_tracks(mid.tracks)”中获取刻度。感谢您的评论。以上是关于在 Python MIDI MIDO 读取/保存文件中转换时间/刻度的主要内容,如果未能解决你的问题,请参考以下文章
python mido MIDI包中使用MultiPort的问题
如何将MIDO下的ticks_per_beat设置为一个新的MIDI文件?
在 Mac 上从 Python Mido 库输出 MIDI 声音
使用 Python Mido 库选择 GM MIDI Level 2 乐器