Python中的MIDI消息令人困惑?

2024-04-25 09:55:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在研究MIDI数据集maestro-v2.0.0(see

我使用from mido import MidiFile
加载python中的文件 然后我处理数据集中的文件(例如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_onvelocity=0对应的是事件关闭令牌,即注释被释放。
我只是想知道发生了什么,为什么我的数据看起来如此“丑陋”? 当我说“丑陋”时,我的意思是为什么midi文件中包含未播放的音符。如果在时间{}与{}发生{}事件,但同时与{}发生相同音高的{},则不播放音符。这些不必要的信息可以简单地省略,我们不需要说没有播放音符。这就是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-第个条目是速度,最后一个条目是为时间t保留的


Tags: pathimportjsonmessagedatatimeonchannel