On Fri, 27 Oct 2023 11:10:45 GMT, Alec Su <d...@openjdk.org> wrote: > JVM attempts to reuse the buffer for sending MIDI out data when the buffer > size is enough. It use `dwBytesRecorded` in `MIDIHDR` structure to indicate > the actual size of the data. However, `midiOutLongMsg()` ignores > `dwBytesRecorded`, although it did not mentioned in the documentation. I've > tested on Windows 7, 10 and 11. All of them have the same behavior. > > The bug cannot be easily reproduced because some MIDI drivers filter out any > malformed MIDI data. The example code below create a special case to make > sure all MIDI data are legally when the bug is triggered. > > > import javax.sound.midi.*; > > public class MidiTest { > public static class RawMidiMessage extends MidiMessage { > public RawMidiMessage(byte[] data) { > super(data); > } > > @Override > public Object clone() { > return new RawMidiMessage(this.getMessage()); > } > } > > public static void main(String[] args) { > var deviceInfos = MidiSystem.getMidiDeviceInfo(); > for (var info : deviceInfos) { > try (MidiDevice device = MidiSystem.getMidiDevice(info)) { > if (device.getMaxReceivers() != 0) { > System.out.println("Open MIDI port: " + info.getName()); > device.open(); > Receiver receiver = device.getReceiver(); > // Send two sysex messages at once > receiver.send(new RawMidiMessage(new byte[]{ > (byte) 0xF0, 0x7D, 0x01, (byte) 0xF7, > (byte) 0xF0, 0x7D, 0x02, (byte) 0xF7 > }), -1); > // Send another sysex message > receiver.send(new RawMidiMessage(new byte[]{(byte) 0xF0, > 0x7D, 0x03, (byte) 0xF7}), -1); > } > } catch (MidiUnavailableException e) { > e.printStackTrace(); > } > } > } > } > > > The expected messages received should be the following three messages > > F0 7D 01 F7 > F0 7D 02 F7 > F0 7D 03 F7 > > > But acually four messages was received with the second message repeated twice. > > F0 7D 01 F7 > F0 7D 02 F7 > F0 7D 03 F7 > F0 7D 02 F7 > > > To resolve the issue, I add a new variable to backup the actual buffer size > and set `dwBufferLength` of `MIDIHDR` structure to the size of MIDI data. > After calling `midiOutLongMsg()`, I restore the original buffer size if the > buffer hasn't been freed due to an error. > > It seems that the patch may also resolve JDK-8250667. The extra bytes in the > s...
I think the java code in the description can be added as a testcase, even if it works fine before the patch, it is useful that the affected code will be triggered. As an example you can use the tests in the next folder: https://github.com/openjdk/jdk/tree/master/test/jdk/javax/sound ------------- PR Comment: https://git.openjdk.org/jdk/pull/16399#issuecomment-1783346826