Integrated: 8074211: javax.sound.midi: Error with send System Exclusive messages of different length

Alec Su duke at openjdk.org
Tue Nov 21 19:30:18 UTC 2023


On Fri, 27 Oct 2023 11:10:45 GMT, Alec Su <duke at 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...

This pull request has now been integrated.

Changeset: e47cf611
Author:    Alec Su <ae40515 at yahoo.com.tw>
Committer: Phil Race <prr at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/e47cf611c9490225e50a548787cbba66ab147058
Stats:     46 lines in 5 files changed: 20 ins; 0 del; 26 mod

8074211: javax.sound.midi: Error with send System Exclusive messages of different length
8250667: MIDI sysex over USB scrambled when reply length matches previous message

Reviewed-by: prr

-------------

PR: https://git.openjdk.org/jdk/pull/16399


More information about the client-libs-dev mailing list