-
Bug
-
Resolution: Fixed
-
P4
-
8u191, 14.0.1
-
b25
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Intel or compatible PC, Windows 10 (build 19041 or other), Java 14.0.1 (64 bit AdoptOpenJDK build 14.0.1+7 hotspot, mixed mode, sharing) or Java 1.8.0_191 (32-bit JRE, build 25.191-b12, mixed mode).
A DESCRIPTION OF THE PROBLEM :
When sending a sysex message of a certain length n, followed by a sysex message causing a sysex reply of length n (sometimes n+1 or n-1), the next (third) sysex message is totally mixed up. It contains some artifacts from the previous messages and invalid (zero) USB midi headers. The problem is reliably reproducible and the content of the messages sent via USB is always the same, independently of timing. The error does not occur when sending these messages from python using rtmidi.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code below with an Ableton Push 2 attached via USB. Use an USB sniffer like BEAGLE USB 480 for tracing. Analyse the outgoing data. Alternatively, use display brightness setting as third sysex command to see if it works (commented out).
To repoduce with other hardware: Other USB MIDI hardware sends replies of different length to the device inquiry used as second command. Therefore, to reproduce the issue for other hardware, the length of the first sysex message needs to be adopted - just add or remove bytes. The third sysex should do something observable with that hardware.
The python program to verify its not a driver issue looks as follows (run with python 2.7, sorry):
---- cut here ----
#!/usr/bin/env python
import rtmidi
import re
def open_push2_midiout():
pattern = "Ableton Push 2( [0-9]+)*"
midiio = rtmidi.MidiOut()
ports = midiio.get_ports()
for i, port in enumerate(ports):
if re.match(pattern, port):
midiio.open_port(i)
return midiio
return None
midiout = open_push2_midiout()
midiout.send_message([0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0xF7])
midiout.send_message([0xF0, 0x7E, 0x7F, 0x06, 0x01, 0xF7])
midiout.send_message([0xF0, 0x00, 0xF7])
# midiout.send_message([0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x08, 0x3F, 0x00, 0xF7])
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Correct sysex transfer (as produced by python script with rtmidi, see below):
> sysex message f0000102030405060708090a0b0c0d0e0f1011121314f7 <--- 23 MIDI bytes
sent:
04 F0 00 01
04 02 03 04
04 05 06 07
04 08 09 0A
04 0B 0C 0D
04 0E 0F 10
04 11 12 13
06 14 F7 00
> sysex message f07e7f0601f7
sent:
04 F0 7E 7F
07 06 01 F7
received: (23 MIDI bytes)
04 F0 7E 01
04 06 02 00
04 21 1D 67
04 32 02 00
04 01 00 46
04 00 16 7A
04 28 08 00
06 01 F7 00
> sysex message f000f7
sent:
07 F0 00 F7
ACTUAL -
Incorrect sysex transfer (as produced by the given Java program)
> sysex message f0000102030405060708090a0b0c0d0e0f1011121314f7 <--- 23 MIDI bytes
sent:
04 F0 00 01
04 02 03 04
04 05 06 07
04 08 09 0A
04 0B 0C 0D
04 0E 0F 10
04 11 12 13
06 14 F7 00
> sysex message f07e7f0601f7
sent:
04 F0 7E 7F
07 06 01 F7
00 05 06 07 <--- extra bytes with zero headers
00 08 09 0A
00 0B 0C 0D
00 0E 0F 10
00 11 12 13
received: (23 MIDI bytes)
04 F0 7E 01
04 06 02 00
04 21 1D 67
04 32 02 00
04 01 00 46
04 00 16 7A
04 28 08 00
06 01 F7 00
> sysex message f000f7
sent:
00 14 F7 00 <- no useful sysex from here, zero headers
00 06 01 06
00 05 06 05
00 08 07 08
00 0B 0A 0B
00 0E 0D 0E
00 11 10 11
00 14 13 14
05 F7 00 00
---------- BEGIN SOURCE ----------
import javax.sound.midi.*;
class SysexTest {
static MidiDevice findOutPort() throws MidiUnavailableException {
MidiDevice.Info[] infoArray = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info info : infoArray) {
if (info.getName().equals("Ableton Push 2")) {
MidiDevice port = MidiSystem.getMidiDevice(info);
if (port.getMaxReceivers() != 0) {
return port;
}
}
}
return null;
}
static void sendMessage(MidiDevice outPort, byte[] data) throws Exception {
SysexMessage msg = new SysexMessage(data, data.length);
outPort.getReceiver().send(msg, -1l);
}
static final byte[] data1 = new byte[] {(byte)0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, (byte)0xF7};
static final byte[] data2 = new byte[] {(byte)0xF0, 0x7E, 0x7F, 0x06, 0x01, (byte)0xF7};
static final byte[] data3 = new byte[] {(byte)0xF0, 0x00, (byte)0xF7};
// alternatively, set display backlight brightness to 25%
// static final byte[] data3 = new byte[] {(byte)0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01,
// 0x08, 0x3F, 0x00, (byte)0xF7};
public static void main(String[] args) throws Exception {
MidiDevice outPort = findOutPort();
outPort.open();
sendMessage(outPort, data1); // dummy message of 23 bytes
sendMessage(outPort, data2); // device inquiry with 23 bytes reponse
sendMessage(outPort, data3); // this message is sent out scrambled
System.exit(0);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
no workarounds known
FREQUENCY : always
Intel or compatible PC, Windows 10 (build 19041 or other), Java 14.0.1 (64 bit AdoptOpenJDK build 14.0.1+7 hotspot, mixed mode, sharing) or Java 1.8.0_191 (32-bit JRE, build 25.191-b12, mixed mode).
A DESCRIPTION OF THE PROBLEM :
When sending a sysex message of a certain length n, followed by a sysex message causing a sysex reply of length n (sometimes n+1 or n-1), the next (third) sysex message is totally mixed up. It contains some artifacts from the previous messages and invalid (zero) USB midi headers. The problem is reliably reproducible and the content of the messages sent via USB is always the same, independently of timing. The error does not occur when sending these messages from python using rtmidi.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code below with an Ableton Push 2 attached via USB. Use an USB sniffer like BEAGLE USB 480 for tracing. Analyse the outgoing data. Alternatively, use display brightness setting as third sysex command to see if it works (commented out).
To repoduce with other hardware: Other USB MIDI hardware sends replies of different length to the device inquiry used as second command. Therefore, to reproduce the issue for other hardware, the length of the first sysex message needs to be adopted - just add or remove bytes. The third sysex should do something observable with that hardware.
The python program to verify its not a driver issue looks as follows (run with python 2.7, sorry):
---- cut here ----
#!/usr/bin/env python
import rtmidi
import re
def open_push2_midiout():
pattern = "Ableton Push 2( [0-9]+)*"
midiio = rtmidi.MidiOut()
ports = midiio.get_ports()
for i, port in enumerate(ports):
if re.match(pattern, port):
midiio.open_port(i)
return midiio
return None
midiout = open_push2_midiout()
midiout.send_message([0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0xF7])
midiout.send_message([0xF0, 0x7E, 0x7F, 0x06, 0x01, 0xF7])
midiout.send_message([0xF0, 0x00, 0xF7])
# midiout.send_message([0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01, 0x08, 0x3F, 0x00, 0xF7])
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Correct sysex transfer (as produced by python script with rtmidi, see below):
> sysex message f0000102030405060708090a0b0c0d0e0f1011121314f7 <--- 23 MIDI bytes
sent:
04 F0 00 01
04 02 03 04
04 05 06 07
04 08 09 0A
04 0B 0C 0D
04 0E 0F 10
04 11 12 13
06 14 F7 00
> sysex message f07e7f0601f7
sent:
04 F0 7E 7F
07 06 01 F7
received: (23 MIDI bytes)
04 F0 7E 01
04 06 02 00
04 21 1D 67
04 32 02 00
04 01 00 46
04 00 16 7A
04 28 08 00
06 01 F7 00
> sysex message f000f7
sent:
07 F0 00 F7
ACTUAL -
Incorrect sysex transfer (as produced by the given Java program)
> sysex message f0000102030405060708090a0b0c0d0e0f1011121314f7 <--- 23 MIDI bytes
sent:
04 F0 00 01
04 02 03 04
04 05 06 07
04 08 09 0A
04 0B 0C 0D
04 0E 0F 10
04 11 12 13
06 14 F7 00
> sysex message f07e7f0601f7
sent:
04 F0 7E 7F
07 06 01 F7
00 05 06 07 <--- extra bytes with zero headers
00 08 09 0A
00 0B 0C 0D
00 0E 0F 10
00 11 12 13
received: (23 MIDI bytes)
04 F0 7E 01
04 06 02 00
04 21 1D 67
04 32 02 00
04 01 00 46
04 00 16 7A
04 28 08 00
06 01 F7 00
> sysex message f000f7
sent:
00 14 F7 00 <- no useful sysex from here, zero headers
00 06 01 06
00 05 06 05
00 08 07 08
00 0B 0A 0B
00 0E 0D 0E
00 11 10 11
00 14 13 14
05 F7 00 00
---------- BEGIN SOURCE ----------
import javax.sound.midi.*;
class SysexTest {
static MidiDevice findOutPort() throws MidiUnavailableException {
MidiDevice.Info[] infoArray = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info info : infoArray) {
if (info.getName().equals("Ableton Push 2")) {
MidiDevice port = MidiSystem.getMidiDevice(info);
if (port.getMaxReceivers() != 0) {
return port;
}
}
}
return null;
}
static void sendMessage(MidiDevice outPort, byte[] data) throws Exception {
SysexMessage msg = new SysexMessage(data, data.length);
outPort.getReceiver().send(msg, -1l);
}
static final byte[] data1 = new byte[] {(byte)0xF0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, (byte)0xF7};
static final byte[] data2 = new byte[] {(byte)0xF0, 0x7E, 0x7F, 0x06, 0x01, (byte)0xF7};
static final byte[] data3 = new byte[] {(byte)0xF0, 0x00, (byte)0xF7};
// alternatively, set display backlight brightness to 25%
// static final byte[] data3 = new byte[] {(byte)0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01,
// 0x08, 0x3F, 0x00, (byte)0xF7};
public static void main(String[] args) throws Exception {
MidiDevice outPort = findOutPort();
outPort.open();
sendMessage(outPort, data1); // dummy message of 23 bytes
sendMessage(outPort, data2); // device inquiry with 23 bytes reponse
sendMessage(outPort, data3); // this message is sent out scrambled
System.exit(0);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
no workarounds known
FREQUENCY : always