编辑 midi 事件

Posted

技术标签:

【中文标题】编辑 midi 事件【英文标题】:Editing midi events 【发布时间】:2012-11-19 20:31:43 【问题描述】:

我正在尝试通过在钢琴卷帘编辑器中向上或向下移动图形音符(矩形)来按顺序编辑现有 MIDI 音符的音高。阅读 API 和在线文档,并没有非常具体地了解如何编辑现有笔记。据我所知,我需要使用 setMessage() 方法来覆盖现有的 ShortMessage。这是我现在得到的:

public void changePitch(int pitchUpOrDown) 
    MidiMessage message =  this.getMessage();
    message.setMessage(___?, ____?, ____? + pitchUpOrDown, ____?);

我通过鼠标拖动一个音符从 JPanel 调用 changePitch(),我发送 +1 或 –1 作为调整音高的增量。我找不到需要在 setMessage() 调用的其他四个空白参数中输入的值。从逻辑上讲,我想保留命令、通道和时间戳的现有值,但是如何访问这些现有值以便将它们放在空白处?我尝试过诸如 message.command 或 message[0] 之类的东西,但它们不起作用。此外,在文档中,set Message 的参数显示为 (byte[] data, int length)。这些 args 的解释真的很模糊,而且它们肯定与我一开始用来创建 ShortMessage 的 args 不匹配。有什么建议吗?

【问题讨论】:

【参考方案1】:

MidiMessage 向下转换为ShortMessage,然后您可以获得数据1 和数据2 的音高和速度:

if (message instanceof ShortMessage) 
    ShortMessage shortMessage = (ShortMessage) message;

    if(shortMessage.getCommand() == ShortMessage.NOTE_ON) 
        int channel = shortMessage.getChannel();
        int pitch = shortMessage.getData1();
        int vel = shortMessage.getData2();
        if(vel > 0) 
            shortMessage.setMessage(ShortMessage.NOTE_ON, channel, pitch + pitchUpOrDown, vel);
        
    

您可能还需要更改下一条 NOTE_OFF 消息。这将是一个带有 NOTE_OFF 命令的短消息,或者是一个速度为 0 的 NOTE_ON 命令。

【讨论】:

谢谢!那完全奏效了!但是您对 NOTE-OFF 的看法是正确的。这些编辑过的笔记不再关闭。但是如何在音符向量中找到正确的 NOTE_OFF 消息以便对其进行编辑? 如果它们是按时间戳排序的,那么它将是具有相同音高和频道的下一条 NOTE_OFF 消息。 我是否可以通过尝试在 Vector 中访问 NOTE_OFF 消息(我相信它是轨道)来找到它?或者那会是某种 if 语句,例如,“如果音符是这样那样的音高和通道并且具有 NOTE_OFF 的命令并且时间戳晚于_______”?这是文档非常模糊的地方。它们告诉您如何创建消息,但 API 中很少有关于创建消息后如何访问消息的详细信息。我一直在打印示例、阅读书籍和搜索 API。 @KyleWalker 您需要使用 if 语句遍历轨道检查每个音符。另一种方法是在更易于编辑的自定义数据结构中创建注释,并在每次需要时重新创建序列。 这就是我的想法,但这正是我感到困惑的地方。你如何迭代一个轨道?它没有分配给它的变量(除非“track”是变量),那么我该如何引用它呢?非常感谢您的耐心等待。

以上是关于编辑 midi 事件的主要内容,如果未能解决你的问题,请参考以下文章

将 MIDI 事件转换为 pygame 事件

将 MIDI 歌曲事件与初始设置事件分开

解析 MIDI 文件以记录事件

重复 MIDI FF 51 03 事件?

从 PortMIDI 发送虚拟 MIDI 事件

Android上的Midi事件路由