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.MidiDevice; 25 import javax.sound.midi.MidiSystem; 26 import javax.sound.midi.Sequencer; 27 import javax.sound.midi.Synthesizer; 28 29 /** 30 * @test 31 * @bug 4903786 32 * @summary MIDI OUT does not implement getMicrosecondPosition() consistently 33 */ 34 public class MidiOutGetMicrosecondPositionBug { 35 static int successfulTests = 0; 36 37 private static void testDevice(MidiDevice device) throws Exception { 38 boolean timestampsAvailable = false; 39 boolean timestampPrecisionOk = false; 40 try { 41 // expected behaviour if not opened? 42 device.open(); 43 /* First, we're testing if timestamps are provided at all. 44 Returning -1 (unsupported), while allowed by the API 45 specification, is not sufficient to pass this test. */ 46 long timestamp = device.getMicrosecondPosition(); 47 timestampsAvailable = (timestamp != -1); 48 49 /* Then, we're testing the precision. Note that the system time 50 is measured in milliseconds, while the device time is measured 51 in microseconds. */ 52 53 long systemTime1 = System.currentTimeMillis(); 54 long deviceTime1 = device.getMicrosecondPosition(); 55 // rest for 5 seconds 56 Thread.sleep(5000); 57 long systemTime2 = System.currentTimeMillis(); 58 long deviceTime2 = device.getMicrosecondPosition(); 59 60 // now both period measurements are calculated in milliseconds. 61 long systemDuration = systemTime2 - systemTime1; 62 long deviceDuration = (deviceTime2 - deviceTime1) / 1000; 63 long delta = Math.abs(systemDuration - deviceDuration); 64 // a deviation of 0.5 seconds (= 500 ms) is allowed. 65 timestampPrecisionOk = (delta <= 500); 66 } catch (Throwable t) { 67 System.out.println(" - Caught exception. Not failed."); 68 System.out.println(" - " + t.toString()); 69 return; 70 } finally { 71 device.close(); 72 } 73 if (! timestampsAvailable) { 74 throw new Exception("timestamps are not supported"); 75 } 76 if (! timestampPrecisionOk) { 77 throw new Exception("device timer not precise enough"); 78 } 79 successfulTests++; 80 } 81 82 private static void doAll() throws Exception { 83 MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); 84 for (int i=0; i < infos.length; i++) { 85 MidiDevice device = MidiSystem.getMidiDevice(infos[i]); 86 if ((! (device instanceof Sequencer)) && 87 (! (device instanceof Synthesizer)) && 88 (device.getMaxReceivers() > 0 || device.getMaxReceivers() == -1)) { 89 90 System.out.println("--------------"); 91 System.out.println("Testing MIDI device: " + infos[i]); 92 testDevice(device); 93 } 94 if (infos.length==0) { 95 System.out.println("No MIDI devices available!"); 96 } 97 } 98 } 99 100 public static void main(String[] args) throws Exception { 101 if (!isMidiInstalled()) { 102 return; 103 } 104 doAll(); 105 if (successfulTests==0) { 106 System.out.println("Could not execute any of the tests. Test NOT failed."); 107 } else { 108 System.out.println("Test PASSED."); 109 } 110 } 111 112 /** 113 * Returns true if at least one MIDI (port) device is correctly installed on 114 * the system. 115 */ 116 public static boolean isMidiInstalled() { 117 boolean result = false; 118 MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); 119 for (int i = 0; i < devices.length; i++) { 120 try { 121 MidiDevice device = MidiSystem.getMidiDevice(devices[i]); 122 result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer); 123 } catch (Exception e1) { 124 System.err.println(e1); 125 } 126 if (result) 127 break; 128 } 129 if (!result) { 130 System.err.println("Soundcard does not exist or sound drivers not installed!"); 131 System.err.println("This test requires sound drivers for execution."); 132 } 133 return result; 134 } 135 }