1 /* 2 * Copyright (c) 2002, 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.MidiEvent; 28 import javax.sound.midi.MidiSystem; 29 import javax.sound.midi.Sequence; 30 import javax.sound.midi.Sequencer; 31 import javax.sound.midi.ShortMessage; 32 import javax.sound.midi.Track; 33 34 /** 35 * @test 36 * @bug 4427890 37 * @run main/othervm TickLength 38 * @summary Sequencer.getTickLength() and Sequence.getTickLength() report the 39 * wrong length 40 */ 41 public class TickLength implements MetaEventListener { 42 private Sequence theSequence; 43 private Sequencer theSequencer; 44 TickLength()45 public TickLength() { 46 this.initMidiCompoments(); 47 System.out.println("Got Sequencer "+theSequencer); 48 theSequence = this.generateSequence(); 49 try { 50 theSequencer.setSequence(theSequence); 51 } 52 catch(Exception e) { 53 System.out.println(this.getClass()+"\tCannot set sequence to sequencer ("+e+")"); 54 return; 55 } 56 } 57 start()58 public void start() { 59 theSequencer.start(); 60 } 61 62 /* 63 instantiate the necessary midi components 64 */ initMidiCompoments()65 private boolean initMidiCompoments() { 66 67 68 try { 69 theSequencer = MidiSystem.getSequencer(); 70 } 71 catch(Exception e) { 72 System.out.println(this.getClass()+"\tSequencer Device not supported"+e+")"); 73 return false; 74 } 75 76 try { 77 theSequencer.open(); 78 } 79 catch(Exception e) { 80 System.out.println(this.getClass()+"Cannot open Sequencer Device"); 81 return false; 82 } 83 if(!theSequencer.addMetaEventListener(this)) { 84 System.out.println(this.getClass()+"\tCould not register MetaEventListener - there will be problems with scrolling! "); 85 return false; 86 } 87 return true; 88 } 89 90 static int lastTick = 0; 91 generateSequence()92 private Sequence generateSequence() { 93 MidiEvent dummyMidiEvent; 94 ShortMessage dummyShortMessage; 95 Sequence dummySequence = null; 96 Track[] allTracks ; 97 Track theTrack; 98 99 try { 100 dummySequence = new Sequence(Sequence.PPQ,1500); 101 } 102 catch(InvalidMidiDataException e) { 103 System.out.println("O o "+e); 104 } 105 106 dummySequence.createTrack(); 107 allTracks = dummySequence.getTracks(); 108 theTrack = allTracks[0]; 109 lastTick = 0; 110 for(int i=0;i<20; i++) { 111 theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_ON, 2, 30+i, 100,100+1000*i)); 112 theTrack.add(this.createMetaMidiEvent(1,"start",100+1000*i)); 113 lastTick = (1000*i)+600; 114 theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_OFF, 2, 30+i, 100, lastTick)); 115 theTrack.add(this.createMetaMidiEvent(1,"end",lastTick)); 116 } 117 118 return dummySequence; 119 } 120 121 /* 122 A method to create a short midi event (sound) 123 */ 124 createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime)125 public MidiEvent createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime) { 126 ShortMessage dummyShortMessage; 127 MidiEvent dummyMidiEvent; 128 129 try { 130 dummyShortMessage = new ShortMessage(); 131 dummyShortMessage.setMessage(theCommand, theChannel, theData1, theData2); 132 dummyMidiEvent = new MidiEvent(dummyShortMessage,theTime); 133 } 134 catch (Exception e) { 135 System.out.println(this.getClass()+"\t"+e); 136 return null; 137 } 138 139 return dummyMidiEvent; 140 } 141 142 /* 143 A method to create a meta midi event (used in meta() method) 144 */ createMetaMidiEvent(int theType, String theData1, long theTime)145 public MidiEvent createMetaMidiEvent(int theType, String theData1, long theTime) { 146 MetaMessage dummyMetaMessage; 147 MidiEvent dummyMidiEvent; 148 149 try { 150 dummyMetaMessage = new MetaMessage(); 151 dummyMetaMessage.setMessage(theType, theData1.getBytes(), theData1.length()); 152 dummyMidiEvent = new MidiEvent(dummyMetaMessage,theTime); 153 } 154 catch (Exception e) { 155 System.out.println(e); 156 return null; 157 } 158 159 return dummyMidiEvent; 160 } 161 162 /* 163 the method is activated by each meta midi event 164 it puts out the actual tick position, as well as the WRONG total tick length and the RIGHT 165 tick length using the work around by dividing the total length by 64 166 */ meta(MetaMessage p1)167 public void meta(MetaMessage p1) { 168 if(p1.getType() ==47) { 169 return; 170 } 171 System.out.println("getTickPosition:\t"+theSequencer.getTickPosition() 172 +"\t Sequencer.getTickLength:\t"+theSequencer.getTickLength() 173 +"\tReal Length:\t"+lastTick 174 +"\t Sequence.getTickLength:\t"+theSequence.getTickLength() 175 //(theSequencer.getTickLength()/64)); 176 ); 177 } 178 checkLengths()179 public void checkLengths() throws Exception { 180 System.out.println("Sequencer.getTickLength() = "+theSequencer.getTickLength()); 181 System.out.println("Sequence.getTickLength() = "+theSequence.getTickLength()); 182 long diff = theSequencer.getTickLength() - theSequence.getTickLength(); 183 if (diff > 100 || diff < -100) { 184 throw new Exception("Difference too large! Failed."); 185 } 186 System.out.println("Passed"); 187 } 188 main(String[] args)189 public static void main(String[] args) throws Exception { 190 if (!hasSequencer()) { 191 return; 192 } 193 TickLength tlt = new TickLength(); 194 //tlt.start(); 195 tlt.checkLengths(); 196 } 197 hasSequencer()198 static boolean hasSequencer() { 199 try { 200 Sequencer seq = MidiSystem.getSequencer(); 201 if (seq != null) { 202 seq.open(); 203 seq.close(); 204 return true; 205 } 206 } catch (Exception e) {} 207 System.out.println("No sequencer available! Cannot execute test."); 208 return false; 209 } 210 211 } 212