我一整天都在喋喋不休,阅读我能找到的所有内容,遵循JDK源代码,没有好运找到关于如何获取midi设备上的数据以及确定什么是什么的关于HOW或WHERE的详细信息.
我试图通过我的NI Audio 8 DJ MIDI IN端口捕获midi消息,但是,java并没有“看到”MIDI IN端口,只有out,我已成功用于发送midi.我也可以使用M-Audio USB UNO midi设备获得相同的结果:MidiSystem.getMidiDeviceInfo()仅“看到”输出端口.
我已经验证了MIDI IN端口的操作:
amidi -p hw:2,0 -d
并发送一些信号.工作良好.
getMaxTransmitters()返回零.
MidiSystem.getMidiDeviceInfo()仅显示两个设备的一个条目:Audio8DJ [hw:2,0]或接口[hw:2,0]
下面的代码适用于Receiver,我认为只需要验证getTransmitter()获取端口,因为它只适用于另一个并且一切正常,我得到一个MidiUnavailableException / Transmitter不可用的异常.
我甚至拿出了getMaxReceivers()陷阱,因为我只是试图看看设备是否只提供了一个条目并将其整理出来,但没有.
public static Transmitter getMidiIn () {
if (midiIn == null){
devices = MidiSystem.getMidiDeviceInfo();
for(MidiDevice.Info info: devices){
System.out.println("device class " + info.getClass());
MidiDevice device;
try{
device = MidiSystem.getMidiDevice(info);
if (info.toString().equals("Audio8DJ [hw:2,0]")){
if (device.getMaxTransmitters() != 0){
try{
device.open();
System.out.println("max transmitters:" + device.getMaxTransmitters());
midiIn = device.getTransmitter();
System.out.println("Found a transmitter: "+ midiIn);
break;
} catch (Exception e){
e.printStackTrace();
}
}
}
} catch (MidiUnavailableException e1){
e1.printStackTrace();
}
}
}
return midiIn;
}
所以让我来到这里的是:alsa在amidi -l中只列出一个条目,当我指定它作为转储端口时,它工作正常. Java获取相同的文本条目并且无法对MIDI IN进行排序,为其分配com.sun.media.sound.MidioutDeviceProvider类,因此它让我想知道Java是如何做到的,或者Java在哪里弄清楚设备提供的内容为什么不看到alsa看到的输入端口.
我正在使用带有JDK1.6的eclipse版本:3.8.1 IDE进行编码,在Linux薄型操作系统上.
我很乐意提供任何要求.谢谢阅读!
在我测试的三个版本中,jdk1.8.0_60,jdk1.7.0_80,jdk1.6.0_45,1.7没有遇到错误并成功从我的设备获得了一个发送器.我发现了这一点,并且特权不是我特定问题的原因,通过编译和运行一些适合命令行执行的代码,我试图获取发送器,打印发送给它的midi数据,并稍微修改它…
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
public class MidiInputTest {
public MidiDevice input;
public MidiDevice output;
public static void main(String[] args) {
new MidiInputTest().start();
}
public void start() {
init(); // initialize your midi input device
// system dependent
try {
output.open(); // From midi device
MyReceiver myrcvr = new MyReceiver();
MidiSystem.getTransmitter().setReceiver(myrcvr);
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
private class MyReceiver implements Receiver {
Receiver rcvr;
public MyReceiver() {
try {
this.rcvr = MidiSystem.getReceiver();
} catch (MidiUnavailableException mue) {
mue.printStackTrace();
}
}
@Override
public void send(MidiMessage message,long timeStamp) {
byte[] b = message.getMessage();
if (b[0] != (byte)254) {
System.out.println((b[0] & 0xff) + " " + (b[1] & 0xff));
}
//rcvr.send(message,timeStamp); // will send out what ever you receive
}
@Override
public void close() {
rcvr.close();
}
}
public void init() {
MidiDevice.Info[] devices;
devices = MidiSystem.getMidiDeviceInfo();
try{
for (MidiDevice.Info info: devices) {
MidiDevice device;
device = MidiSystem.getMidiDevice(info);
System.out.println("MidiDevice.Info="+info + "\n" + "maxTransmitters="+device.getMaxTransmitters());
// I put the specific device I want to connect to behind an if gate here to avoid connecting to something I do not
if (info.toString().equals("Interface [hw:2,0]") && device.getMaxTransmitters() != 0) {
System.out.println(" Name: " + info.toString() +
",Decription: " +
info.getDescription() +
",Vendor: " +
info.getVendor());
output = MidiSystem.getMidiDevice(info);
if (! output.isOpen()) {
output.open();
}
}
}
} catch (MidiUnavailableException mue) {
mue.printStackTrace();
}
}
}
要从命令行运行此选项,请选择已安装的JDK版本,使用这些特定版本编译并运行它,将jdk1.7.0_80替换为您要测试的发行版.
/opt/java-jdk/jdk1.7.0_80/bin/javac MidiInputTest.java
/opt/java-jdk/jdk1.7.0_80/bin/java -cp . MidiInputTest
虽然我无法对其进行验证,但Java Sound显然负责从MIDI架构中找出可供Java使用的内容.
感谢Mike Harris让我在命令行上找到正确的测试路径,感谢jim829在java-forums.org上找到命令行的示例代码.