我目前正在研究 MIDI 数据集 maestro-v2.0.0(请参阅参考资料)。
我在 python 中加载我的文件,from mido import MidiFile
然后我处理数据集中的文件(例如 on 2009/MIDI-Unprocessed_07_R1_2009_04-05_ORIG_MID--AUDIO_07_R1_2009_07_R1_2009_04_WAV.midi
)。
如果我根据时间对事件开启(这里的速度不为零)消息进行排序,那么我得到(对于前 10 条消息):
message note_on channel=0 note=62 velocity=53 time=0,
message note_on channel=0 note=66 velocity=58 time=0,
message note_on channel=0 note=62 velocity=72 time=0,
message note_on channel=0 note=71 velocity=60 time=0,
message note_on channel=0 note=78 velocity=61 time=0,
message note_on channel=0 note=54 velocity=55 time=0,
message note_on channel=0 note=72 velocity=53 time=0,
message note_on channel=0 note=71 velocity=61 time=0,
message note_on channel=0 note=73 velocity=67 time=0,
message note_on channel=0 note=66 velocity=13 time=0
...
如您所见,在第一时间播放了多个音符。
同时,我发现这些note_on
事件的音高与velocity=0
. 我在某处读到note_on
了velocity=0
对应于事件关闭标记的地方,即释放了注释。
我只是想知道发生了什么,为什么我的数据看起来如此“丑陋”?当我说丑陋时,我的意思是为什么要包含未播放的 MIDI 文件注释。如果在时间有一个note_on
事件,但同时有一个相同音高的事件,则不会播放一个音符t
velocity>0
note_on
velocity=0
. 这些不必要的消息可以简单地省略,我们不需要说没有播放一个音符。这就是在 midi 文件中发生的事情(关于我的代码)。我希望我的意思很清楚。
我的代码可以在这里检查
import os
import pandas as pd
import json
import numpy as np
from mido import MidiFile
def openJSON():
path = "C:\\Users\\Bunlong\\PycharmProjects\\midiPreprocessing\\midi\\maestro-v2.0.0"
path = os.path.realpath(path)
os.chdir(path)
filename = 'maestro-v2.0.0.json'
with open(filename, 'r') as json_file:
data = json.load(json_file)
return data
def openMidi(folderNr, fileNr):
data = openJSON()
folder = data[folderNr]['year']
name = data[fileNr]['midi_filename']
mid = MidiFile(name)
return mid
def getRepresentation(mid):
MAX_NOTE = 127
noteOn_sequence = []
noteOff_sequence = []
time = []
for i, track in enumerate(mid.tracks):
if i == 0:
continue
print('Track {}: {}'.format(i, track.name))
for msg in track:
a = msg
print(msg)
if(a.type != 'control_change'):
if (a.type == 'note_on'):
if (a.velocity == 0):
noteOff_sequence.append(a)
else:
noteOn_sequence.append(a)
time.append(a.time)
#Sorting noteOff and noteOn sequence with respect to the timestamp
indexPermutatationOn = sorted(range(len(noteOn_sequence)), key=lambda k: noteOn_sequence[k].time)
indexPermutatationOff = sorted(range(len(noteOff_sequence)), key=lambda k: noteOff_sequence[k].time)
sortedOn = []
for index in indexPermutatationOn:
sortedOn.append(noteOn_sequence[index])
sortedOff = []
for index in indexPermutatationOff:
sortedOff.append(noteOff_sequence[index])
#call of methods
midiFile = openMidi(0,5)
getRepresentation(midiFile)
我的目标是将数据表示如下。如果对于给定的时间戳t,音高p_1, ..., p_k以速度v_1,...,v_k播放,那么我通过说p_i定义向量- 第条目是播放该音高的持续时间,而2p_i -th 条目是速度,最后一个条目是为时间t保留的。