8282578: AIOOBE in javax.sound.sampled.Clip
Reviewed-by: prr, aivanov, azvegint
This commit is contained in:
parent
8b69a2e434
commit
af8fb7eef7
src/java.desktop/share/classes/com/sun/media/sound
test/jdk/javax/sound/midi/SysexMessage
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -123,102 +123,126 @@ public final class SoftMainMixer {
|
||||
private void processSystemExclusiveMessage(byte[] data) {
|
||||
synchronized (synth.control_mutex) {
|
||||
activity();
|
||||
|
||||
if (data.length < 3 || (data[1] & 0xFF) != 0x7E && (data[1] & 0xFF) != 0x7F ) {
|
||||
// Not enough data to determine SysEx type or SysEx type is not supported
|
||||
return;
|
||||
}
|
||||
// Universal Non-Real-Time SysEx
|
||||
if ((data[1] & 0xFF) == 0x7E) {
|
||||
int deviceID = data[2] & 0xFF;
|
||||
if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
|
||||
if (data.length < 4) {
|
||||
return;
|
||||
}
|
||||
int subid1 = data[3] & 0xFF;
|
||||
int subid2;
|
||||
switch (subid1) {
|
||||
case 0x08: // MIDI Tuning Standard
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // BULK TUNING DUMP
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(0,
|
||||
data[5] & 0xFF));
|
||||
tuning.load(data);
|
||||
break;
|
||||
}
|
||||
case 0x04: // KEY-BASED TUNING DUMP
|
||||
case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
|
||||
case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
|
||||
case 0x07: // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
|
||||
case 0x08: // MIDI Tuning Standard
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // BULK TUNING DUMP
|
||||
{
|
||||
if (data.length < 6) {
|
||||
break;
|
||||
}
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(0,
|
||||
data[5] & 0xFF));
|
||||
tuning.load(data);
|
||||
break;
|
||||
}
|
||||
case 0x04: // KEY-BASED TUNING DUMP
|
||||
case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
|
||||
case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
|
||||
case 0x07: // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
|
||||
// (BANK)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(
|
||||
data[5] & 0xFF, data[6] & 0xFF));
|
||||
tuning.load(data);
|
||||
break;
|
||||
}
|
||||
case 0x08: // scale/octave tuning 1-byte form (Non
|
||||
{
|
||||
if (data.length < 7) {
|
||||
break;
|
||||
}
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(
|
||||
data[5] & 0xFF, data[6] & 0xFF));
|
||||
tuning.load(data); // Check inside!
|
||||
break;
|
||||
}
|
||||
case 0x08: // scale/octave tuning 1-byte form (Non
|
||||
// Real-Time)
|
||||
case 0x09: // scale/octave tuning 2-byte form (Non
|
||||
case 0x09: // scale/octave tuning 2-byte form (Non
|
||||
// Real-Time)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
SoftTuning tuning = new SoftTuning(data);
|
||||
int channelmask = (data[5] & 0xFF) * 16384
|
||||
+ (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
|
||||
SoftChannel[] channels = synth.channels;
|
||||
for (int i = 0; i < channels.length; i++)
|
||||
if ((channelmask & (1 << i)) != 0)
|
||||
channels[i].tuning = tuning;
|
||||
{
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
SoftTuning tuning = new SoftTuning(data);
|
||||
int channelmask = (data[5] & 0xFF) * 16384
|
||||
+ (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
|
||||
SoftChannel[] channels = synth.channels;
|
||||
for (int i = 0; i < channels.length; i++)
|
||||
if ((channelmask & (1 << i)) != 0)
|
||||
channels[i].tuning = tuning;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case 0x09: // General Midi Message
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // General Midi 1 On
|
||||
synth.setGeneralMidiMode(1);
|
||||
reset();
|
||||
break;
|
||||
case 0x02: // General Midi Off
|
||||
synth.setGeneralMidiMode(0);
|
||||
reset();
|
||||
break;
|
||||
case 0x03: // General MidI Level 2 On
|
||||
synth.setGeneralMidiMode(2);
|
||||
reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x09: // General Midi Message
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // General Midi 1 On
|
||||
synth.setGeneralMidiMode(1);
|
||||
reset();
|
||||
case 0x0A: // DLS Message
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // DLS On
|
||||
if (synth.getGeneralMidiMode() == 0)
|
||||
synth.setGeneralMidiMode(1);
|
||||
synth.voice_allocation_mode = 1;
|
||||
reset();
|
||||
break;
|
||||
case 0x02: // DLS Off
|
||||
synth.setGeneralMidiMode(0);
|
||||
synth.voice_allocation_mode = 0;
|
||||
reset();
|
||||
break;
|
||||
case 0x03: // DLS Static Voice Allocation Off
|
||||
synth.voice_allocation_mode = 0;
|
||||
break;
|
||||
case 0x04: // DLS Static Voice Allocation On
|
||||
synth.voice_allocation_mode = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x02: // General Midi Off
|
||||
synth.setGeneralMidiMode(0);
|
||||
reset();
|
||||
break;
|
||||
case 0x03: // General MidI Level 2 On
|
||||
synth.setGeneralMidiMode(2);
|
||||
reset();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x0A: // DLS Message
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // DLS On
|
||||
if (synth.getGeneralMidiMode() == 0)
|
||||
synth.setGeneralMidiMode(1);
|
||||
synth.voice_allocation_mode = 1;
|
||||
reset();
|
||||
break;
|
||||
case 0x02: // DLS Off
|
||||
synth.setGeneralMidiMode(0);
|
||||
synth.voice_allocation_mode = 0;
|
||||
reset();
|
||||
break;
|
||||
case 0x03: // DLS Static Voice Allocation Off
|
||||
synth.voice_allocation_mode = 0;
|
||||
break;
|
||||
case 0x04: // DLS Static Voice Allocation On
|
||||
synth.voice_allocation_mode = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,197 +251,240 @@ public final class SoftMainMixer {
|
||||
if ((data[1] & 0xFF) == 0x7F) {
|
||||
int deviceID = data[2] & 0xFF;
|
||||
if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
|
||||
if (data.length < 4) {
|
||||
return;
|
||||
}
|
||||
int subid1 = data[3] & 0xFF;
|
||||
int subid2;
|
||||
switch (subid1) {
|
||||
case 0x04: // Device Control
|
||||
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Master Volume
|
||||
case 0x02: // Master Balane
|
||||
case 0x03: // Master fine tuning
|
||||
case 0x04: // Master coarse tuning
|
||||
int val = (data[5] & 0x7F)
|
||||
+ ((data[6] & 0x7F) * 128);
|
||||
if (subid2 == 0x01)
|
||||
setVolume(val);
|
||||
else if (subid2 == 0x02)
|
||||
setBalance(val);
|
||||
else if (subid2 == 0x03)
|
||||
setFineTuning(val);
|
||||
else if (subid2 == 0x04)
|
||||
setCoarseTuning(val);
|
||||
break;
|
||||
case 0x05: // Global Parameter Control
|
||||
int ix = 5;
|
||||
int slotPathLen = (data[ix++] & 0xFF);
|
||||
int paramWidth = (data[ix++] & 0xFF);
|
||||
int valueWidth = (data[ix++] & 0xFF);
|
||||
int[] slotPath = new int[slotPathLen];
|
||||
for (int i = 0; i < slotPathLen; i++) {
|
||||
int msb = (data[ix++] & 0xFF);
|
||||
int lsb = (data[ix++] & 0xFF);
|
||||
slotPath[i] = msb * 128 + lsb;
|
||||
case 0x04: // Device Control
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
int paramCount = (data.length - 1 - ix)
|
||||
/ (paramWidth + valueWidth);
|
||||
long[] params = new long[paramCount];
|
||||
long[] values = new long[paramCount];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
values[i] = 0;
|
||||
for (int j = 0; j < paramWidth; j++)
|
||||
params[i] = params[i] * 128
|
||||
+ (data[ix++] & 0xFF);
|
||||
for (int j = 0; j < valueWidth; j++)
|
||||
values[i] = values[i] * 128
|
||||
+ (data[ix++] & 0xFF);
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Master Volume
|
||||
case 0x02: // Master Balane
|
||||
case 0x03: // Master fine tuning
|
||||
case 0x04: // Master coarse tuning
|
||||
if (data.length < 7) {
|
||||
break;
|
||||
}
|
||||
int val = (data[5] & 0x7F)
|
||||
+ ((data[6] & 0x7F) * 128);
|
||||
if (subid2 == 0x01)
|
||||
setVolume(val);
|
||||
else if (subid2 == 0x02)
|
||||
setBalance(val);
|
||||
else if (subid2 == 0x03)
|
||||
setFineTuning(val);
|
||||
else if (subid2 == 0x04)
|
||||
setCoarseTuning(val);
|
||||
break;
|
||||
case 0x05: // Global Parameter Control
|
||||
if (data.length < 6) {
|
||||
break;
|
||||
}
|
||||
int ix = 5;
|
||||
int slotPathLen = (data[ix++] & 0xFF);
|
||||
if (data.length < slotPathLen * 2 + 8) {
|
||||
break;
|
||||
}
|
||||
int paramWidth = (data[ix++] & 0xFF);
|
||||
int valueWidth = (data[ix++] & 0xFF);
|
||||
int[] slotPath = new int[slotPathLen];
|
||||
for (int i = 0; i < slotPathLen; i++) {
|
||||
int msb = (data[ix++] & 0xFF);
|
||||
int lsb = (data[ix++] & 0xFF);
|
||||
slotPath[i] = msb * 128 + lsb;
|
||||
}
|
||||
int paramCount = (data.length - 1 - ix)
|
||||
/ (paramWidth + valueWidth);
|
||||
if (paramCount < 1) {
|
||||
break;
|
||||
}
|
||||
long[] params = new long[paramCount];
|
||||
long[] values = new long[paramCount];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
values[i] = 0;
|
||||
for (int j = 0; j < paramWidth; j++)
|
||||
params[i] = params[i] * 128
|
||||
+ (data[ix++] & 0xFF);
|
||||
for (int j = 0; j < valueWidth; j++)
|
||||
values[i] = values[i] * 128
|
||||
+ (data[ix++] & 0xFF);
|
||||
|
||||
}
|
||||
globalParameterControlChange(slotPath, params, values);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
globalParameterControlChange(slotPath, params, values);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08: // MIDI Tuning Standard
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(0,
|
||||
data[5] & 0xFF));
|
||||
tuning.load(data);
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if (voices[i].tuning == tuning)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
case 0x07: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
|
||||
case 0x08: // MIDI Tuning Standard
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
if (data.length < 6) {
|
||||
break;
|
||||
}
|
||||
SoftTuning tuning = synth.getTuning(new Patch(0,
|
||||
data[5] & 0xFF));
|
||||
tuning.load(data);
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if (voices[i].tuning == tuning)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
case 0x07: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
|
||||
// (BANK)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
SoftTuning tuning = synth.getTuning(new Patch(
|
||||
data[5] & 0xFF, data[6] & 0xFF));
|
||||
tuning.load(data);
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if (voices[i].tuning == tuning)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
case 0x08: // scale/octave tuning 1-byte form
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
if (data.length < 7) {
|
||||
break;
|
||||
}
|
||||
SoftTuning tuning = synth.getTuning(new Patch(
|
||||
data[5] & 0xFF, data[6] & 0xFF));
|
||||
tuning.load(data);
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if (voices[i].tuning == tuning)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
case 0x08: // scale/octave tuning 1-byte form
|
||||
//(Real-Time)
|
||||
case 0x09: // scale/octave tuning 2-byte form
|
||||
case 0x09: // scale/octave tuning 2-byte form
|
||||
// (Real-Time)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
SoftTuning tuning = new SoftTuning(data);
|
||||
int channelmask = (data[5] & 0xFF) * 16384
|
||||
+ (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
|
||||
SoftChannel[] channels = synth.channels;
|
||||
for (int i = 0; i < channels.length; i++)
|
||||
if ((channelmask & (1 << i)) != 0)
|
||||
channels[i].tuning = tuning;
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if ((channelmask & (1 << (voices[i].channel))) != 0)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x09: // Control Destination Settings
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Channel Pressure
|
||||
{
|
||||
int[] destinations = new int[(data.length - 7) / 2];
|
||||
int[] ranges = new int[(data.length - 7) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 6; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
SoftTuning tuning = new SoftTuning(data);
|
||||
int channelmask = (data[5] & 0xFF) * 16384
|
||||
+ (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
|
||||
SoftChannel[] channels = synth.channels;
|
||||
for (int i = 0; i < channels.length; i++)
|
||||
if ((channelmask & (1 << i)) != 0)
|
||||
channels[i].tuning = tuning;
|
||||
SoftVoice[] voices = synth.getVoices();
|
||||
for (int i = 0; i < voices.length; i++)
|
||||
if (voices[i].active)
|
||||
if ((channelmask & (1 << (voices[i].channel))) != 0)
|
||||
voices[i].updateTuning(tuning);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
softchannel.mapChannelPressureToDestination(
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
case 0x02: // Poly Pressure
|
||||
{
|
||||
int[] destinations = new int[(data.length - 7) / 2];
|
||||
int[] ranges = new int[(data.length - 7) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 6; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
case 0x09: // Control Destination Settings
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
softchannel.mapPolyPressureToDestination(
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
case 0x03: // Control Change
|
||||
{
|
||||
int[] destinations = new int[(data.length - 7) / 2];
|
||||
int[] ranges = new int[(data.length - 7) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 7; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Channel Pressure
|
||||
{
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
int[] destinations = new int[(data.length - 6) / 2];
|
||||
int[] ranges = new int[(data.length - 6) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 6; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
softchannel.mapChannelPressureToDestination(
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
case 0x02: // Poly Pressure
|
||||
{
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
int[] destinations = new int[(data.length - 6) / 2];
|
||||
int[] ranges = new int[(data.length - 6) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 6; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
softchannel.mapPolyPressureToDestination(
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
case 0x03: // Control Change
|
||||
{
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
int[] destinations = new int[(data.length - 7) / 2];
|
||||
int[] ranges = new int[(data.length - 7) / 2];
|
||||
int ix = 0;
|
||||
for (int j = 7; j < data.length - 1; j += 2) {
|
||||
destinations[ix] = data[j] & 0xFF;
|
||||
ranges[ix] = data[j + 1] & 0xFF;
|
||||
ix++;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
int control = data[6] & 0xFF;
|
||||
softchannel.mapControlToDestination(control,
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int channel = data[5] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
int control = data[6] & 0xFF;
|
||||
softchannel.mapControlToDestination(control,
|
||||
destinations, ranges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0A: // Key Based Instrument Control
|
||||
{
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Basic Message
|
||||
int channel = data[5] & 0xFF;
|
||||
int keynumber = data[6] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
for (int j = 7; j < data.length - 1; j += 2) {
|
||||
int controlnumber = data[j] & 0xFF;
|
||||
int controlvalue = data[j + 1] & 0xFF;
|
||||
softchannel.controlChangePerNote(keynumber,
|
||||
controlnumber, controlvalue);
|
||||
case 0x0A: // Key Based Instrument Control
|
||||
{
|
||||
if (data.length < 8 || (data[4] & 0xFF) != 0x01) {
|
||||
break;
|
||||
}
|
||||
subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // Basic Message
|
||||
int channel = data[5] & 0xFF;
|
||||
int keynumber = data[6] & 0xFF;
|
||||
SoftChannel softchannel = synth.channels[channel];
|
||||
for (int j = 7; j < data.length - 1; j += 2) {
|
||||
int controlnumber = data[j] & 0xFF;
|
||||
int controlvalue = data[j + 1] & 0xFF;
|
||||
softchannel.controlChangePerNote(keynumber,
|
||||
controlnumber, controlvalue);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,10 +89,21 @@ public final class SoftTuning {
|
||||
*/
|
||||
public void load(byte[] data) {
|
||||
// Universal Non-Real-Time / Real-Time SysEx
|
||||
if (data.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
|
||||
if (data.length < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
int subid1 = data[3] & 0xFF;
|
||||
switch (subid1) {
|
||||
case 0x08: // MIDI Tuning Standard
|
||||
if (data.length < 5) {
|
||||
break;
|
||||
}
|
||||
int subid2 = data[4] & 0xFF;
|
||||
switch (subid2) {
|
||||
case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
|
||||
@ -100,8 +111,11 @@ public final class SoftTuning {
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
//if (!checksumOK2(data))
|
||||
// break;
|
||||
name = new String(data, 6, 16, US_ASCII);
|
||||
int r = 22;
|
||||
if (data.length < 128 * 3 + r) {
|
||||
break;
|
||||
}
|
||||
name = new String(data, 6, 16, US_ASCII);
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int xx = data[r++] & 0xFF;
|
||||
int yy = data[r++] & 0xFF;
|
||||
@ -115,8 +129,14 @@ public final class SoftTuning {
|
||||
case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning.shtml
|
||||
if (data.length < 7) {
|
||||
break;
|
||||
}
|
||||
int ll = data[6] & 0xFF;
|
||||
int r = 7;
|
||||
if (data.length < ll * 4 + r) {
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < ll; i++) {
|
||||
int kk = data[r++] & 0xFF;
|
||||
int xx = data[r++] & 0xFF;
|
||||
@ -132,6 +152,9 @@ public final class SoftTuning {
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
if (!checksumOK(data))
|
||||
break;
|
||||
if (data.length < 407) {
|
||||
break;
|
||||
}
|
||||
name = new String(data, 7, 16, US_ASCII);
|
||||
int r = 23;
|
||||
for (int i = 0; i < 128; i++) {
|
||||
@ -149,6 +172,9 @@ public final class SoftTuning {
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
if (!checksumOK(data))
|
||||
break;
|
||||
if (data.length < 35) {
|
||||
break;
|
||||
}
|
||||
name = new String(data, 7, 16, US_ASCII);
|
||||
int[] octave_tuning = new int[12];
|
||||
for (int i = 0; i < 12; i++)
|
||||
@ -163,6 +189,9 @@ public final class SoftTuning {
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
if (!checksumOK(data))
|
||||
break;
|
||||
if (data.length < 47) {
|
||||
break;
|
||||
}
|
||||
name = new String(data, 7, 16, US_ASCII);
|
||||
double[] octave_tuning = new double[12];
|
||||
for (int i = 0; i < 12; i++) {
|
||||
@ -177,7 +206,13 @@ public final class SoftTuning {
|
||||
case 0x07: // SINGLE NOTE TUNING CHANGE (NON
|
||||
// REAL-TIME/REAL-TIME) (BANK)
|
||||
// http://www.midi.org/about-midi/tuning_extens.shtml
|
||||
if (data.length < 8) {
|
||||
break;
|
||||
}
|
||||
int ll = data[7] & 0xFF;
|
||||
if (data.length < ll * 4 + 8) {
|
||||
break;
|
||||
}
|
||||
int r = 8;
|
||||
for (int i = 0; i < ll; i++) {
|
||||
int kk = data[r++] & 0xFF;
|
||||
@ -193,6 +228,9 @@ public final class SoftTuning {
|
||||
// Real-Time/REAL-TIME)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
if (data.length < 20) {
|
||||
break;
|
||||
}
|
||||
int[] octave_tuning = new int[12];
|
||||
for (int i = 0; i < 12; i++)
|
||||
octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
|
||||
@ -204,6 +242,9 @@ public final class SoftTuning {
|
||||
// Real-Time/REAL-TIME)
|
||||
{
|
||||
// http://www.midi.org/about-midi/tuning-scale.shtml
|
||||
if (data.length < 32) {
|
||||
break;
|
||||
}
|
||||
double[] octave_tuning = new double[12];
|
||||
for (int i = 0; i < 12; i++) {
|
||||
int v = (data[i * 2 + 8] & 0xFF) * 128
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key sound
|
||||
* @bug 8282578
|
||||
* @summary AIOOBE in javax.sound.sampled.Clip
|
||||
* @run main EmptySysExMessageTest
|
||||
*/
|
||||
|
||||
public class EmptySysExMessageTest {
|
||||
public static void main(String[] args) {
|
||||
String sep = System.getProperty("file.separator");
|
||||
String dir = System.getProperty("test.src", ".");
|
||||
String name = "zerosysex.mid";
|
||||
try {
|
||||
readAudioFile(dir + sep + name);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Invalid file " + name
|
||||
+ " caused unexpected exception during read: "
|
||||
+ t + System.lineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
static void readAudioFile(String name) throws IOException {
|
||||
File soundFile = new File(name);
|
||||
Path path = Paths.get(soundFile.getAbsolutePath());
|
||||
byte[] samples = Files.readAllBytes(path);
|
||||
|
||||
try {
|
||||
AudioInputStream audioInputStream =
|
||||
AudioSystem.getAudioInputStream(new ByteArrayInputStream(samples));
|
||||
try (Clip clip = AudioSystem.getClip()) {
|
||||
clip.open(audioInputStream);
|
||||
clip.start();
|
||||
Thread.sleep(1000);
|
||||
clip.stop();
|
||||
}
|
||||
} catch (UnsupportedAudioFileException
|
||||
| LineUnavailableException
|
||||
| IOException
|
||||
| InterruptedException
|
||||
| IllegalArgumentException
|
||||
| IllegalStateException
|
||||
| SecurityException expected) {
|
||||
// Do nothing, these types of exception are expected on invalid file
|
||||
}
|
||||
}
|
||||
}
|
BIN
test/jdk/javax/sound/midi/SysexMessage/zerosysex.mid
Normal file
BIN
test/jdk/javax/sound/midi/SysexMessage/zerosysex.mid
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user