【问题标题】:how do multi-track midi files work?多轨 MIDI 文件如何工作?
【发布时间】:2016-09-22 17:42:39
【问题描述】:

我正在做一个分析 MIDI 文件并计算音阶的项目,但我碰壁了。

我可以找到一首单轨歌曲的所有音符(即只有一种乐器正在播放),但我在多轨 MIDI 中得到一个奇怪的数字。

我用:88 个 C 音符、32 个 C#、16 个 D、68 G 和 36 个 E 制作了一个 MIDI。当我将那个 MIDI 文件通过我的分析器时,我得到:2 个 C 音符、2 个 C# 和 1 个 G

这是我将 MIDI 文件放入ableton 时的样子:http://imgur.com/a/7pvPW

这是我的完整代码(对不起,如果它真的很丑/很糟糕,我还很新):http://pastebin.com/r7YkgqMB

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

相关位:

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# 等等)

【问题讨论】:

  • 您的代码应该放在问题中,而不是外部链接 - 找出相关的位,然后直接放在帖子中。

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


【解决方案1】:

您不能简单地在上半字节中搜索带有8 的字节。 note-off 消息可以编码为速度为零的 note-on 消息,并且在某些情况下(运行状态)可以省略状态字节。此外,编码增量时间的字节也可以具有这样的值。

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

【讨论】:

  • 我不确定我是否理解正确。在像 9x 这样的字节中,它应该意味着注意,对吧?每个音符都应该有这个命令,否则他们不知道开始演奏音符。但是当我寻找 9x 时,我只找到了 240 个音符中的 2 个。
  • 使用运行状态的事件没有9x字节。
【解决方案2】:

前段时间我不得不在一个非常基础的级别处理 MIDI:标题读取和元数据提取、标准化事件识别、未识别事件处理 ...

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

我希望它能以帮助我的方式帮助你。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多