提交 8e6232b7 编写于 作者: K kalli

6943053: Gervill: failures on invalid ranges and 14-bit banks

Summary: ModelStandardIndexedDirector fails on invalid ranges. Program changes with 14-bit banks where handled incorectly as 7-bit banks.
Reviewed-by: amenkov
上级 7c2f1d9e
......@@ -57,8 +57,7 @@ public class ModelStandardIndexedDirector implements ModelDirector {
buildindex();
}
private int[] lookupIndex(int x, int y)
{
private int[] lookupIndex(int x, int y) {
if ((x >= 0) && (x < 128) && (y >= 0) && (y < 128)) {
int xt = trantables[0][x];
int yt = trantables[1][y];
......@@ -69,14 +68,30 @@ public class ModelStandardIndexedDirector implements ModelDirector {
return null;
}
private int restrict(int value) {
if(value < 0) return 0;
if(value > 127) return 127;
return value;
}
private void buildindex() {
trantables = new byte[2][129];
counters = new int[trantables.length];
for (ModelPerformer performer : performers) {
trantables[0][performer.getKeyFrom()] = 1;
trantables[0][performer.getKeyTo() + 1] = 1;
trantables[1][performer.getVelFrom()] = 1;
trantables[1][performer.getVelTo() + 1] = 1;
int keyFrom = performer.getKeyFrom();
int keyTo = performer.getKeyTo();
int velFrom = performer.getVelFrom();
int velTo = performer.getVelTo();
if (keyFrom > keyTo) continue;
if (velFrom > velTo) continue;
keyFrom = restrict(keyFrom);
keyTo = restrict(keyTo);
velFrom = restrict(velFrom);
velTo = restrict(velTo);
trantables[0][keyFrom] = 1;
trantables[0][keyTo + 1] = 1;
trantables[1][velFrom] = 1;
trantables[1][velTo + 1] = 1;
}
for (int d = 0; d < trantables.length; d++) {
byte[] trantable = trantables[d];
......@@ -102,10 +117,20 @@ public class ModelStandardIndexedDirector implements ModelDirector {
mat = new int[counters[0] * counters[1]][];
int ix = 0;
for (ModelPerformer performer : performers) {
int x_from = trantables[0][performer.getKeyFrom()];
int x_to = trantables[0][performer.getKeyTo() + 1];
int y_from = trantables[1][performer.getVelFrom()];
int y_to = trantables[1][performer.getVelTo() + 1];
int keyFrom = performer.getKeyFrom();
int keyTo = performer.getKeyTo();
int velFrom = performer.getVelFrom();
int velTo = performer.getVelTo();
if (keyFrom > keyTo) continue;
if (velFrom > velTo) continue;
keyFrom = restrict(keyFrom);
keyTo = restrict(keyTo);
velFrom = restrict(velFrom);
velTo = restrict(velTo);
int x_from = trantables[0][keyFrom];
int x_to = trantables[0][keyTo + 1];
int y_from = trantables[1][velFrom];
int y_to = trantables[1][velTo + 1];
if (x_to == -1)
x_to = counters[0];
if (y_to == -1)
......
......@@ -1264,7 +1264,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
}
public void programChange(int bank, int program) {
bank = restrict7Bit(bank);
bank = restrict14Bit(bank);
program = restrict7Bit(program);
synchronized (control_mutex) {
mainmixer.activity();
......
/*
* Copyright (c) 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
/* @test
@summary Test ModelStandardIndexedDirector class */
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import com.sun.media.sound.ModelConnectionBlock;
import com.sun.media.sound.ModelDirectedPlayer;
import com.sun.media.sound.ModelPerformer;
import com.sun.media.sound.ModelStandardDirector;
import com.sun.media.sound.ModelStandardIndexedDirector;
public class ModelStandardIndexedDirectorTest {
private static String treeToString(TreeSet<Integer> set)
{
StringBuffer buff = new StringBuffer();
boolean first = true;
for(Integer s : set)
{
if(!first)
buff.append(";");
buff.append(s);
first = false;
}
return buff.toString();
}
private static void testDirector(ModelPerformer[] performers) throws Exception
{
final TreeSet<Integer> played = new TreeSet<Integer>();
ModelDirectedPlayer player = new ModelDirectedPlayer()
{
public void play(int performerIndex,
ModelConnectionBlock[] connectionBlocks) {
played.add(performerIndex);
}
};
ModelStandardIndexedDirector idirector =
new ModelStandardIndexedDirector(performers, player);
ModelStandardDirector director =
new ModelStandardDirector(performers, player);
for (int n = 0; n < 128; n++)
{
for (int v = 0; v < 128; v++)
{
director.noteOn(n, v);
String p1 = treeToString(played);
played.clear();
idirector.noteOn(n, v);
String p2 = treeToString(played);
played.clear();
if(!p1.equals(p2))
throw new Exception(
"Note = " + n + ", Vel = " + v + " failed");
}
}
}
private static void testDirectorCombinations(
ModelPerformer[] performers) throws Exception
{
for (int i = 0; i < performers.length; i++) {
ModelPerformer[] performers2 = new ModelPerformer[i];
for (int j = 0; j < performers2.length; j++) {
performers2[j] = performers[i];
}
testDirector(performers2);
}
}
private static void addPerformer(
List<ModelPerformer> performers,
int keyfrom,
int keyto,
int velfrom,
int velto)
{
ModelPerformer performer = new ModelPerformer();
performer.setKeyFrom(keyfrom);
performer.setKeyTo(keyto);
performer.setVelFrom(velfrom);
performer.setVelTo(velto);
performers.add(performer);
}
public static void main(String[] args) throws Exception
{
// Test collection of normal values
List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
addPerformer(performers, 0, 0, 0, 127);
addPerformer(performers, 0, 50, 0, 127);
addPerformer(performers, 0, 127, 0, 127);
addPerformer(performers, 21, 21, 0, 127);
addPerformer(performers, 21, 60, 0, 127);
addPerformer(performers, 21, 127, 0, 127);
addPerformer(performers, 50, 50, 0, 127);
addPerformer(performers, 50, 60, 0, 127);
addPerformer(performers, 50, 127, 0, 127);
addPerformer(performers, 73, 73, 0, 127);
addPerformer(performers, 73, 80, 0, 127);
addPerformer(performers, 73, 127, 0, 127);
addPerformer(performers, 127, 127, 0, 127);
addPerformer(performers, 0, 0, 60, 127);
addPerformer(performers, 0, 50, 60, 127);
addPerformer(performers, 0, 127, 60, 127);
addPerformer(performers, 21, 21, 60, 127);
addPerformer(performers, 21, 60, 60, 127);
addPerformer(performers, 21, 127, 60, 127);
addPerformer(performers, 50, 50, 60, 127);
addPerformer(performers, 50, 60, 60, 127);
addPerformer(performers, 50, 127, 60, 127);
addPerformer(performers, 73, 73, 60, 127);
addPerformer(performers, 73, 80, 60, 127);
addPerformer(performers, 73, 127, 60, 127);
addPerformer(performers, 127, 127, 60, 127);
addPerformer(performers, 0, 0, 80, 83);
addPerformer(performers, 0, 50, 80, 83);
addPerformer(performers, 0, 127, 80, 83);
addPerformer(performers, 21, 21, 80, 83);
addPerformer(performers, 21, 60, 80, 83);
addPerformer(performers, 21, 127, 80, 83);
addPerformer(performers, 50, 50, 80, 83);
addPerformer(performers, 50, 60, 80, 83);
addPerformer(performers, 50, 127, 80, 83);
addPerformer(performers, 73, 73, 80, 83);
addPerformer(performers, 73, 80, 80, 83);
addPerformer(performers, 73, 127, 80, 83);
addPerformer(performers, 127, 127, 80, 83);
testDirectorCombinations(
performers.toArray(
new ModelPerformer[performers.size()])
);
// Test reversed values
performers.clear();
addPerformer(performers, 50, 30, 80, 83);
addPerformer(performers, 30, 30, 50, 30);
addPerformer(performers, 37, 30, 50, 30);
testDirector(
performers.toArray(
new ModelPerformer[performers.size()])
);
// Test out-of-range values
performers.clear();
addPerformer(performers, -20, 6, 0, 127);
addPerformer(performers, 0, 300, 0, 300);
addPerformer(performers, -2, -8, -5, -9);
testDirector(
performers.toArray(
new ModelPerformer[performers.size()])
);
}
}
/*
* Copyright (c) 2010, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
/* @test
@summary Test SoftChannel program and bank change */
import java.io.IOException;
import javax.sound.midi.*;
import javax.sound.sampled.*;
import com.sun.media.sound.*;
public class ProgramAndBankChange {
private static SimpleInstrument generateTestInstrument(Patch patch) {
ModelOscillator osc = new ModelOscillator() {
public float getAttenuation() {
return 0;
}
public int getChannels() {
return 1;
}
public ModelOscillatorStream open(float samplerate) {
return new ModelOscillatorStream() {
public void close() throws IOException {
}
public void noteOff(int velocity) {
}
public void noteOn(MidiChannel channel, VoiceStatus voice,
int noteNumber, int velocity) {
}
public int read(float[][] buffer, int offset, int len)
throws IOException {
return len;
}
public void setPitch(float ipitch) {
}
};
}
};
ModelPerformer performer = new ModelPerformer();
performer.getOscillators().add(osc);
SimpleInstrument testinstrument = new SimpleInstrument();
testinstrument.setPatch(patch);
testinstrument.add(performer);
return testinstrument;
}
private static void assertTrue(boolean value) throws Exception {
if (!value)
throw new RuntimeException("assertTrue fails!");
}
private static void testProgramAndBank(SoftSynthesizer soft,
AudioInputStream stream, Patch patch) throws Exception {
int program = patch.getProgram();
int bank = patch.getBank();
MidiChannel channel = soft.getChannels()[0];
byte[] buff = new byte[2048];
channel.programChange(bank, program);
channel.noteOn(64, 64);
stream.read(buff, 0, buff.length);
int foundprogram = -1;
int foundbank = -1;
VoiceStatus[] vstatus = soft.getVoiceStatus();
for (int i = 0; i < vstatus.length; i++) {
if (vstatus[i].active) {
foundprogram = vstatus[i].program;
foundbank = vstatus[i].bank;
break;
}
}
assertTrue(foundprogram == program);
assertTrue(foundbank == bank);
channel.noteOn(64, 0);
stream.read(buff, 0, buff.length);
channel = soft.getChannels()[1];
// Send MSB Bank
channel.controlChange(0x00, bank / 128);
// Send LSB Bank
channel.controlChange(0x20, bank % 128);
// Send Program Change
channel.programChange(program);
channel.noteOn(64, 64);
stream.read(buff, 0, buff.length);
foundprogram = -1;
foundbank = -1;
vstatus = soft.getVoiceStatus();
for (int i = 0; i < vstatus.length; i++) {
if (vstatus[i].active) {
foundprogram = vstatus[i].program;
foundbank = vstatus[i].bank;
break;
}
}
assertTrue(foundprogram == program);
assertTrue(foundbank == bank);
channel.noteOn(64, 0);
stream.read(buff, 0, buff.length);
}
public static void main(String[] args) throws Exception {
SoftSynthesizer soft = new SoftSynthesizer();
AudioInputStream stream = soft.openStream(null, null);
soft.unloadAllInstruments(soft.getDefaultSoundbank());
soft.loadInstrument(generateTestInstrument(new Patch(0, 0)));
soft.loadInstrument(generateTestInstrument(new Patch(7, 0)));
soft.loadInstrument(generateTestInstrument(new Patch(20, 10)));
soft.loadInstrument(generateTestInstrument(new Patch(3678, 15)));
soft.loadInstrument(generateTestInstrument(new Patch(4678, 15)));
testProgramAndBank(soft, stream, new Patch(0, 0));
testProgramAndBank(soft, stream, new Patch(7, 0));
testProgramAndBank(soft, stream, new Patch(20, 10));
testProgramAndBank(soft, stream, new Patch(3678, 15));
testProgramAndBank(soft, stream, new Patch(4678, 15));
soft.close();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册