-
Bug
-
Resolution: Fixed
-
P4
-
7u60
-
b25
-
x86_64
-
windows_7
FULL PRODUCT VERSION :
JDK 7 and 8
tried:
Java 1.7.0_55-b14 (on Win 6.1.7601, 32 bit)
Java 1.8.0_05-b13 (on Win 6.1.7601, 64 bit)
ADDITIONAL OS VERSION INFORMATION :
Windows 6.1.7601
32 bit and 64 bit
EXTRA RELEVANT SYSTEM CONFIGURATION :
tried with 2 types of phisical USB MIDI device on the same OS/Java combination:
E-MU XMidiX1 Tab
MIDIMATE II
A DESCRIPTION OF THE PROBLEM :
After sending a longer System Exclusive message, sending shorter ones doesn't work properly.
The result depends on the actual length, or the difference in length between the messages. It is independent of the time interval between the messages.
Some result examples:
1. The shorter message results in a one byte message: 0xF7 (System Excl End), without 0xF0 (System Excl Start) and without body.
2. The shorter message is followed by one extra 0xF7.
3. The shorter message isn't sent at all.
ADDITIONAL REGRESSION INFORMATION:
Works fine with Windows XP (tried with Java 7)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Connect a physical MIDI In and Out device to the computer.
2. Use a MIDI analyzer that can show the System Exclusive messages sent by the device.
3. Run the code (it takes the first available MIDI output to send the messages).
4. Analyze the sent messages in the MIDI analyzer.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
(hexadecimal)
First message:
F0, 00, 00, 00, F7
Second message:
F0, 00, 00, F7
First message again etc.
ACTUAL -
(hexadecimal)
First message:
F0, 00, 00, 00, F7
Second message:
F0, 00, 00, F7
F7
First message again etc.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
no error message
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package basicMidiOut;
import javax.sound.midi.*;
public class MidiOutTest {
private static MidiDevice device;
private static Receiver midiOutReceiver;
private static MidiDevice.Info getOutputDeviceInfo() {
MidiDevice.Info tempInfo = null;
MidiDevice.Info[] infoArray = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info info : infoArray) {
try {
// check if this device represents a hardware MIDI port, see
// http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiDevice.html
MidiDevice tempDevice = MidiSystem.getMidiDevice(info);
if (!(tempDevice instanceof Sequencer) &&
!(tempDevice instanceof Synthesizer)) {
// http://jsresources.org/faq_midi.html#gettransmitter_objects
// getMaxReceivers() and getMaxTransmitters() return -1 if the max is unlimited
if ((tempDevice.getMaxReceivers() != 0)) {
tempInfo = info;
}
}
} catch (MidiUnavailableException e) {
//todo
}
}
return tempInfo;
}
public static void main(String[] args) {
try {
device = MidiSystem.getMidiDevice(getOutputDeviceInfo());
midiOutReceiver = device.getReceiver();
device.open();
} catch (MidiUnavailableException ex) {
//todo
}
boolean b = false;
byte[] msg1 = {(byte)SysexMessage.SYSTEM_EXCLUSIVE,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)ShortMessage.END_OF_EXCLUSIVE};
byte[] msg2 = {(byte)SysexMessage.SYSTEM_EXCLUSIVE,
(byte)0x00, (byte)0x00, (byte)ShortMessage.END_OF_EXCLUSIVE};
byte[] msg;
for (;;) {
msg = b? msg2 : msg1;
try {
SysexMessage sysxMsg = new SysexMessage(msg, msg.length);
midiOutReceiver.send(sysxMsg, -1);
} catch (InvalidMidiDataException ex) {
//todo
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
//todo
}
//b = true; // repeat short
b = b == false; // toggle long/short
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Close the device and create a new instance each time a System Exclusive is smaller than the previous one.
This also sends All Notes Off codes before closing.
JDK 7 and 8
tried:
Java 1.7.0_55-b14 (on Win 6.1.7601, 32 bit)
Java 1.8.0_05-b13 (on Win 6.1.7601, 64 bit)
ADDITIONAL OS VERSION INFORMATION :
Windows 6.1.7601
32 bit and 64 bit
EXTRA RELEVANT SYSTEM CONFIGURATION :
tried with 2 types of phisical USB MIDI device on the same OS/Java combination:
E-MU XMidiX1 Tab
MIDIMATE II
A DESCRIPTION OF THE PROBLEM :
After sending a longer System Exclusive message, sending shorter ones doesn't work properly.
The result depends on the actual length, or the difference in length between the messages. It is independent of the time interval between the messages.
Some result examples:
1. The shorter message results in a one byte message: 0xF7 (System Excl End), without 0xF0 (System Excl Start) and without body.
2. The shorter message is followed by one extra 0xF7.
3. The shorter message isn't sent at all.
ADDITIONAL REGRESSION INFORMATION:
Works fine with Windows XP (tried with Java 7)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Connect a physical MIDI In and Out device to the computer.
2. Use a MIDI analyzer that can show the System Exclusive messages sent by the device.
3. Run the code (it takes the first available MIDI output to send the messages).
4. Analyze the sent messages in the MIDI analyzer.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
(hexadecimal)
First message:
F0, 00, 00, 00, F7
Second message:
F0, 00, 00, F7
First message again etc.
ACTUAL -
(hexadecimal)
First message:
F0, 00, 00, 00, F7
Second message:
F0, 00, 00, F7
F7
First message again etc.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
no error message
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package basicMidiOut;
import javax.sound.midi.*;
public class MidiOutTest {
private static MidiDevice device;
private static Receiver midiOutReceiver;
private static MidiDevice.Info getOutputDeviceInfo() {
MidiDevice.Info tempInfo = null;
MidiDevice.Info[] infoArray = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info info : infoArray) {
try {
// check if this device represents a hardware MIDI port, see
// http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiDevice.html
MidiDevice tempDevice = MidiSystem.getMidiDevice(info);
if (!(tempDevice instanceof Sequencer) &&
!(tempDevice instanceof Synthesizer)) {
// http://jsresources.org/faq_midi.html#gettransmitter_objects
// getMaxReceivers() and getMaxTransmitters() return -1 if the max is unlimited
if ((tempDevice.getMaxReceivers() != 0)) {
tempInfo = info;
}
}
} catch (MidiUnavailableException e) {
//todo
}
}
return tempInfo;
}
public static void main(String[] args) {
try {
device = MidiSystem.getMidiDevice(getOutputDeviceInfo());
midiOutReceiver = device.getReceiver();
device.open();
} catch (MidiUnavailableException ex) {
//todo
}
boolean b = false;
byte[] msg1 = {(byte)SysexMessage.SYSTEM_EXCLUSIVE,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)ShortMessage.END_OF_EXCLUSIVE};
byte[] msg2 = {(byte)SysexMessage.SYSTEM_EXCLUSIVE,
(byte)0x00, (byte)0x00, (byte)ShortMessage.END_OF_EXCLUSIVE};
byte[] msg;
for (;;) {
msg = b? msg2 : msg1;
try {
SysexMessage sysxMsg = new SysexMessage(msg, msg.length);
midiOutReceiver.send(sysxMsg, -1);
} catch (InvalidMidiDataException ex) {
//todo
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
//todo
}
//b = true; // repeat short
b = b == false; // toggle long/short
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Close the device and create a new instance each time a System Exclusive is smaller than the previous one.
This also sends All Notes Off codes before closing.