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 
isInstrumentExist(Instrument inst, Instrument[] insts)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 
test( boolean reloadInstr, boolean unloadFrom, boolean unloadTo )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 
cleanup()150     static void cleanup() {
151         if (synth != null) {
152             synth.close();
153             synth = null;
154         }
155     }
156 
runTest( boolean reloadInstr, boolean unloadTo, boolean unloadFrom )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 
main(String args[])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();
currentTimeMillis()196     static long currentTimeMillis() {
197         //return System.nanoTime() / 1000000L;
198         return System.currentTimeMillis();
199     }
log(String s)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     }
delay(int millis)215     static void delay(int millis) {
216         try {
217             Thread.sleep(millis);
218         } catch (InterruptedException e) {}
219     }
220 }
221