1 /* 2 * Copyright (c) 2003, 2016, 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.InvalidMidiDataException; 25 import javax.sound.midi.MetaEventListener; 26 import javax.sound.midi.MetaMessage; 27 import javax.sound.midi.MidiDevice; 28 import javax.sound.midi.MidiEvent; 29 import javax.sound.midi.MidiSystem; 30 import javax.sound.midi.Sequence; 31 import javax.sound.midi.Sequencer; 32 import javax.sound.midi.ShortMessage; 33 import javax.sound.midi.Track; 34 35 /** 36 * @test 37 * @bug 4204105 38 * @summary RFE: add loop() method(s) to Sequencer 39 * @key intermittent 40 */ 41 public class Looping { 42 main(String[] args)43 public static void main(String[] args) throws Exception { 44 out("4204105: RFE: add loop() method(s) to Sequencer"); 45 boolean passed = testAll(); 46 if (passed) { 47 out("Test PASSED."); 48 } else { 49 throw new Exception("Test FAILED."); 50 } 51 } 52 53 /** 54 * Execute the test on all available Sequencers. 55 * 56 * @return true if the test passed for all Sequencers, false otherwise 57 */ testAll()58 private static boolean testAll() throws Exception { 59 boolean result = true; 60 MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); 61 for (int i = 0; i < devices.length; i++) { 62 MidiDevice device = MidiSystem.getMidiDevice(devices[i]); 63 if (device instanceof Sequencer) { 64 result &= testSequencer((Sequencer) device); 65 } 66 } 67 return result; 68 } 69 70 /** 71 * Execute the test on the passed Sequencer. 72 * 73 * @return true if the test is passed this Sequencer, false otherwise 74 */ testSequencer(Sequencer seq)75 private static boolean testSequencer(Sequencer seq) throws Exception{ 76 boolean result = true; 77 out("testing: " + seq); 78 79 result &= testGetSet(seq); 80 81 seq.setSequence(createSequence()); 82 83 result &= testGetSet(seq); 84 85 result &= testPlay(seq); 86 87 return result; 88 } 89 testGetSet(Sequencer seq)90 private static boolean testGetSet(Sequencer seq) { 91 boolean result = true; 92 Sequence sequence = seq.getSequence(); 93 boolean isSequenceLoaded = (sequence != null); 94 95 out("TestGetSet"); 96 97 try { 98 if (seq.getLoopStartPoint() != 0) { 99 out("start point", isSequenceLoaded, 100 "isn't 0!"); 101 result = false; 102 } 103 } catch (IllegalArgumentException iae) { 104 if (!isSequenceLoaded) { 105 out("Caught permissable IllegalArgumentException:"); 106 } else { 107 out("Threw unacceptable IllegalArgumentException! FAILED"); 108 result = false; 109 } 110 out(iae.toString()); 111 } 112 113 if (seq.getLoopEndPoint() != -1) { 114 out("end point", isSequenceLoaded, 115 "isn't -1!"); 116 result = false; 117 } 118 119 try { 120 seq.setLoopStartPoint(25); 121 if (seq.getLoopStartPoint() != 25) { 122 out("setLoopStartPoint()", isSequenceLoaded, 123 "doesn't set the start point correctly!"); 124 result = false; 125 } 126 } catch (IllegalArgumentException iae) { 127 if (!isSequenceLoaded) { 128 out("Caught permissable IllegalArgumentException:"); 129 } else { 130 out("Threw unacceptable IllegalArgumentException! FAILED"); 131 result = false; 132 } 133 out(iae.toString()); 134 } 135 136 try { 137 seq.setLoopEndPoint(26); 138 if (seq.getLoopEndPoint() != 26) { 139 out("setLoopEndPoint()", isSequenceLoaded, 140 "doesn't set the end point correctly!"); 141 result = false; 142 } 143 } catch (IllegalArgumentException iae) { 144 if (!isSequenceLoaded) { 145 out("Caught permissable IllegalArgumentException:"); 146 } else { 147 out("Threw unacceptable IllegalArgumentException! FAILED"); 148 result = false; 149 } 150 out(iae.toString()); 151 } 152 153 try { 154 seq.setLoopStartPoint(0); 155 if (seq.getLoopStartPoint() != 0) { 156 out("setLoopStartPoint()", isSequenceLoaded, 157 "doesn't set the start point correctly!"); 158 result = false; 159 } 160 } catch (IllegalArgumentException iae) { 161 if (!isSequenceLoaded) { 162 out("Caught permissable IllegalArgumentException:"); 163 } else { 164 out("Threw unacceptable IllegalArgumentException! FAILED"); 165 result = false; 166 } 167 out(iae.toString()); 168 } 169 170 if (isSequenceLoaded) { 171 seq.setLoopEndPoint(sequence.getTickLength()); 172 if (seq.getLoopEndPoint() != sequence.getTickLength()) { 173 out("setLoopEndPoint()", isSequenceLoaded, 174 "doesn't set the end point correctly!"); 175 result = false; 176 } 177 } else { 178 // fails 179 seq.setLoopEndPoint(-1); 180 if (seq.getLoopEndPoint() != -1) { 181 out("setLoopEndPoint()", isSequenceLoaded, 182 "doesn't set the end point correctly!"); 183 result = false; 184 } 185 } 186 187 if (seq.getLoopCount() != 0) { 188 out("loop count", isSequenceLoaded, 189 "isn't 0!"); 190 result = false; 191 } 192 193 seq.setLoopCount(1001); 194 if (seq.getLoopCount() != 1001) { 195 out("setLoopCount()", isSequenceLoaded, 196 "doesn't set the loop count correctly!"); 197 result = false; 198 } 199 200 seq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); 201 if (seq.getLoopCount() != Sequencer.LOOP_CONTINUOUSLY) { 202 out("setLoopCount(Sequencer.LOOP_CONTINUOUSLY)", isSequenceLoaded, 203 "doesn't set the loop count correctly!"); 204 result = false; 205 } 206 207 try { 208 seq.setLoopCount(-55); 209 out("setLoopCount()", isSequenceLoaded, 210 "doesn't throw IllegalArgumentException on illegal value!"); 211 result = false; 212 } catch (IllegalArgumentException e) { 213 // EXCEPTION IS EXPECTED 214 out("Caught permissable IAE"); 215 } 216 217 seq.setLoopCount(0); 218 if (seq.getLoopCount() != 0) { 219 out("setLoopCount()", isSequenceLoaded, 220 "doesn't set the loop count correctly!"); 221 result = false; 222 } 223 224 return result; 225 } 226 testPlay(Sequencer seq)227 private static boolean testPlay(Sequencer seq) { 228 boolean result = true; 229 long stopTime; 230 231 out("TestPlay"); 232 233 TestMetaEventListener listener = new TestMetaEventListener(); 234 seq.addMetaEventListener(listener); 235 long startTime = System.currentTimeMillis(); 236 try { 237 seq.open(); 238 out("Playing sequence, length="+(seq.getMicrosecondLength()/1000)+"millis"); 239 seq.start(); 240 while (true) { 241 stopTime = listener.getStopTime(); 242 if (stopTime != 0) { 243 break; 244 } 245 try { 246 Thread.sleep(100); 247 } catch (InterruptedException e) { 248 } 249 } 250 long measuredDuration = stopTime - startTime; 251 out("play duration (us): " + measuredDuration); 252 } catch (Exception e) { 253 out("test not executed; exception:"); 254 e.printStackTrace(); 255 } 256 seq.close(); 257 return result; 258 } 259 260 /** 261 * Create a new Sequence for testing. 262 * 263 * @return a dummy Sequence, or null, if a problem occured while creating 264 * the Sequence 265 */ createSequence()266 private static Sequence createSequence() { 267 Sequence sequence = null; 268 int lengthInSeconds = 2; 269 long lengthInMicroseconds = lengthInSeconds * 1000000; 270 int resolution = 480; 271 long lengthInTicks = (lengthInMicroseconds * 120 * resolution) / 60000000l; 272 out("length in ticks: " + lengthInTicks); 273 try { 274 sequence = new Sequence(Sequence.PPQ, resolution, 1); 275 Track track = sequence.createTrack(); 276 ShortMessage mm = new ShortMessage(); 277 mm.setMessage(0xF6, 0, 0); 278 MidiEvent me = new MidiEvent(mm, lengthInTicks); 279 track.add(me); 280 } catch (InvalidMidiDataException e) { 281 // DO NOTHING 282 } 283 out("sequence length (ticks): " + sequence.getTickLength()); 284 out("sequence length (us): " + sequence.getMicrosecondLength()); 285 return sequence; 286 } 287 288 out(String m1, boolean isSequenceLoaded, String m2)289 private static void out(String m1, boolean isSequenceLoaded, String m2) { 290 out(m1 + (isSequenceLoaded ? " with Sequence " : " without Sequence ") + m2); 291 } 292 out(String message)293 private static void out(String message) { 294 System.out.println(message); 295 } 296 297 private static class TestMetaEventListener implements MetaEventListener { 298 private long stopTime; 299 300 meta(MetaMessage m)301 public void meta(MetaMessage m) { 302 System.out.print(" Got MetaMessage: "); 303 if (m.getType() == 47) { 304 stopTime = System.currentTimeMillis(); 305 System.out.println(" End Of Track -- OK"); 306 } else { 307 System.out.println(" unknown. Ignored."); 308 } 309 } 310 getStopTime()311 public long getStopTime() { 312 return stopTime; 313 } 314 } 315 } 316