Java 从 MIDI 序列中获取乐器列表

Posted

技术标签:

【中文标题】Java 从 MIDI 序列中获取乐器列表【英文标题】:Java get instrument list from MIDI Sequence 【发布时间】:2015-07-28 23:38:03 【问题描述】:

我需要从通用 MIDI 文件中获取音符、时间戳和乐器列表等等。

几乎一切都完成了,但我还需要每个音轨对应的每个乐器,否则如果我不知道它们属于哪个乐器,这些音符就没用了。

这似乎是通过获取补丁列表来完成的,补丁在 MIDI 序列使用的音库中包含乐器代码。

这看起来很简单,但是当我尝试在 Sequence 对象上使用 getPatchList() 时,它会返回一个空数组。

问题?:似乎这从未在 java MIDI 库 (??) 中真正实现,至少从我发现的情况来看:

/**
 * Get an array of patches used in this sequence.
 * 
 * @return an array of patches used in this sequence
 */
public Patch[] getPatchList()

  // FIXE: not quite sure how to do this yet. 
  throw new UnsupportedOperationException("Can't get patch list yet");

来源:javax.sound.midi.Sequence

显然,android 开发人员也无法弄清楚。 注意这是一个普通的java程序,与Android无关:

public Patch[] getPatchList() 
    //FIXME
    /*
     * I don't understand how to works this method, and so
     * I simply return an empty array. 'patches' initializes
     * in the constructor as empty vector 
     */
    Patch[] patch = new Patch[patches.size()];
    patches.toArray(patch);
    return patch;

来源:javax.sound.midi.Sequence

那么有什么可以做的吗? 有没有其他方法可以获得乐器? 为什么没有实施? 自 2005 年以来,真的没有人需要这个吗?

【问题讨论】:

getPatchList() 是否可行?我对 MIDI 了解不多,但乐器的分配难道不是 Sequence 所不知道的吗?您可以通过扫描所有 MidiMessages 从序列中获取乐器编号,但在我看来,需要Synthesizer 才能知道它们如何映射到补丁。 【参考方案1】:

要让 MIDI 设备选择乐器,您需要向它发送 Program Change 消息(这也会考虑到 Bank Select 控制器的当前设置)。

要获得序列中所有补丁的列表,需要遍历所有消息的列表,并收集所有程序编号(以及当时有效的所有银行编号)。

如果您的实现没有这样做,您必须手动执行此操作。

【讨论】:

那行得通,为每个频道注册程序更改消息可以让我获得所有乐器。谢谢。

以上是关于Java 从 MIDI 序列中获取乐器列表的主要内容,如果未能解决你的问题,请参考以下文章

如何从 DryWetMidi 库中的特定 MIDI 文件块中获取程序/乐器标题?

如何获取对非默认 MIDI 音序器的引用?

如何使用 Java 在 Midi 文件中列出乐器名称?

如何访问和更改 Pygame.midi?

如何从 MIDI 序列中获取 Note On/Off 消息?

如何在 Java MIDI 程序中更改乐器