2

我如何在java中关闭midi设备?我尝试重新初始化 MidiHandler 对象,但设备保持打开状态,直到程序终止。此外,如果我在程序运行时拔下我的 midi 控制器,它不会在重新连接后发送注释,即使在重新初始化之后也是如此。我必须再次终止并重新启动程序,才能使其正常工作。我对使用 midi 很陌生,所以我可能从根本上误解了整个概念。这是我到目前为止所拥有的:

public class MidiHandler {
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();

public MidiHandler() {

    for (int i = 0; i < infos.length; i++) {
        try {
            this.device = MidiSystem.getMidiDevice(this.infos[i]);
            // does the device have any transmitters?
            // if it does, add it to the device list
            System.out.println(this.infos[i]);

            // get all transmitters
            List<Transmitter> transmitters = this.device.getTransmitters();
            // and for each transmitter

            for (int j = 0; j < transmitters.size(); j++) {
                // create a new receiver
                transmitters.get(j).setReceiver(
                // using my own MidiInputReceiver
                        new MidiInputReceiver(this.device.getDeviceInfo()
                                .toString()));
            }

            Transmitter trans = this.device.getTransmitter();
            trans.setReceiver(new MidiInputReceiver(this.device.getDeviceInfo()
                    .toString()));
            this.device.open();
        } catch (MidiUnavailableException e) {
        }
    }

}

public void close() {

}

public String getInfos() {
    String infos = "";
    for(int i = 0; i < this.infos.length; i++) {
        infos += "\n" + this.infos[i] + " ";
    }
    return infos;
}

// tried to write my own class. I thought the send method handles an
// MidiEvents sent to it
public class MidiInputReceiver implements Receiver {
    Synthesizer synth;
    MidiChannel[] mc;
    Instrument[] instr;
    int instrument;
    int channel;

    public MidiInputReceiver(String name) {
        try
        {
            patcher p = new patcher();
            this.instrument = p.getInstrument();
            this.channel = p.getChannel();
            this.synth = MidiSystem.getSynthesizer();
            this.synth.open();
            this.mc = synth.getChannels();
            instr = synth.getDefaultSoundbank().getInstruments();
            this.synth.loadInstrument(instr[1]);
            mc[this.channel].programChange(0, this.instrument);
        }
        catch (MidiUnavailableException e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void send(MidiMessage msg, long timeStamp) {
        /*
         * Use to display midi message
         */ 
        for(int i = 0; i < msg.getMessage().length; i++) {
            System.out.print("[" + msg.getMessage()[i] + "] ");

        }
        System.out.println();

        if (msg.getMessage()[0] == -112) {
            mc[this.channel].noteOn(msg.getMessage()[1], msg.getMessage()[2]+1000);
        }

        if (msg.getMessage()[0] == -128) {
            mc[this.channel].noteOff(msg.getMessage()[1], msg.getMessage()[2]+1000);
        }

    }

    public void close() {
    }
}

主类只是实例化了一个 MidiHandler 并且工作正常,除了上面的问题。

4

2 回答 2

1

你检查过Oracle MIDI 消息吗?

关闭连接

完成连接后,您可以通过为已获得的每个发送器和接收器调用 close 方法来释放其资源。Transmitter 和 Receiver 接口各有一个 close 方法。请注意,调用 Transmitter.setReceiver 不会关闭发送器的当前接收器。接收器保持打开状态,它仍然可以接收来自与其连接的任何其他发射器的消息。

如果您也完成了这些设备,您可以通过调用 MidiDevice.close() 类似地使它们对其他应用程序可用。关闭设备会自动关闭其所有发射器和接收器。

于 2015-04-15T19:44:08.967 回答
1

您可以调用MidiDevice::close()

通过调用 close() 来完成显式关闭

但是 MIDI 设备扩展了Autocloseable,因此,根据 API,您必须关闭Transmitteror Receiver

API中:

关闭最后一个接收器或发射器后,设备将关闭。另一方面,直接在设备实例上调用 getReceiver 或 getTransmitter 不会隐式打开设备。关闭这些发送器和接收器不会隐式关闭设备。

于 2015-04-15T19:44:19.370 回答