0

我有一个 java 程序设置,它从控制器获取 MIDI 输入,理想情况下根据发送的 MIDI 音符做不同的事情(不一定与播放合成器输出有关)。

我的代码很大程度上基于这个 SO 问题中的代码:Java getting input from MIDI keyboard,特别是我正在使用整个 MidiInputReceiver 类。我已经修改它来执行 System.out.println(msg) 以及打印“收到的 MIDI”,并且它似乎可以在每次我按下控制器上的一个键时检测到 MIDI 并打印 midi msg ,但我不知道如何将输出解码为我可以破译的东西,如果这可能的话。

我得到的输出是:

midi received
com.sun.media.sound.FastShortMessage@75b0e2c3
midi received
com.sun.media.sound.FastShortMessage@2ff7ac92
midi received
com.sun.media.sound.FastShortMessage@2d62bdd8
midi received
com.sun.media.sound.FastShortMessage@2d9dc72f

我一直在尝试使用这个 Java 类http://www.jsresources.org/examples/DumpReceiver.java.html来解码消息,但它只解码 ShortMessages,而不是 FastShortMessages,而且我在网上找不到任何文档关于什么是 FastShortMessage,更不用说如何从 FSM 转换为 SM。有人有什么想法吗?有没有比我正在做的更简单的方法?

编辑:这可能不是最好的方法,但我只是想出了一种可行的方法,我无法在 8 小时内回答我自己的帖子,但我会在这里发布以防其他人需要它。

我只是设法用下面的代码解决了我自己的问题。

public void send(MidiMessage msg, long timeStamp) {
    // Print to confirm signal arrival
    System.out.println("midi received");

    byte[] aMsg = msg.getMessage();
    // take the MidiMessage msg and store it in a byte array

    // msg.getLength() returns the length of the message in bytes
    for(int i=0;i<msg.getLength();i++){
        System.out.println(aMsg[i]);
        // aMsg[0] is something, velocity maybe? Not 100% sure.
        // aMsg[1] is the note value as an int. This is the important one.
        // aMsg[2] is pressed or not (0/100), it sends 100 when they key goes down,  
        // and 0 when the key is back up again. With a better keyboard it could maybe
        // send continuous values between then for how quickly it's pressed? 
        // I'm only using VMPK for testing on the go, so it's either 
        // clicked or not.
    }
    System.out.println();
}

按下两个键的示例输出:

midi received 
-103
71
100

midi received
-119
71
0

midi received
-103
52
100

midi received
-119
52
0

所以 aMsg[1] 保存了每个笔记的 Midi 号​​码,可以在网上任何地方引用,由于代表我无法发布链接。

getMessage() 和 getLength() 方法来自http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiMessage.html,我还没有弄清楚什么是 FastShortMessage ,但它可能只是遗留的遗留代码或其他东西?它是 com.sun 的东西,所以它一定很老了。

从这里我可以在 aMsg[1] 上执行 switch() 语句,具体取决于按下哪个键,这正是我的目标,因为它是一个整数,所以它将向后兼容 1.6。

4

1 回答 1

2

FastShortMessage是(间接)衍生自MidiMessage; 就像一个人一样处理它。

当你有 时ShortMessage,你应该使用getCommand///函数getChannel,它比临时getData1字节2数组更容易使用。

于 2014-04-22T16:17:13.100 回答