MIDI OUT发射器不可用

时间:2016-01-05 22:16:33

标签: java midi

我整天都在敲打我的脑袋,阅读我能找到的所有内容,按照JDK来源,找不到关于 HOW 的血腥细节WHERE java希望在midi设备上获取数据并确定它是什么。

我试图通过我的NI Audio 8 DJ MIDI IN端口捕获midi消息,但是,java并没有" t"看到" 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]Interface [hw:2,0]

下面的代码适用于Receiver,我认为只有我需要验证getTransmitter()抓取端口,因为它只适用于另一个并且一切正常,我得到一个MidiUnavailableException /发送器不可用例外。

我甚至把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看到的输入端口。

我使用eclipse版本进行编码:3.8.1带有JDK1.6的IDE,在Linux模拟操作系统上,。

我很乐意提供任何要求的东西。谢谢你的阅读!

2 个答案:

答案 0 :(得分:3)

java看到发送器的解决方案是在使用的JDK版本中,但不幸的是,此时,我没有回答为什么失败,只是一个版本工作并且暂时适合我的需要。如果我找到答案,我会编辑这个答案。

我在测试之间切换的三个版本中,jdk1.8.0_60,jdk1.7.0_80,jdk1.6.0_45,1.7没有遇到错误并成功从我的设备获得了一个发送器。我发现了这一点,并且通过编译和运行一些适合命令行执行的代码found来尝试获取发送器,打印出发送给它的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 Sound显然负责确定从MIDI架构中使用java的内容。

感谢Mike Harris在命令行上向我发送了正确的测试路径,感谢jim829在java-forums.org上找到了命令行的示例代码。

答案 1 :(得分:0)

我遇到了此问题,这是由MidiSystem.getMidiDeviceInfo()替换了具有相同名称的设备信息的多个实例引起的。基本上,如果不幸的话,当您调用MidiSystem.getMidiDevice(Info)时,它将返回不带发送器的那个。我不确定为什么要这样做,但是只有一个实例具有发送器,(我认为其中一个可能是输入输出,但不确定)。通过首先获取具有发射器的设备,然后从它们中选择所需的信息,它对我有用。希望有帮助

select collect_set(df2.col1) as col1, df1.id as col2
from df2 lateral view
     explode(col2) s as c2 join
     df1
     on df1.id = s.c2
group by df1.id;