Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MIDI输出发射机不可用_Java_Midi - Fatal编程技术网

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()仅“看到”输出端口 我已通过以下方式验

我花了一整天的时间研究这个问题,阅读了所有我能找到的东西,跟踪了JDK源代码,没有找到java如何或在何处在midi设备上获取数据并确定是什么的血淋淋的细节

我试图通过我的
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错误?