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 24import javax.sound.midi.InvalidMidiDataException; 25import javax.sound.midi.MetaMessage; 26import javax.sound.midi.MidiEvent; 27import javax.sound.midi.Sequence; 28import javax.sound.midi.ShortMessage; 29import javax.sound.midi.Track; 30 31/** 32 * @test 33 * @bug 4929955 34 * @summary Sequence.getMicrosecondLength() returns wrong value 35 */ 36public class GetMicrosecondLength { 37 38 public static boolean failed = false; 39 //private static Sequencer seq = null; 40 41 public static void main(String[] args) throws Exception { 42 /* 43 try { 44 seq = MidiSystem.getSequencer(); 45 } catch (Exception e) { 46 e.printStackTrace(); 47 } 48 */ 49 for (int sec = 1; sec < 10; sec += 4) { 50 for (int tempo=0; tempo < 1000; tempo+=120) { 51 for (int resolution=1; resolution < 480; ) { 52 testSequence(sec, tempo, resolution); 53 if (resolution == 1) { 54 resolution = 120; 55 } else { 56 resolution += 120; 57 } 58 } 59 } 60 } 61 if (failed) throw new Exception("Test FAILED!"); 62 out("Test Passed."); 63 } 64 65 /** 66 * Create a new Sequence for testing. 67 */ 68 private static void testSequence(int lengthInSeconds, int tempoInBPM, int resolution) { 69 Sequence sequence = null; 70 long lengthInMicroseconds = lengthInSeconds * 1000000; 71 boolean createTempoEvent = true; 72 if (tempoInBPM == 0) { 73 tempoInBPM = 120; 74 createTempoEvent = false; 75 System.out.print("Creating sequence: "+lengthInSeconds+"sec, " 76 +"resolution="+resolution+" ticks/beat..."); 77 } else { 78 System.out.print("Creating sequence: "+lengthInSeconds+"sec, " 79 +tempoInBPM+" beats/min, " 80 +"resolution="+resolution+" ticks/beat..."); 81 } 82 //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM; 83 long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l; 84 //out("expected length in ticks: " + lengthInTicks); 85 try { 86 sequence = new Sequence(Sequence.PPQ, resolution); 87 Track track = sequence.createTrack(); 88 if (createTempoEvent) { 89 int tempoInMPQ = (int) (60000000l / tempoInBPM); 90 MetaMessage tm = new MetaMessage(); 91 byte[] msg = new byte[3]; 92 msg[0] = (byte) (tempoInMPQ >> 16); 93 msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF); 94 msg[2] = (byte) (tempoInMPQ & 0xFF); 95 96 tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length); 97 track.add(new MidiEvent(tm, 0)); 98 //out("regtest: tempoInMPQ="+tempoInMPQ); 99 //out("Added tempo event: new size="+track.size()); 100 } 101 ShortMessage mm = new ShortMessage(); 102 mm.setMessage(0xF6, 0, 0); 103 MidiEvent me = new MidiEvent(mm, lengthInTicks); 104 track.add(me); 105 //out("Added realtime event: new size="+track.size()); 106 } catch (InvalidMidiDataException e) { 107 out(e); 108 } 109 boolean thisFailed = false; 110 long actualLengthInTicks = sequence.getTickLength(); 111 // allow +/- 5% 112 if (Math.abs(actualLengthInTicks - lengthInTicks) > lengthInTicks / 20) { 113 out("FAILED:"); 114 out(" expected length in ticks: " + lengthInTicks); 115 out(" actual length in ticks : " + actualLengthInTicks); 116 thisFailed = true; 117 } 118 long actualLengthInUs = sequence.getMicrosecondLength(); 119 // allow +/- 5% 120 if (Math.abs(actualLengthInUs - lengthInMicroseconds) > lengthInMicroseconds / 20) { 121 if (!thisFailed) { 122 out("FAILED:"); 123 } 124 out(" expected length in microsecs: " + lengthInMicroseconds); 125 out(" actual length in microsecs : " + actualLengthInUs); 126 thisFailed = true; 127 } 128 if (!thisFailed) { 129 out("OK"); 130 } 131 /*if (seq != null) { 132 try { 133 seq.setSequence(sequence); 134 out("Sequencer tempo="+seq.getTempoInBPM()); 135 } catch (Exception e) { 136 e.printStackTrace(); 137 } 138 } 139 */ 140 failed |= thisFailed; 141 } 142 143 144 private static void out(Throwable t) { 145 t.printStackTrace(System.out); 146 } 147 148 private static void out(String message) { 149 System.out.println(message); 150 } 151} 152