diff --git a/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java b/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java index 506eab542ac2e059391ef57dced8a2089a0bc362..1a8a36520b1224cb9e05c93420afcfa25f29c911 100644 --- a/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java +++ b/src/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java @@ -175,7 +175,6 @@ public class AudioFloatFormatConverter extends FormatConversionProvider { for (int c = 0; c < targetChannels; c++) { for (int i = 0, ix = off + c; i < len2; i++, ix += cs) { b[ix] = conversion_buffer[i]; - ; } } } else if (targetChannels == 1) { @@ -186,7 +185,6 @@ public class AudioFloatFormatConverter extends FormatConversionProvider { for (int c = 1; c < sourceChannels; c++) { for (int i = c, ix = off; i < len2; i += cs, ix++) { b[ix] += conversion_buffer[i]; - ; } } float vol = 1f / ((float) sourceChannels); @@ -390,6 +388,7 @@ public class AudioFloatFormatConverter extends FormatConversionProvider { return -1; if (len < 0) return 0; + int offlen = off + len; int remain = len / nrofchannels; int destPos = 0; int in_end = ibuffer_len; @@ -423,7 +422,7 @@ public class AudioFloatFormatConverter extends FormatConversionProvider { for (int c = 0; c < nrofchannels; c++) { int ix = 0; float[] buff = cbuffer[c]; - for (int i = c; i < b.length; i += nrofchannels) { + for (int i = c + off; i < offlen; i += nrofchannels) { b[i] = buff[ix++]; } } @@ -447,7 +446,7 @@ public class AudioFloatFormatConverter extends FormatConversionProvider { } public long skip(long len) throws IOException { - if (len > 0) + if (len < 0) return 0; if (skipbuffer == null) skipbuffer = new float[1024 * targetFormat.getFrameSize()]; diff --git a/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java b/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java index c37f48ac37c24e6854f449b5233afa81c82b9271..2c5e160a4bb595e7ff275ed6a3a0534be317c23b 100644 --- a/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java +++ b/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java @@ -42,11 +42,14 @@ public class AudioSynthesizerPropertyInfo { */ public AudioSynthesizerPropertyInfo(String name, Object value) { this.name = name; - this.value = value; if (value instanceof Class) valueClass = (Class)value; - else if (value != null) - valueClass = value.getClass(); + else + { + this.value = value; + if (value != null) + valueClass = value.getClass(); + } } /** * The name of the property. diff --git a/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java b/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java index 9ad439a6f696f7ff26d827002a474633dd587256..bc3f63ac1a17d3e411b50730b86f661cc8800d83 100644 --- a/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java +++ b/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java @@ -205,7 +205,8 @@ public class ModelByteBufferWavetable implements ModelWavetable { } if (buffer.array() == null) { return AudioFloatInputStream.getInputStream(new AudioInputStream( - buffer.getInputStream(), format, buffer.capacity())); + buffer.getInputStream(), format, + buffer.capacity() / format.getFrameSize())); } if (buffer8 != null) { if (format.getEncoding().equals(Encoding.PCM_SIGNED) diff --git a/src/share/classes/com/sun/media/sound/ModelInstrument.java b/src/share/classes/com/sun/media/sound/ModelInstrument.java index 5ecb84c0d178ef4d249b87a7c701ff4e77effbc3..89969209f71f056995e76e28f3b46c175f4a71ca 100644 --- a/src/share/classes/com/sun/media/sound/ModelInstrument.java +++ b/src/share/classes/com/sun/media/sound/ModelInstrument.java @@ -56,7 +56,7 @@ public abstract class ModelInstrument extends Instrument { public ModelDirector getDirector(ModelPerformer[] performers, MidiChannel channel, ModelDirectedPlayer player) { - return new ModelStandardDirector(performers, player); + return new ModelStandardIndexedDirector(performers, player); } public ModelPerformer[] getPerformers() { diff --git a/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java b/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java new file mode 100644 index 0000000000000000000000000000000000000000..512a7cd19c8ca6bc6c148a0584d4fd6d1e454fea --- /dev/null +++ b/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java @@ -0,0 +1,161 @@ +/* + * 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. + */ +package com.sun.media.sound; + +/** + * A standard indexed director who chooses performers + * by there keyfrom,keyto,velfrom,velto properties. + * + * @author Karl Helgason + */ +public class ModelStandardIndexedDirector implements ModelDirector { + + ModelPerformer[] performers; + ModelDirectedPlayer player; + boolean noteOnUsed = false; + boolean noteOffUsed = false; + + // Variables needed for index + byte[][] trantables; + int[] counters; + int[][] mat; + + public ModelStandardIndexedDirector(ModelPerformer[] performers, + ModelDirectedPlayer player) { + this.performers = performers; + this.player = player; + for (int i = 0; i < performers.length; i++) { + ModelPerformer p = performers[i]; + if (p.isReleaseTriggered()) { + noteOffUsed = true; + } else { + noteOnUsed = true; + } + } + buildindex(); + } + + 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]; + if (xt != -1 && yt != -1) { + return mat[xt + yt * counters[0]]; + } + } + return null; + } + + 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; + } + for (int d = 0; d < trantables.length; d++) { + byte[] trantable = trantables[d]; + int transize = trantable.length; + for (int i = transize - 1; i >= 0; i--) { + if (trantable[i] == 1) { + trantable[i] = -1; + break; + } + trantable[i] = -1; + } + int counter = -1; + for (int i = 0; i < transize; i++) { + if (trantable[i] != 0) { + counter++; + if (trantable[i] == -1) + break; + } + trantable[i] = (byte) counter; + } + counters[d] = counter; + } + 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]; + if (x_to == -1) + x_to = counters[0]; + if (y_to == -1) + y_to = counters[1]; + for (int y = y_from; y < y_to; y++) { + int i = x_from + y * counters[0]; + for (int x = x_from; x < x_to; x++) { + int[] mprev = mat[i]; + if (mprev == null) { + mat[i] = new int[] { ix }; + } else { + int[] mnew = new int[mprev.length + 1]; + mnew[mnew.length - 1] = ix; + for (int k = 0; k < mprev.length; k++) + mnew[k] = mprev[k]; + mat[i] = mnew; + } + i++; + } + } + ix++; + } + } + + public void close() { + } + + public void noteOff(int noteNumber, int velocity) { + if (!noteOffUsed) + return; + int[] plist = lookupIndex(noteNumber, velocity); + if(plist == null) return; + for (int i : plist) { + ModelPerformer p = performers[i]; + if (p.isReleaseTriggered()) { + player.play(i, null); + } + } + } + + public void noteOn(int noteNumber, int velocity) { + if (!noteOnUsed) + return; + int[] plist = lookupIndex(noteNumber, velocity); + if(plist == null) return; + for (int i : plist) { + ModelPerformer p = performers[i]; + if (!p.isReleaseTriggered()) { + player.play(i, null); + } + } + } +} diff --git a/src/share/classes/com/sun/media/sound/SoftChannel.java b/src/share/classes/com/sun/media/sound/SoftChannel.java index 1526cef99c1c4984702a4e455d20c1e9030ea573..4dcafb76bf5b2bb59fdf0b8ca60fe83d92a9591f 100644 --- a/src/share/classes/com/sun/media/sound/SoftChannel.java +++ b/src/share/classes/com/sun/media/sound/SoftChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -116,7 +116,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { protected int tuning_program = 0; protected SoftInstrument current_instrument = null; protected ModelChannelMixer current_mixer = null; - private ModelDirector current_director = null; + protected ModelDirector current_director = null; // Controller Destination Settings protected int cds_control_number = -1; @@ -1268,9 +1268,12 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { program = restrict7Bit(program); synchronized (control_mutex) { mainmixer.activity(); - this.bank = bank; - this.program = program; - current_instrument = null; + if(this.bank != bank || this.program != program) + { + this.bank = bank; + this.program = program; + current_instrument = null; + } } } diff --git a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java index 1c33dfc48a3aba432c98f1a37ddc923b070aa5ff..a868bd441a2892cf6cedac903ef5621b353fc9bd 100644 --- a/src/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/src/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -25,16 +25,25 @@ package com.sun.media.sound; +import java.io.BufferedInputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.lang.ref.WeakReference; -import java.security.AccessControlException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; import javax.sound.midi.Instrument; import javax.sound.midi.MidiChannel; @@ -182,6 +191,7 @@ public class SoftSynthesizer implements AudioSynthesizer, // 1: DLS Voice Allocation protected int voice_allocation_mode = 0; + protected boolean load_default_soundbank = false; protected boolean reverb_light = true; protected boolean reverb_on = true; protected boolean chorus_on = true; @@ -226,8 +236,6 @@ public class SoftSynthesizer implements AudioSynthesizer, = new HashMap(); private Map inslist = new HashMap(); - private Map availlist - = new HashMap(); private Map loadedlist = new HashMap(); @@ -275,10 +283,12 @@ public class SoftSynthesizer implements AudioSynthesizer, synchronized (control_mutex) { if (channels != null) for (SoftChannel c : channels) + { c.current_instrument = null; + c.current_director = null; + } for (Instrument instrument : instruments) { String pat = patchToString(instrument.getPatch()); - availlist.remove(pat); SoftInstrument softins = new SoftInstrument((ModelInstrument) instrument); inslist.put(pat, softins); @@ -341,6 +351,7 @@ public class SoftSynthesizer implements AudioSynthesizer, number_of_midi_channels = (Integer)items[10].value; jitter_correction = (Boolean)items[11].value; reverb_light = (Boolean)items[12].value; + load_default_soundbank = (Boolean)items[13].value; } private String patchToString(Patch patch) { @@ -578,7 +589,9 @@ public class SoftSynthesizer implements AudioSynthesizer, c.current_instrument = null; inslist.remove(pat); loadedlist.remove(pat); - availlist.remove(pat); + for (int i = 0; i < channels.length; i++) { + channels[i].allSoundOff(); + } } } @@ -600,7 +613,7 @@ public class SoftSynthesizer implements AudioSynthesizer, return false; synchronized (control_mutex) { - if (!loadedlist.containsValue(to) && !availlist.containsValue(to)) + if (!loadedlist.containsValue(to)) throw new IllegalArgumentException("Instrument to is not loaded."); unloadInstrument(from); ModelMappedInstrument mfrom = new ModelMappedInstrument( @@ -609,118 +622,155 @@ public class SoftSynthesizer implements AudioSynthesizer, } } - public synchronized Soundbank getDefaultSoundbank() { - if (defaultSoundBank == null) { - try { - File javahome = new File(System.getProperties().getProperty( - "java.home")); - File libaudio = new File(new File(javahome, "lib"), "audio"); - - if (libaudio.exists()) { - File foundfile = null; - File[] files = libaudio.listFiles(); - if (files != null) { - for (int i = 0; i < files.length; i++) { - File file = files[i]; - if (file.isFile()) { - String lname = file.getName().toLowerCase(); - if (lname.endsWith(".sf2") || - lname.endsWith(".dls")) { - if (foundfile == null || (file.length() > - foundfile.length())) { - foundfile = file; + public Soundbank getDefaultSoundbank() { + synchronized (SoftSynthesizer.class) { + if (defaultSoundBank != null) + return defaultSoundBank; + + List> actions = + new ArrayList>(); + + actions.add(new PrivilegedAction() { + public InputStream run() { + File javahome = new File(System.getProperties() + .getProperty("java.home")); + File libaudio = new File(new File(javahome, "lib"), "audio"); + if (libaudio.exists()) { + File foundfile = null; + File[] files = libaudio.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isFile()) { + String lname = file.getName().toLowerCase(); + if (lname.endsWith(".sf2") + || lname.endsWith(".dls")) { + if (foundfile == null + || (file.length() > foundfile + .length())) { + foundfile = file; + } } } } } + if (foundfile != null) { + try { + return new FileInputStream(foundfile); + } catch (IOException e) { + } + } } - if (foundfile != null) { - try { - Soundbank sbk = MidiSystem.getSoundbank(foundfile); - defaultSoundBank = sbk; - return defaultSoundBank; - } catch (Exception e) { - //e.printStackTrace(); + return null; + } + }); + + actions.add(new PrivilegedAction() { + public InputStream run() { + if (System.getProperties().getProperty("os.name") + .startsWith("Windows")) { + File gm_dls = new File(System.getenv("SystemRoot") + + "\\system32\\drivers\\gm.dls"); + if (gm_dls.exists()) { + try { + return new FileInputStream(gm_dls); + } catch (IOException e) { + } } } + return null; } - - if (System.getProperties().getProperty("os.name") - .startsWith("Windows")) { - File gm_dls = new File(System.getenv("SystemRoot") - + "\\system32\\drivers\\gm.dls"); - if (gm_dls.exists()) { + }); + + actions.add(new PrivilegedAction() { + public InputStream run() { + /* + * Try to load saved generated soundbank + */ + File userhome = new File(System.getProperty("user.home"), + ".gervill"); + File emg_soundbank_file = new File(userhome, + "soundbank-emg.sf2"); + if (emg_soundbank_file.exists()) { try { - Soundbank sbk = MidiSystem.getSoundbank(gm_dls); - defaultSoundBank = sbk; - return defaultSoundBank; - } catch (Exception e) { - //e.printStackTrace(); + return new FileInputStream(emg_soundbank_file); + } catch (IOException e) { } } + return null; } - } catch (AccessControlException e) { - } catch (Exception e) { - //e.printStackTrace(); - } - - File userhome = null; - File emg_soundbank_file = null; + }); - /* - * Try to load saved generated soundbank - */ - try { - userhome = new File(System.getProperty("user.home"), - ".gervill"); - emg_soundbank_file = new File(userhome, "soundbank-emg.sf2"); - Soundbank sbk = MidiSystem.getSoundbank(emg_soundbank_file); - defaultSoundBank = sbk; - return defaultSoundBank; - } catch (AccessControlException e) { - } catch (Exception e) { - //e.printStackTrace(); + for (PrivilegedAction action : actions) { + try { + InputStream is = AccessController.doPrivileged(action); + if(is == null) continue; + Soundbank sbk; + try { + sbk = MidiSystem.getSoundbank(new BufferedInputStream(is)); + } finally { + is.close(); + } + if (sbk != null) { + defaultSoundBank = sbk; + return defaultSoundBank; + } + } catch (Exception e) { + } } try { - /* - * Generate emergency soundbank + * Generate emergency soundbank */ defaultSoundBank = EmergencySoundbank.createSoundbank(); + } catch (Exception e) { + } + if (defaultSoundBank != null) { /* - * Save generated soundbank to disk for faster future use. + * Save generated soundbank to disk for faster future use. */ - if(defaultSoundBank != null) - { - if(!userhome.exists()) userhome.mkdirs(); - if(!emg_soundbank_file.exists()) - ((SF2Soundbank)defaultSoundBank).save(emg_soundbank_file); + OutputStream out = AccessController + .doPrivileged(new PrivilegedAction() { + public OutputStream run() { + try { + File userhome = new File(System + .getProperty("user.home"), + ".gervill"); + if (!userhome.exists()) + userhome.mkdirs(); + File emg_soundbank_file = new File( + userhome, "soundbank-emg.sf2"); + if (emg_soundbank_file.exists()) + return null; + return new FileOutputStream( + emg_soundbank_file); + } catch (IOException e) { + } catch (SecurityException e) { + } + return null; + } + }); + if (out != null) { + try { + ((SF2Soundbank) defaultSoundBank).save(out); + out.close(); + } catch (IOException e) { + } } - } catch (Exception e) { - //e.printStackTrace(); } - } return defaultSoundBank; } public Instrument[] getAvailableInstruments() { - if (!isOpen()) { - Soundbank defsbk = getDefaultSoundbank(); - if (defsbk == null) - return new Instrument[0]; - return defsbk.getInstruments(); - } - - synchronized (control_mutex) { - ModelInstrument[] inslist_array = - new ModelInstrument[availlist.values().size()]; - availlist.values().toArray(inslist_array); - Arrays.sort(inslist_array, new ModelInstrumentComparator()); - return inslist_array; - } + Soundbank defsbk = getDefaultSoundbank(); + if (defsbk == null) + return new Instrument[0]; + Instrument[] inslist_array = defsbk.getInstruments(); + Arrays.sort(inslist_array, new ModelInstrumentComparator()); + return inslist_array; } public Instrument[] getLoadedInstruments() { @@ -794,6 +844,31 @@ public class SoftSynthesizer implements AudioSynthesizer, return info; } + private Properties getStoredProperties() { + return AccessController + .doPrivileged(new PrivilegedAction() { + public Properties run() { + Properties p = new Properties(); + String notePath = "/com/sun/media/sound/softsynthesizer"; + try { + Preferences prefroot = Preferences.userRoot(); + if (prefroot.nodeExists(notePath)) { + Preferences prefs = prefroot.node(notePath); + String[] prefs_keys = prefs.keys(); + for (String prefs_key : prefs_keys) { + String val = prefs.get(prefs_key, null); + if (val != null) + p.setProperty(prefs_key, val); + } + } + } catch (BackingStoreException e) { + } catch (SecurityException e) { + } + return p; + } + }); + } + public AudioSynthesizerPropertyInfo[] getPropertyInfo(Map info) { List list = new ArrayList(); @@ -861,17 +936,92 @@ public class SoftSynthesizer implements AudioSynthesizer, item.description = "Turn light reverb mode on or off"; list.add(item); + item = new AudioSynthesizerPropertyInfo("load default soundbank", o?load_default_soundbank:true); + item.description = "Enabled/disable loading default soundbank"; + list.add(item); + AudioSynthesizerPropertyInfo[] items; items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]); - if (info != null) - for (AudioSynthesizerPropertyInfo item2: items) { - Object v = info.get(item2.name); + Properties storedProperties = getStoredProperties(); + + for (AudioSynthesizerPropertyInfo item2 : items) { + Object v = (info == null) ? null : info.get(item2.name); + v = (v != null) ? v : storedProperties.getProperty(item2.name); + if (v != null) { Class c = (item2.valueClass); - if (v != null) - if (c.isInstance(v)) - item2.value = v; + if (c.isInstance(v)) + item2.value = v; + else if (v instanceof String) { + String s = (String) v; + if (c == Boolean.class) { + if (s.equalsIgnoreCase("true")) + item2.value = Boolean.TRUE; + if (s.equalsIgnoreCase("false")) + item2.value = Boolean.FALSE; + } else if (c == AudioFormat.class) { + int channels = 2; + boolean signed = true; + boolean bigendian = false; + int bits = 16; + float sampleRate = 44100f; + try { + StringTokenizer st = new StringTokenizer(s, ", "); + String prevToken = ""; + while (st.hasMoreTokens()) { + String token = st.nextToken().toLowerCase(); + if (token.equals("mono")) + channels = 1; + if (token.startsWith("channel")) + channels = Integer.parseInt(prevToken); + if (token.contains("unsigned")) + signed = false; + if (token.equals("big-endian")) + bigendian = true; + if (token.equals("bit")) + bits = Integer.parseInt(prevToken); + if (token.equals("hz")) + sampleRate = Float.parseFloat(prevToken); + prevToken = token; + } + item2.value = new AudioFormat(sampleRate, bits, + channels, signed, bigendian); + } catch (NumberFormatException e) { + } + + } else + try { + if (c == Byte.class) + item2.value = Byte.valueOf(s); + else if (c == Short.class) + item2.value = Short.valueOf(s); + else if (c == Integer.class) + item2.value = Integer.valueOf(s); + else if (c == Long.class) + item2.value = Long.valueOf(s); + else if (c == Float.class) + item2.value = Float.valueOf(s); + else if (c == Double.class) + item2.value = Double.valueOf(s); + } catch (NumberFormatException e) { + } + } else if (v instanceof Number) { + Number n = (Number) v; + if (c == Byte.class) + item2.value = Byte.valueOf(n.byteValue()); + if (c == Short.class) + item2.value = Short.valueOf(n.shortValue()); + if (c == Integer.class) + item2.value = Integer.valueOf(n.intValue()); + if (c == Long.class) + item2.value = Long.valueOf(n.longValue()); + if (c == Float.class) + item2.value = Float.valueOf(n.floatValue()); + if (c == Double.class) + item2.value = Double.valueOf(n.doubleValue()); + } } + } return items; } @@ -1007,11 +1157,12 @@ public class SoftSynthesizer implements AudioSynthesizer, if (targetFormat != null) setFormat(targetFormat); - Soundbank defbank = getDefaultSoundbank(); - if (defbank != null) { - loadAllInstruments(defbank); - availlist.putAll(loadedlist); - loadedlist.clear(); + if (load_default_soundbank) + { + Soundbank defbank = getDefaultSoundbank(); + if (defbank != null) { + loadAllInstruments(defbank); + } } voices = new SoftVoice[maxpoly]; @@ -1117,7 +1268,6 @@ public class SoftSynthesizer implements AudioSynthesizer, } inslist.clear(); - availlist.clear(); loadedlist.clear(); tunings.clear(); diff --git a/src/share/classes/com/sun/media/sound/SoftVoice.java b/src/share/classes/com/sun/media/sound/SoftVoice.java index 6f891959dcae6b07e007d82f3152b905a4f024e0..8e8fd5ecee05dbd5d60add208b8258c58796ab48 100644 --- a/src/share/classes/com/sun/media/sound/SoftVoice.java +++ b/src/share/classes/com/sun/media/sound/SoftVoice.java @@ -279,9 +279,12 @@ public class SoftVoice extends VoiceStatus { } protected void updateTuning(SoftTuning newtuning) { + tuning = newtuning; tunedKey = tuning.getTuning(note) / 100.0; if (!portamento) { co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0); + if(performer == null) + return; int[] c = performer.midi_connections[4]; if (c == null) return; @@ -433,6 +436,8 @@ public class SoftVoice extends VoiceStatus { } protected void setPolyPressure(int pressure) { + if(performer == null) + return; int[] c = performer.midi_connections[2]; if (c == null) return; @@ -441,6 +446,8 @@ public class SoftVoice extends VoiceStatus { } protected void setChannelPressure(int pressure) { + if(performer == null) + return; int[] c = performer.midi_connections[1]; if (c == null) return; @@ -449,6 +456,8 @@ public class SoftVoice extends VoiceStatus { } protected void controlChange(int controller, int value) { + if(performer == null) + return; int[] c = performer.midi_ctrl_connections[controller]; if (c == null) return; @@ -457,6 +466,8 @@ public class SoftVoice extends VoiceStatus { } protected void nrpnChange(int controller, int value) { + if(performer == null) + return; int[] c = performer.midi_nrpn_connections.get(controller); if (c == null) return; @@ -465,6 +476,8 @@ public class SoftVoice extends VoiceStatus { } protected void rpnChange(int controller, int value) { + if(performer == null) + return; int[] c = performer.midi_rpn_connections.get(controller); if (c == null) return; @@ -473,6 +486,8 @@ public class SoftVoice extends VoiceStatus { } protected void setPitchBend(int bend) { + if(performer == null) + return; int[] c = performer.midi_connections[0]; if (c == null) return; @@ -499,6 +514,8 @@ public class SoftVoice extends VoiceStatus { co_noteon_on[0] = -1; + if(performer == null) + return; int[] c = performer.midi_connections[3]; if (c == null) return; @@ -527,6 +544,8 @@ public class SoftVoice extends VoiceStatus { co_noteon_on[0] = 0; + if(performer == null) + return; int[] c = performer.midi_connections[3]; if (c == null) return; @@ -543,6 +562,8 @@ public class SoftVoice extends VoiceStatus { sustain = true; co_noteon_on[0] = 1; + if(performer == null) + return; int[] c = performer.midi_connections[3]; if (c == null) return; @@ -555,6 +576,11 @@ public class SoftVoice extends VoiceStatus { active = false; stopping = false; audiostarted = false; + instrument = null; + performer = null; + connections = null; + extendedConnectionBlocks = null; + channelmixer = null; if (osc_stream != null) try { osc_stream.close(); diff --git a/test/javax/sound/midi/Gervill/AudioFloatFormatConverter/SkipTest.java b/test/javax/sound/midi/Gervill/AudioFloatFormatConverter/SkipTest.java new file mode 100644 index 0000000000000000000000000000000000000000..43fc8566d74a47f266b6daf03118f323d7755435 --- /dev/null +++ b/test/javax/sound/midi/Gervill/AudioFloatFormatConverter/SkipTest.java @@ -0,0 +1,63 @@ +/* + * 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 skip method returned from AudioFloatFormatConverter.getAudioInputStream */ + +import java.io.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +import com.sun.media.sound.AudioFloatFormatConverter; + +public class SkipTest { + + public static void main(String[] args) throws Exception { + AudioFloatFormatConverter converter = new AudioFloatFormatConverter(); + byte[] data = { 10, 20, 30, 40, 30, 20, 10 }; + AudioFormat format = new AudioFormat(8000, 8, 1, true, false); + AudioFormat format2 = new AudioFormat(16000, 8, 1, true, false); + AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream( + data), format, data.length); + AudioInputStream ais2 = converter.getAudioInputStream(format2, ais); + byte[] data2 = new byte[30]; + int ret = ais2.read(data2, 0, data2.length); + ais.reset(); + AudioInputStream ais3 = converter.getAudioInputStream(format2, ais); + byte[] data3 = new byte[100]; + ais3.skip(7); + int ret2 = ais3.read(data3, 7, data3.length); + if (ret2 != ret - 7) + throw new Exception("Skip doesn't work correctly (" + ret2 + " != " + + (ret - 7) + ")"); + for (int i = 7; i < ret2 + 7; i++) { + if (data3[i] != data2[i]) + throw new Exception("Skip doesn't work correctly (" + data3[i] + + " != " + data2[i] + ")"); + } + } + +} diff --git a/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/OpenStream.java b/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/OpenStream.java new file mode 100644 index 0000000000000000000000000000000000000000..d339c4c6140bc2d6912f9692acaa4ff130e100b6 --- /dev/null +++ b/test/javax/sound/midi/Gervill/ModelByteBufferWavetable/OpenStream.java @@ -0,0 +1,142 @@ +/* + * 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 AudioFloatInputStream.getFrameLength() returned from + ModelByteBufferWavetable openStream method */ + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; + +import javax.sound.sampled.*; + +import com.sun.media.sound.*; + +public class OpenStream { + + static float[] testarray; + + static byte[] test_byte_array; + + static byte[] test_byte_array_8ext; + + static AudioFormat format = new AudioFormat(44100, 16, 1, true, false); + + static AudioFormat format24 = new AudioFormat(44100, 24, 1, true, false); + + static ModelByteBuffer buffer; + + static ModelByteBuffer buffer_wave; + + static ModelByteBuffer buffer8; + + static ModelByteBuffer buffer16_8; + + static ModelByteBuffer buffer24; + + static File test_file; + + static ModelByteBuffer buffer_wave_ondisk; + + static void setUp() throws Exception { + testarray = new float[1024]; + for (int i = 0; i < 1024; i++) { + double ii = i / 1024.0; + ii = ii * ii; + testarray[i] = (float) Math.sin(10 * ii * 2 * Math.PI); + testarray[i] += (float) Math.sin(1.731 + 2 * ii * 2 * Math.PI); + testarray[i] += (float) Math.sin(0.231 + 6.3 * ii * 2 * Math.PI); + testarray[i] *= 0.3; + } + test_byte_array = new byte[testarray.length * 2]; + AudioFloatConverter.getConverter(format).toByteArray(testarray, + test_byte_array); + buffer = new ModelByteBuffer(test_byte_array); + + byte[] test_byte_array2 = new byte[testarray.length * 3]; + buffer24 = new ModelByteBuffer(test_byte_array2); + test_byte_array_8ext = new byte[testarray.length]; + byte[] test_byte_array_8_16 = new byte[testarray.length * 2]; + AudioFloatConverter.getConverter(format24).toByteArray(testarray, + test_byte_array2); + int ix = 0; + int x = 0; + for (int i = 0; i < test_byte_array_8ext.length; i++) { + test_byte_array_8ext[i] = test_byte_array2[ix++]; + test_byte_array_8_16[x++] = test_byte_array2[ix++]; + test_byte_array_8_16[x++] = test_byte_array2[ix++]; + } + buffer16_8 = new ModelByteBuffer(test_byte_array_8_16); + buffer8 = new ModelByteBuffer(test_byte_array_8ext); + + AudioInputStream ais = new AudioInputStream(buffer.getInputStream(), + format, testarray.length); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + AudioSystem.write(ais, AudioFileFormat.Type.WAVE, baos); + buffer_wave = new ModelByteBuffer(baos.toByteArray()); + + test_file = File.createTempFile("test", ".raw"); + FileOutputStream fos = new FileOutputStream(test_file); + fos.write(baos.toByteArray()); + fos.close(); + buffer_wave_ondisk = new ModelByteBuffer(test_file); + + } + + static void tearDown() throws Exception { + if (!test_file.delete()) + test_file.deleteOnExit(); + } + + public static void testOpenStream(ModelByteBufferWavetable wavetable) + throws Exception { + AudioFloatInputStream ais = wavetable.openStream(); + long frames = wavetable.getBuffer().capacity() + / wavetable.getFormat().getFrameSize(); + long framelength = ais.getFrameLength(); + ais.close(); + if (frames != framelength) { + throw new Exception("Incorrect framelength returned (" + frames + + " != " + framelength + ")"); + } + } + + public static void main(String[] args) throws Exception { + + setUp(); + + try { + testOpenStream(new ModelByteBufferWavetable(buffer, format)); + testOpenStream(new ModelByteBufferWavetable(buffer_wave, format)); + testOpenStream(new ModelByteBufferWavetable(buffer_wave_ondisk, + format)); + } finally { + tearDown(); + } + + } + +} diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments2.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments2.java new file mode 100644 index 0000000000000000000000000000000000000000..20e2360a74ee9c79df9fdff42e03f544f62c0a1f --- /dev/null +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments2.java @@ -0,0 +1,62 @@ +/* + * 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 SoftSynthesizer getAvailableInstruments method */ + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.sampled.*; +import javax.sound.midi.MidiDevice.Info; + +import com.sun.media.sound.*; + +public class GetAvailableInstruments2 { + + private static void assertEquals(Object a, Object b) throws Exception { + if (!a.equals(b)) + throw new RuntimeException("assertEquals fails!"); + } + + private static void assertTrue(boolean value) throws Exception { + if (!value) + throw new RuntimeException("assertTrue fails!"); + } + + public static void main(String[] args) throws Exception { + AudioSynthesizer synth = new SoftSynthesizer(); + synth.openStream(null, null); + Soundbank defsbk = synth.getDefaultSoundbank(); + if (defsbk != null) { + synth.unloadAllInstruments(defsbk); + assertTrue(defsbk.getInstruments().length == synth + .getAvailableInstruments().length); + } + synth.close(); + + } +} diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments2.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments2.java new file mode 100644 index 0000000000000000000000000000000000000000..5fa3fb21d860436f12a7e964de8842bbef101737 --- /dev/null +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments2.java @@ -0,0 +1,61 @@ +/* + * 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 SoftSynthesizer getLoadedInstruments method */ + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.sampled.*; +import javax.sound.midi.MidiDevice.Info; + +import com.sun.media.sound.*; + +public class GetLoadedInstruments2 { + + private static void assertEquals(Object a, Object b) throws Exception { + if (!a.equals(b)) + throw new RuntimeException("assertEquals fails!"); + } + + private static void assertTrue(boolean value) throws Exception { + if (!value) + throw new RuntimeException("assertTrue fails!"); + } + + public static void main(String[] args) throws Exception { + AudioSynthesizer synth = new SoftSynthesizer(); + synth.openStream(null, null); + Soundbank defsbk = synth.getDefaultSoundbank(); + if (defsbk != null) { + assertTrue(defsbk.getInstruments().length == synth + .getLoadedInstruments().length); + } + synth.close(); + + } +} diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/GetPropertyInfo.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetPropertyInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..43c5438bfdd723573cf56b627821432a631b1c2b --- /dev/null +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/GetPropertyInfo.java @@ -0,0 +1,103 @@ +/* + * 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 SoftSynthesizer getPropertyInfo method */ + +import java.util.HashMap; +import java.util.Map; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.sampled.*; +import javax.sound.sampled.AudioFormat.Encoding; +import javax.sound.midi.MidiDevice.Info; + +import com.sun.media.sound.*; + +public class GetPropertyInfo { + + private static void assertTrue(boolean value) throws Exception { + if (!value) + throw new RuntimeException("assertTrue fails!"); + } + + public static void main(String[] args) throws Exception { + SoftSynthesizer synth = new SoftSynthesizer(); + Map p = new HashMap(); + p.put("format", "8000 HZ 24 BIT MONO UNSIGNED BIG-ENDIAN"); + p.put("control rate", 125); + p.put("reverb", false); + p.put("auto gain control", "false"); + AudioSynthesizerPropertyInfo[] ap = synth.getPropertyInfo(p); + for (int i = 0; i < ap.length; i++) { + if (ap[i].name.equals("control rate")) + assertTrue(Math.abs((Float) ap[i].value - 125.0) < 0.001); + if (ap[i].name.equals("reverb")) + assertTrue((Boolean) ap[i].value == false); + if (ap[i].name.equals("auto gain control")) + assertTrue((Boolean) ap[i].value == false); + if (ap[i].name.equals("format")) { + AudioFormat format = (AudioFormat) ap[i].value; + assertTrue(format.getChannels() == 1); + assertTrue(format.getSampleSizeInBits() == 24); + assertTrue(format.isBigEndian()); + assertTrue(Math.abs(format.getSampleRate() - 8000) < 0.001); + assertTrue(format.getEncoding() == Encoding.PCM_UNSIGNED); + } + } + p = new HashMap(); + p.put("format", "9000 Hz, 8 bit, 4 channels"); + ap = synth.getPropertyInfo(p); + for (int i = 0; i < ap.length; i++) { + if (ap[i].name.equals("format")) { + AudioFormat format = (AudioFormat) ap[i].value; + assertTrue(format.getChannels() == 4); + assertTrue(format.getSampleSizeInBits() == 8); + assertTrue(!format.isBigEndian()); + assertTrue(Math.abs(format.getSampleRate() - 9000) < 0.001); + assertTrue(format.getEncoding() == Encoding.PCM_SIGNED); + } + } + + p = new HashMap(); + p.put("format", "PCM_UNSIGNED 44100.0 Hz, 16 bit, 3 channels, 6 bytes/frame, big-endian"); + ap = synth.getPropertyInfo(p); + for (int i = 0; i < ap.length; i++) { + if (ap[i].name.equals("format")) { + AudioFormat format = (AudioFormat) ap[i].value; + assertTrue(format.getChannels() == 3); + assertTrue(format.getSampleSizeInBits() == 16); + assertTrue(format.isBigEndian()); + assertTrue(Math.abs(format.getSampleRate() - 44100) < 0.001); + assertTrue(format.getEncoding() == Encoding.PCM_UNSIGNED); + } + } + + + } +} diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java index 67c448de863e42e59422315b81e0b204c6c12f75..5dc16828695f496ba9e6dc2f54b93e691c61c86d 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadAllInstruments.java @@ -55,7 +55,6 @@ public class LoadAllInstruments { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); SimpleSoundbank sbk = new SimpleSoundbank(); SimpleInstrument ins = new SimpleInstrument(); diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java index 75f1cd5dc1735bdea1fe14954e220ca80029f423..97d69a34855d986552e9932b504ba57c382763bb 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstrument.java @@ -55,7 +55,6 @@ public class LoadInstrument { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); SimpleSoundbank sbk = new SimpleSoundbank(); SimpleInstrument ins = new SimpleInstrument(); diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java index 4c438d046a620ccaf64affa24c8126f579f2dcb8..263ef470f5dc7fbec561cb9d4b0d5eac653ab2e2 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/LoadInstruments.java @@ -55,7 +55,6 @@ public class LoadInstruments { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); SimpleSoundbank sbk = new SimpleSoundbank(); SimpleInstrument ins = new SimpleInstrument(); diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java index 8c72a04d23e7ea5d2594fa939886798ba8d519ed..f7fa9e59a71482a7c9b9222147de400b86be4ba5 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/RemapInstrument.java @@ -56,15 +56,15 @@ public class RemapInstrument { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - Instrument ins0 = defsbk.getInstrument(new Patch(0,0)); + Instrument ins3 = defsbk.getInstrument(new Patch(0,3)); Instrument ins10 = defsbk.getInstrument(new Patch(0,10)); - assertTrue(synth.remapInstrument(ins0, ins10)); + assertTrue(synth.remapInstrument(ins3, ins10)); Instrument[] loaded = synth.getLoadedInstruments(); for (int i = 0; i < loaded.length; i++) { - if(loaded[i].getPatch().getBank() == 0) - if(loaded[i].getPatch().getProgram() == 10) + if(loaded[i].getPatch().getBank() == ins3.getPatch().getBank()) + if(loaded[i].getPatch().getProgram() == ins3.getPatch().getProgram()) { - assertEquals(loaded[i].getName(), ins0.getName()); + assertEquals(loaded[i].getName(), ins10.getName()); break; } } diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/TestDisableLoadDefaultSoundbank.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/TestDisableLoadDefaultSoundbank.java new file mode 100644 index 0000000000000000000000000000000000000000..06c39995398e03868332056afe2c965371ec4505 --- /dev/null +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/TestDisableLoadDefaultSoundbank.java @@ -0,0 +1,71 @@ +/* + * 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 Disable/enable loading default soundbank in SoftSynthesizer */ + +import java.util.HashMap; +import java.util.Map; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Patch; +import javax.sound.midi.Soundbank; +import javax.sound.sampled.*; +import javax.sound.midi.MidiDevice.Info; + +import com.sun.media.sound.*; + +public class TestDisableLoadDefaultSoundbank { + + private static void assertEquals(Object a, Object b) throws Exception { + if (!a.equals(b)) + throw new RuntimeException("assertEquals fails!"); + } + + private static void assertTrue(boolean value) throws Exception { + if (!value) + throw new RuntimeException("assertTrue fails!"); + } + + public static void main(String[] args) throws Exception { + AudioSynthesizer synth = new SoftSynthesizer(); + synth.openStream(null, null); + Soundbank defsbk = synth.getDefaultSoundbank(); + if (defsbk != null) { + assertTrue(defsbk.getInstruments().length == synth + .getLoadedInstruments().length); + } + synth.close(); + Map p = new HashMap(); + p.put("load default soundbank", false); + synth.openStream(null, p); + if (defsbk != null) { + assertTrue(synth.getLoadedInstruments().length == 0); + } + synth.close(); + + } +} diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java index f96b67eac80d226bbf8f66e5ca1aec6c8cb5d728..6070db1200176e639427217aa20af7bdbb060d19 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadAllInstruments.java @@ -55,9 +55,8 @@ public class UnloadAllInstruments { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); - assertTrue(synth.getAvailableInstruments().length == 0); + assertTrue(synth.getLoadedInstruments().length == 0); synth.loadAllInstruments(defsbk); assertTrue(synth.getLoadedInstruments().length != 0); synth.unloadAllInstruments(defsbk); diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java index 2e78a0861cc0cda4b8ae897218e9de26adbbf4f3..13753af120a6a14b658376e61a8c26d30308e514 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstrument.java @@ -55,7 +55,6 @@ public class UnloadInstrument { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); SimpleSoundbank sbk = new SimpleSoundbank(); SimpleInstrument ins = new SimpleInstrument(); diff --git a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java index 603691d80dbdddd1ce1a486dcbbeaeef3941deb8..bfa791ef402b9bd2e49df1cf4e3f0c8943121a95 100644 --- a/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java +++ b/test/javax/sound/midi/Gervill/SoftSynthesizer/UnloadInstruments.java @@ -55,7 +55,6 @@ public class UnloadInstruments { Soundbank defsbk = synth.getDefaultSoundbank(); if(defsbk != null) { - assertTrue(synth.getLoadedInstruments().length == 0); synth.unloadAllInstruments(defsbk); SimpleSoundbank sbk = new SimpleSoundbank(); SimpleInstrument ins = new SimpleInstrument(); diff --git a/test/javax/sound/midi/Gervill/SoftTuning/RealTimeTuning.java b/test/javax/sound/midi/Gervill/SoftTuning/RealTimeTuning.java new file mode 100644 index 0000000000000000000000000000000000000000..7b6aaf66d82fa2781cbd38dcd5f48d3588574f61 --- /dev/null +++ b/test/javax/sound/midi/Gervill/SoftTuning/RealTimeTuning.java @@ -0,0 +1,250 @@ +/* + * 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 RealTime-tunings using SoftReciver.send method */ + +import java.io.IOException; + +import javax.sound.midi.*; +import javax.sound.sampled.*; + +import com.sun.media.sound.*; + +public class RealTimeTuning { + + private static class PitchSpy { + public float pitch = 0; + + public Soundbank getSoundBank() { + ModelOscillator osc = new ModelOscillator() { + public float getAttenuation() { + return 0; + } + + public int getChannels() { + return 0; + } + + public ModelOscillatorStream open(float samplerate) { + return new ModelOscillatorStream() { + public void close() throws IOException { + pitch = 0; + } + + public void noteOff(int velocity) { + pitch = 0; + } + + public void noteOn(MidiChannel channel, + VoiceStatus voice, int noteNumber, int velocity) { + pitch = noteNumber * 100; + } + + public int read(float[][] buffer, int offset, int len) + throws IOException { + return len; + } + + public void setPitch(float ipitch) { + pitch = ipitch; + } + }; + } + }; + ModelPerformer performer = new ModelPerformer(); + performer.getOscillators().add(osc); + SimpleInstrument testinstrument = new SimpleInstrument(); + testinstrument.setPatch(new Patch(0, 0)); + testinstrument.add(performer); + SimpleSoundbank testsoundbank = new SimpleSoundbank(); + testsoundbank.addInstrument(testinstrument); + return testsoundbank; + } + } + + public static void sendTuningChange(Receiver recv, int channel, + int tuningpreset, int tuningbank) throws InvalidMidiDataException { + // Data Entry + ShortMessage sm1 = new ShortMessage(); + sm1.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x64, 04); + ShortMessage sm2 = new ShortMessage(); + sm2.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x65, 00); + + // Tuning Bank + ShortMessage sm3 = new ShortMessage(); + sm3.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x06, tuningbank); + // Data Increment + ShortMessage sm4 = new ShortMessage(); + sm4.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x60, 0x7F); + // Data Decrement + ShortMessage sm5 = new ShortMessage(); + sm5.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x61, 0x7F); + + // Data Entry + ShortMessage sm6 = new ShortMessage(); + sm6.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x64, 03); + ShortMessage sm7 = new ShortMessage(); + sm7.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x65, 00); + + // Tuning program + ShortMessage sm8 = new ShortMessage(); + sm8 + .setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x06, + tuningpreset); + // Data Increment + ShortMessage sm9 = new ShortMessage(); + sm9.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x60, 0x7F); + // Data Decrement + ShortMessage sm10 = new ShortMessage(); + sm10.setMessage(ShortMessage.CONTROL_CHANGE, channel, 0x61, 0x7F); + + recv.send(sm1, -1); + recv.send(sm2, -1); + recv.send(sm3, -1); + recv.send(sm4, -1); + recv.send(sm5, -1); + recv.send(sm6, -1); + recv.send(sm7, -1); + recv.send(sm8, -1); + recv.send(sm9, -1); + recv.send(sm10, -1); + + } + + private static void assertTrue(boolean value) throws Exception { + if (!value) + throw new RuntimeException("assertTrue fails!"); + } + + public static void testTunings(int[] msg, int tuningProgram, + int tuningBank, int targetNote, float targetPitch, boolean realtime) + throws Exception { + AudioSynthesizer synth = new SoftSynthesizer(); + AudioInputStream stream = synth.openStream(null, null); + Receiver recv = synth.getReceiver(); + MidiChannel channel = synth.getChannels()[0]; + byte[] buff = new byte[2048]; + + // Create test instrument which we can use to monitor pitch changes + PitchSpy pitchspy = new PitchSpy(); + + synth.unloadAllInstruments(synth.getDefaultSoundbank()); + synth.loadAllInstruments(pitchspy.getSoundBank()); + + SysexMessage sysex = null; + + // Send tuning changes + if (msg != null) { + byte[] bmsg = new byte[msg.length]; + for (int i = 0; i < bmsg.length; i++) + bmsg[i] = (byte) msg[i]; + sysex = new SysexMessage(); + sysex.setMessage(bmsg, bmsg.length); + if (targetPitch == 0) { + targetPitch = (float) new SoftTuning(bmsg) + .getTuning(targetNote); + // Check if targetPitch != targetNote * 100 + assertTrue(Math.abs(targetPitch - targetNote * 100.0) > 0.001); + } + } + + if (tuningProgram != -1) + sendTuningChange(recv, 0, tuningProgram, tuningBank); + + // First test without tunings + channel.noteOn(targetNote, 64); + stream.read(buff, 0, buff.length); + assertTrue(Math.abs(pitchspy.pitch - (targetNote * 100.0)) < 0.001); + + // Test if realtime/non-realtime works + if (sysex != null) + recv.send(sysex, -1); + stream.read(buff, 0, buff.length); + if (realtime) + assertTrue(Math.abs(pitchspy.pitch - targetPitch) < 0.001); + else + assertTrue(Math.abs(pitchspy.pitch - (targetNote * 100.0)) < 0.001); + + // Test if tunings works + channel.noteOn(targetNote, 0); + stream.read(buff, 0, buff.length); + assertTrue(Math.abs(pitchspy.pitch - 0.0) < 0.001); + + channel.noteOn(targetNote, 64); + stream.read(buff, 0, buff.length); + assertTrue(Math.abs(pitchspy.pitch - targetPitch) < 0.001); + + channel.noteOn(targetNote, 0); + stream.read(buff, 0, buff.length); + assertTrue(Math.abs(pitchspy.pitch - 0.0) < 0.001); + + stream.close(); + } + + public static void main(String[] args) throws Exception { + // Test with no-tunings + testTunings(null, -1, -1, 60, 6000, false); + + int[] msg; + // 0x02 SINGLE NOTE TUNING CHANGE (REAL-TIME) + msg = new int[] { 0xf0, 0x7f, 0x7f, 0x08, 0x02, 0x10, 0x02, 36, 36, 64, + 0, 60, 70, 0, 0, 0xf7 }; + testTunings(msg, 0x10, 0, 60, 7000, true); + + // 0x07 SINGLE NOTE TUNING CHANGE (NON REAL-TIME) (BANK) + msg = new int[] { 0xf0, 0x7e, 0x7f, 0x08, 0x07, 0x05, 0x07, 0x02, 36, + 36, 64, 0, 60, 80, 0, 0, 0xf7 }; + testTunings(msg, 0x07, 0x05, 60, 8000, false); + + // 0x07 SINGLE NOTE TUNING CHANGE (REAL-TIME) (BANK) + msg = new int[] { 0xf0, 0x7f, 0x7f, 0x08, 0x07, 0x05, 0x07, 0x02, 36, + 36, 64, 0, 60, 80, 0, 0, 0xf7 }; + testTunings(msg, 0x07, 0x05, 60, 8000, true); + + // 0x08 scale/octave tuning 1-byte form (Non Real-Time) + msg = new int[] { 0xf0, 0x7e, 0x7f, 0x08, 0x08, 0x03, 0x7f, 0x7f, 5, + 10, 15, 20, 25, 30, 35, 40, 45, 50, 51, 52, 0xf7 }; + testTunings(msg, -1, -1, 60, 0, false); + + // 0x08 scale/octave tuning 1-byte form (REAL-TIME) + msg = new int[] { 0xf0, 0x7f, 0x7f, 0x08, 0x08, 0x03, 0x7f, 0x7f, 5, + 10, 15, 20, 25, 30, 35, 40, 45, 50, 51, 52, 0xf7 }; + testTunings(msg, -1, -1, 60, 0, true); + + // 0x09 scale/octave tuning 2-byte form (Non Real-Time) + msg = new int[] { 0xf0, 0x7e, 0x7f, 0x08, 0x09, 0x03, 0x7f, 0x7f, 5, + 10, 15, 20, 25, 30, 35, 40, 45, 50, 51, 52, 5, 10, 15, 20, 25, + 30, 35, 40, 45, 50, 51, 52, 0xf7 }; + testTunings(msg, -1, -1, 60, 0, false); + + // 0x09 scale/octave tuning 2-byte form (REAL-TIME) + msg = new int[] { 0xf0, 0x7f, 0x7f, 0x08, 0x09, 0x03, 0x7f, 0x7f, 5, + 10, 15, 20, 25, 30, 35, 40, 45, 50, 51, 52, 5, 10, 15, 20, 25, + 30, 35, 40, 45, 50, 51, 52, 0xf7 }; + testTunings(msg, -1, -1, 60, 0, true); + + } +}