Java MIDI输出发射机不可用
我花了一整天的时间研究这个问题,阅读了所有我能找到的东西,跟踪了JDK源代码,没有找到java如何或在何处在midi设备上获取数据并确定是什么的血淋淋的细节 我试图通过我的Java MIDI输出发射机不可用,java,midi,Java,Midi,我花了一整天的时间研究这个问题,阅读了所有我能找到的东西,跟踪了JDK源代码,没有找到java如何或在何处在midi设备上获取数据并确定是什么的血淋淋的细节 我试图通过我的NI Audio 8 DJ midi IN端口捕获midi消息,但是,java没有“看到”midi IN端口,只有out端口,我已经成功地使用它发送midi。对于M-Audio USB UNO midi设备,我也得到了相同的结果:MidiSystem.getMidiDeviceInfo()仅“看到”输出端口 我已通过以下方式验
NI Audio 8 DJ midi IN
端口捕获midi消息,但是,java没有“看到”midi IN端口,只有out端口,我已经成功地使用它发送midi。对于M-Audio USB UNO midi设备,我也得到了相同的结果:MidiSystem.getMidiDeviceInfo()
仅“看到”输出端口
我已通过以下方式验证了MIDI在端口中的操作:
amidi -p hw:2,0 -d
并向它发送一些信号。很好
getMaxTransmissions()
返回零。
MidiSystem.getMidiDeviceInfo()
仅显示两台设备的一个条目:Audio8DJ[hw:2,0]
或接口[hw:2,0]
下面的代码适用于接收器,我想我只需要验证getTransmiter()
是否抓取了端口,因为它只适用于另一个端口,而且一切正常,所以我得到了一个MidiUnavailableException/Transmiter not available异常
我甚至把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进行排序,将其分配给com.sun.media.sound.MidiOutDeviceProvider
类,因此我想知道Java是如何或从何处知道设备必须提供什么,为什么它看不到alsa看到的输入端口
我使用eclipse版本编码:3.8.1 IDE和JDK1.6,在LinuxMint操作系统上
我很乐意提供任何需要的东西。谢谢你的阅读 java变送器的解决方案是使用JDK版本,但不幸的是,目前我还不知道为什么会出现故障,只有一个版本可以工作,并且适合我目前的需要。如果我找到了答案,我会编辑这个答案 在我切换测试的三个版本中,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,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声音显然负责从MIDI体系结构中找出Java可用的内容
感谢Mike Harris给我发送了命令行测试的正确路径,感谢jim829在java-forums.org上提供了命令行的示例代码。我遇到了这个问题,它是由MidiSystem.getMidiDeviceInfo()重新调用的同名设备信息的多个实例引起的。基本上,当你调用MidiSystem.getMidiDevice(Info)时,如果你运气不好,它会返回没有发射机的设备。我不确定它为什么会这样做,但只有一个实例有发射机(我认为一个可能用于输入,一个用于输出,但不确定)。通过首先只获取带有发射机的设备,然后从这些设备中选择所需的信息,这对我很有用。希望有帮助
public ArrayList<MidiDevice> getTransmitterDevices() {
MidiDevice.Info[] deviceInfo = MidiSystem.getMidiDeviceInfo();
ArrayList<MidiDevice> transmitterDevices = new ArrayList<>();
for(int i=0;i<deviceInfo.length;i++) {
try {
MidiDevice device = MidiSystem.getMidiDevice(deviceInfo[i]);
if(device.getMaxTransmitters()!=0) {
transmitterDevices.add(device);
}
} catch (MidiUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return transmitterDevices;
}
//Somewhere else
//choose appropriate info somehow
MidiDevices<ArrayList> transmitterDevices = getTransmitterDevices();
for(MidiDevice tmp : transmitterDevices) {
if(tmp.getDeviceInfo().equals(info)) {
try {
midiController = tmp;
Transmitter transmitter = midiController.getTransmitter();
// something that implements receiver
midiReceiver = new MidiReceiver();
transmitter.setReceiver(midiReceiver);
midiController.open();
System.out.println("controller set ok");
} catch (MidiUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public ArrayList getTransmitterDevices(){
MidiDevice.Info[]设备信息=MidiSystem.getMidiDeviceInfo();
ArrayList transmitterDevices=新的ArrayList();
对于(inti=0;我只是一个随机的想法……您是否尝试过使用sudo
?(即,sudojavayour.class.name
)在命令行中运行它。)我看到过一些问题,您需要成为root用户才能操作某些设备,因此可能值得一试。我已经想到了这一点,我愿意接受建议,但是,我一直不愿尝试,原因有两个:作为root用户运行复杂应用程序是危险的,这是下意识的反应:1)由于它可以获得MIDI输出端口,而不会出现输出问题,因此我更愿意找出是什么文件java正在访问并解决这个问题。2)它不应该以root用户身份运行,如果以root用户身份运行解决了这个问题,我又回到了同样的问题,即找出哪个文件存在访问问题。再次感谢你的帮助,迈克,你让我朝着正确的方向前进。请看下面我的答案。JDK 1.7在Ubuntu 16.04及更高版本上不再可用。。。它可以通过手动过程安装,但不安全。是否值得报告Java错误?