1 /*
   2  * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import javax.sound.midi.Instrument;
  25 import javax.sound.midi.MidiSystem;
  26 import javax.sound.midi.MidiUnavailableException;
  27 import javax.sound.midi.Soundbank;
  28 import javax.sound.midi.Synthesizer;
  29 
  30 /**
  31  * @test
  32  * @bug 4685396
  33  * @summary Tests that Synthesizer.remapInstrument works
  34  * @run main bug4685396
  35  */
  36 public class bug4685396 {
  37 
  38     static Synthesizer synth = null;
  39 
  40     public static boolean isInstrumentExist(Instrument inst, Instrument[] insts) {
  41         for (int i = 0; i < insts.length; i++) {
  42             if (inst.equals(insts[i]))
  43                 return true;
  44         }
  45         return false;
  46     }
  47 
  48     static boolean test(
  49             boolean reloadInstr,    // reload all instruments?
  50             boolean unloadFrom,     // unload "from" instrument?
  51             boolean unloadTo        // unload "to" instrument?
  52             ) throws MidiUnavailableException {
  53         log("Starting test: reloadInstr=" + reloadInstr
  54                 + ", unloadFrom=" + unloadFrom
  55                 + ", unloadTo=" + unloadTo
  56                 + "");
  57 
  58         log("  creating synthesizer...");
  59         synth = MidiSystem.getSynthesizer();
  60         log("  opening synthesizer...");
  61         synth.open();
  62 
  63         Soundbank sbank = synth.getDefaultSoundbank();
  64         if (sbank == null)
  65             throw new RuntimeException("ERROR: Could not get default soundbank");
  66 
  67         if (reloadInstr) {
  68             synth.unloadAllInstruments(sbank);
  69             synth.loadAllInstruments(sbank);
  70         }
  71 
  72         Instrument[] instrs = synth.getLoadedInstruments();
  73 
  74         log("  " + instrs.length + " instruments loaded.");
  75 
  76         if (instrs.length < 2)
  77             throw new RuntimeException("ERROR: need at least 2 loaded instruments");
  78 
  79         Instrument from = instrs[0];
  80         Instrument to = instrs[instrs.length - 1];
  81 
  82         if (unloadFrom)
  83             synth.unloadInstrument(from);
  84         if (unloadTo)
  85             synth.unloadInstrument(to);
  86 
  87         log("  from instrument (" + (unloadFrom ? "UNLOADED" : "LOADED")
  88                                 + "): " + from.toString());
  89         log("  to instrument (" + (unloadTo ? "UNLOADED" : "LOADED")
  90                                 + "): " + to.toString());
  91 
  92         boolean result = false;
  93         boolean excepted = false;
  94         try {
  95             result = synth.remapInstrument(from, to);
  96             log("  remapInstrument(from, to) returns " + result);
  97         } catch (IllegalArgumentException ex) {
  98             excepted = true;
  99             log("  EXCEPTION:");
 100             ex.printStackTrace(System.out);
 101         }
 102 
 103         instrs = synth.getLoadedInstruments();
 104         log("  " + instrs.length + " instruments remains loaded.");
 105 
 106         boolean toUnloaded = !isInstrumentExist(to, instrs);
 107         boolean fromUnloaded = !isInstrumentExist(from, instrs);
 108 
 109         log("  from instrument is " + (fromUnloaded ? "UNLOADED" : "LOADED"));
 110         log("  to instrument is " + (toUnloaded ? "UNLOADED" : "LOADED"));
 111 
 112         boolean bOK = true;
 113         if (result) {
 114             if (unloadTo) {
 115                 bOK = false;
 116                 log("ERROR: unloaded to, but sucessfull remap");
 117             }
 118             if (!fromUnloaded) {
 119                 bOK = false;
 120                 log("ERROR: sucessfull remap, but from hasn't been unloaded");
 121             }
 122             if (toUnloaded) {
 123                 bOK = false;
 124                 log("ERROR: to has been unloaded!");
 125             }
 126         } else {
 127             if (!excepted) {
 128                 bOK = false;
 129                 log("ERROR: remap returns false, exception hasn't been thrown");
 130             }
 131             if (!unloadTo) {
 132                 bOK = false;
 133                 log("ERROR: to is loaded, but remap returns false");
 134             }
 135             if (unloadFrom != fromUnloaded) {
 136                 bOK = false;
 137                 log("ERROR: remap returns false, but status of from has been changed");
 138             }
 139         }
 140 
 141         if (bOK) {
 142             log("Test result: OK\n");
 143         } else {
 144             log("Test result: FAIL\n");
 145         }
 146 
 147         return bOK;
 148     }
 149 
 150     static void cleanup() {
 151         if (synth != null) {
 152             synth.close();
 153             synth = null;
 154         }
 155     }
 156 
 157     static boolean runTest(
 158             boolean reloadInstr,    // reload all instruments?
 159             boolean unloadTo,       // unload "to" instrument?
 160             boolean unloadFrom      // unload "from" instrument?
 161             )
 162     {
 163         boolean success = false;
 164         try {
 165             success = test(reloadInstr, unloadFrom, unloadTo);
 166         } catch (final MidiUnavailableException ignored) {
 167             // the test is not applicable
 168             success = true;
 169         } catch (Exception ex) {
 170             log("Exception: " + ex.toString());
 171         }
 172         cleanup();
 173         return success;
 174     }
 175 
 176     public static void main(String args[]) {
 177         boolean failed = false;
 178         if (!runTest(true, false, false))
 179             failed = true;
 180         if (!runTest(true, false, true))
 181             failed = true;
 182         if (!runTest(true, true, false))
 183             failed = true;
 184         if (!runTest(true, true, true))
 185             failed = true;
 186 
 187         if (failed) {
 188             throw new RuntimeException("Test FAILED.");
 189         }
 190         log("Test sucessfully passed.");
 191     }
 192 
 193 
 194     // helper routines
 195     static long startTime = currentTimeMillis();
 196     static long currentTimeMillis() {
 197         //return System.nanoTime() / 1000000L;
 198         return System.currentTimeMillis();
 199     }
 200     static void log(String s) {
 201         long time = currentTimeMillis() - startTime;
 202         long ms = time % 1000;
 203         time /= 1000;
 204         long sec = time % 60;
 205         time /= 60;
 206         long min = time % 60;
 207         time /= 60;
 208         System.out.println(""
 209                 + (time < 10 ? "0" : "") + time
 210                 + ":" + (min < 10 ? "0" : "") + min
 211                 + ":" + (sec < 10 ? "0" : "") + sec
 212                 + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms
 213                 + " (" + Thread.currentThread().getName() + ") " + s);
 214     }
 215     static void delay(int millis) {
 216         try {
 217             Thread.sleep(millis);
 218         } catch (InterruptedException e) {}
 219     }
 220 }