Как закрыть миди-устройство?

Как закрыть MIDI-устройство в Java? Я попытался повторно инициализировать объект MidiHandler, но устройство остается открытым до завершения программы. Кроме того, если я отключу свой 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, и это прекрасно работает, за исключением вышеуказанных проблем.

3 ответа

Решение

Вы проверяли MIDI-сообщения Oracle?

Закрытие соединения

Завершив соединение, вы можете освободить его ресурсы, вызвав метод close для каждого полученного вами передатчика и приемника. Интерфейсы передатчика и приемника имеют закрытый метод. Обратите внимание, что вызов Transmitter.setReceiver не закрывает текущий приемник передатчика. Приемник остается открытым, и он по-прежнему может получать сообщения от любого другого передатчика, подключенного к нему.

Если вы также покончили с устройствами, вы можете аналогичным образом сделать их доступными для других прикладных программ, вызвав MidiDevice.close(). Закрытие устройства автоматически закрывает все его передатчики и приемники.

Вы можете позвонить MidiDevice::close()

явное закрытие выполняется вызовом close ()

Но MIDI-устройства расширяются AutocloseableТаким образом, в соответствии с API, вы должны закрыть Transmitter или же Receiver,

В API:

Устройство закрывается после закрытия последнего Приемника или Передатчика. С другой стороны, вызов getReceiver или getTransmitter для экземпляра устройства напрямую не открывает устройство неявным образом. Закрытие этих передатчиков и приемников не закрывает устройство неявным образом.

Можешь попробовать:

      midiDevice.close();
outputPort.close();
inputPort.close();
Другие вопросы по тегам