我有一个 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。