Как закрыть миди-устройство?
Как закрыть 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();