多轨midi文件如何工作?

时间:2016-09-22 17:42:40

标签: python-3.x midi file-type

我正在开发一个分析MIDI文件并计算比例的项目,但我已经碰壁了。

我可以找到单首曲目歌曲的所有音符(即只有一种乐器正在演奏),但我得到了一个带有多曲目MIDI的奇怪数字。

我制作了一个MIDI:88 C音符,32 C#,16 D,68 G和36 E.当我把MIDI文件放入我的分析仪时,我得到:2 C音符,2 C#和1 G

以下是当我把它放入能效时MIDI文件的样子:http://imgur.com/a/7pvPW

这里是我的代码全部(对不起,如果它真的很丑/不好我相当新):http://pastebin.com/r7YkgqMB

很难找到有关如何构建MIDI文件的信息,但这里是我的主要两个来源(也许它们是错误的?):Source 1,{{3 }}

相关位:

for i in range(0, len(midi_bytes) - 3): # iterates through the midi (without head chunk)
    # Looks for start of track chunk (MTrk)
    if midi_bytes[i][1:3] + \
       midi_bytes[i + 1][1:3] + \
       midi_bytes[i + 2][1:3] + \
       midi_bytes[i + 3][1:3] == "4D54726B":
        # Found a track chunk

        # How long is the chunk?
        len_of_chunk = int(midi_bytes[i + 4][1:3] +
                           midi_bytes[i + 5][1:3] +
                           midi_bytes[i + 6][1:3] +
                           midi_bytes[i + 7][1:3], 16)

        # iterates through that chunk (from 8 bytes after chunk start to length of chunk + 8 (from the 8 after))
        for j in range(9, len_of_chunk + 8):
            # Looks for keys

            bit = int(midi_bytes[j][1:3], 16)

            if midi_bytes[j - 1][1] == "8" and bit <= 127: 

然后它检查8之后的字节(应该是停止音符命令)mod 12是什么(如果= 0那么它的a c,= 1是c#等)。

2 个答案:

答案 0 :(得分:3)

您不能简单地在高位半字节中搜索8的字节。音符关闭消息可以编码为速度为零的音符开启消息,并且在某些情况下(运行状态)可以省略状态字节。此外,编码delta时间的字节也可以具有这样的值。

您必须正确解析MIDI文件。 (并阅读官方Standard MIDI Files (SMF) Specification。)

答案 1 :(得分:1)

我不得不在一个非常基本的层面上处理MIDI:标题阅读和元数据提取,标准化事件识别,无法识别的事件处理 ......

我写了一个非常简单的 JS库 midi-parser-js来完成它,我不得不说,由于这个有用的文档,它快速而有趣: https://github.com/colxi/midi-parser-js/wiki/MIDI-File-Format-Specifications

我希望它可以帮助你帮助我。

快速考虑: 我不知道女巫是你的特殊要求,但是,在我的特殊情况下,经过一些研究,我选择预先处理.mid文件二进制RAW数据,并将其解析,存储到更多&#39;方便的可用&#39;数据结构:具有用于保存元数据的属性的对象-bpm,活动效果,activeinstrument ...-以及具有Midi事件列表的属性(数组)... 这样我就可以简单地将数据推送到数组中,而音乐时钟模块只需要分析和安排&#34; events数组项目&#34; ...