Reputation: 155
How do i close a midi device in java? I have tried re-initialising the MidiHandler object, but the device stays open until the program terminates. Also, if i unplug my midi controller while the program is running, it wont send notes after it is reconnected, even after reinitialising. I have to, again, terminate and start the program anew, in order for it to work. I am very new to using midi, so i might be fundamentally misunderstanding the whole concept. Here is what i have so far:
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() {
}
}
The main class simply instantiates a MidiHandler and that works fine, except for the issues above.
Upvotes: 3
Views: 798
Reputation: 1393
You can try:
midiDevice.close();
outputPort.close();
inputPort.close();
Upvotes: 0
Reputation: 26961
You can call MidiDevice::close()
explicit closing is done by calling close()
But the MIDI devices extends Autocloseable
, so, according to the API, you have to close the Transmitter
or Receiver
.
In the API:
The device is closed after the last Receiver or Transmitter has been closed. On the other hand, calling getReceiver or getTransmitter on the device instance directly does not open the device implicitly. Closing these Transmitters and Receivers does not close the device implicitly.
Upvotes: 1
Reputation: 166
Have you checked out Oracle MIDI-messages?
Closing Connections
Once you're done with a connection, you can free up its resources by invoking the close method for each transmitter and receiver that you've obtained. The Transmitter and Receiver interfaces each have a close method. Note that invoking Transmitter.setReceiver doesn't close the transmitter's current receiver. The receiver is left open, and it can still receive messages from any other transmitter that's connected to it.
If you're also done with the devices, you can similarly make them available to other application programs by invoking MidiDevice.close(). Closing a device automatically closes all its transmitters and receivers.
Upvotes: 1