如何在midi信息到达Java接收器后访问它

如何在midi信息到达Java接收器后访问它,java,midi,receiver,Java,Midi,Receiver,我想做的是编写一个简单的程序,每当我按下外部midi控制器上的键时,内部接收器就会接受消息上的注释,并以某种方式允许它们作为字节信息打印出来。我设置了一个接收机,该接收机设置为我的外部硬件midi控制器的发射机。我不确定在midi信息到达接收端后如何从接收端访问它。就我在这方面所做的研究而言,我阅读了oracles midi over view,并查看了有关StackOverFlow的各种示例。Oracle文章解释了如何连接接收器和发射器以及如何将此信息发送到synth,但没有介绍如何在没有sy

我想做的是编写一个简单的程序,每当我按下外部midi控制器上的键时,内部接收器就会接受消息上的注释,并以某种方式允许它们作为字节信息打印出来。我设置了一个接收机,该接收机设置为我的外部硬件midi控制器的发射机。我不确定在midi信息到达接收端后如何从接收端访问它。就我在这方面所做的研究而言,我阅读了oracles midi over view,并查看了有关StackOverFlow的各种示例。Oracle文章解释了如何连接接收器和发射器以及如何将此信息发送到synth,但没有介绍如何在没有synth或sequencer的情况下从接收器本身访问Midi短消息。StackOverFlow示例有相关的信息,但我没有看到任何解释如何从接收器本身提取信息的内容。如果有人想写一些示例代码,并写一个详细的解释,我认为这对像我这样的初学者来说是一个很好的服务,因为它将展示如何在编写与midi兼容的代码的第一步,即如何在Java中接收midi数据,然后是能够使用它的第一步。下面是一些我已经尝试过的示例代码

package receivemidiattempt;

import javax.sound.midi.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ReceiveMidiAttempt {




public static void main(String[] args)   {



 // My internal receiver which I set up with my own MidiReceiver class   which implements 
 // Receiver

 Receiver r = new MidiReceiver ();




   //My Transmitter 
   Transmitter trans = null;

   try {
  //Setting up transmitter with the external midi controller
       trans= MidiSystem.getTransmitter();

   }
   catch(MidiUnavailableException e)
   {
       System.out.println("No Midi port Detected");
   }

  //contecting the transmitter to my internal receiver
   trans.setReceiver(r);
   }
   }
我已经把发射机和接收机连接好了,但我不知道从这里该怎么做才能从接收机中提取midi信息以便打印出来。receiver接口只有两种方法,close和send,其中close关闭receiver并向receiver本身发送消息。希望我能找到一些方法来获取到达接收器的midi信息,并将其存储在一个名为MIDINFO的字节变量中,然后打印出来


好吧,在过去的一个小时里,我把Java弄得乱七八糟,我几乎把它弄明白了。我想我所困惑的是,当一个类的对象被实例化时,该类中方法的工作方式。例如,只需将println(msg)放在我创建的实现receiver的类的Send()方法中,而不调用该方法,每次我按下控制器上的键时,都会打印一条奇怪的消息,如下所示a@787fd而且每次都会改变。如果我使用msg.getLength,我可以看到每次按下一个键,数字3都会打印出来。考虑到短消息有三个字节——状态字节、音调字节和速度字节,这是有意义的。我仍然不知道如何让java打印实际字节。快到了

最简单的方法是使用:


最简单的方法是使用:


让我困惑的一件事是,为什么即使我没有在主方法中使用r.Send()调用Send,也会执行Send;可能发生的是,将发射机设置为接收机会调用send方法。好吧,我想出来了!!!!我制作了一个字节数组。然后在方法中设置bArray=msg.getMessage。现在我可以使用bArray[1]、bArray[2]等打印阵列的任何部分!这是伟大的,因为现在我可以开始使用这些信息,使更复杂的事情发生!!哈哈哈,我做到了!!!!!!!是的!!!!!让我困惑的一件事的可能重复是,为什么即使我没有在主方法中使用r.Send()调用Send,也会执行Send;可能发生的是,将发射机设置为接收机会调用send方法。好吧,我想出来了!!!!我制作了一个字节数组。然后在方法中设置bArray=msg.getMessage。现在我可以使用bArray[1]、bArray[2]等打印阵列的任何部分!这是伟大的,因为现在我可以开始使用这些信息,使更复杂的事情发生!!哈哈哈,我做到了!!!!!!!是的!!!!!可能重复的谢谢!!!!。没有考虑使用侦听器。这对我会有很大帮助!我投票支持你。它不会显示出来,因为我是个傻瓜,但无论如何,谢谢你。祝你一切顺利Alex@AlexC你不能放弃答案,因为你没有足够的声誉。如果这回答了你的问题,你应该接受这个答案。谢谢没有考虑使用侦听器。这对我会有很大帮助!我投票支持你。它不会显示出来,因为我是个傻瓜,但无论如何,谢谢你。祝你一切顺利Alex@AlexC你不能放弃答案,因为你没有足够的声誉。如果这回答了你的问题,你应该接受这个答案。
// You'll need some try/catches around this block. This is traditional Java Midi code.
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
MidiDevice device = MidiSystem.getMidiDevice(infos[0]); // You'll have to get the right device for your MIDI controller. 

// Here comes the JFugue code
MusicTransmitterToParserListener m = new MusicTransmitterToParserListener(device);
m.addParserListener(new ParserListenerAdapter() {
    @Override public void onNotePressed(Note note) {
        System.out.println(note + " pressed");
    }
    @Override public void onNoteReleased(Note note) {
        System.out.println(note + " released");
    }
} );

// Choose either this option:
m.startListening();
...do stuff...
m.stopListening();

// Or choose this option:
m.listenForMillis(5000); // Listen for 5000 milliseconds (5 seconds)