Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4427890

Sequencer.getTickLength() and Sequence.getTickLength() report the wrong length

XMLWordPrintable

    • mantis
    • generic, x86
    • generic, windows_xp



      Name: yyT116575 Date: 03/20/2001


      legion:source> java -version
      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
      Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)


      Sequencer.getTickLength() and Sequence.getTickLength() report a wrong total tick
      length.

      When checking the actual tick position (Sequencer.getTickPosition()) and
      comparing it with Sequencer.getTickLength() near the end of a track, the total
      tick length reported by Sequencer.getTickLength() has to be divided by 64 in
      order to correspond with the tick length reported by
      Sequencer.getTickPosition().

      I attached a little program demonstrating the problem as well as the work around. The
      program creates a simple MIDI sequence and plays is. It implements MetaEventListener, so one
      can track the actual tick position of the sequence played. It also supplies the total length
      in ticks (according to the sequencer (wrong)) and the corrected one (original divided by
      64). This problem is machine and operating system independent (I tried it on a Ultra 1
      running Solaris and on a PIII with Windows 2000).

      source code:

      import javax.sound.midi.*;

      public class TickLengthTester implements MetaEventListener {
        private Sequence theSequence;
        private Sequencer theSequencer;
        private Synthesizer theSynthesizer;

        public TickLengthTester() {
          this.initMidiCompoments();
          theSequence = this.generateSequence();
          try {
            theSequencer.setSequence(theSequence);
          }
          catch(Exception e) {
            System.out.println(this.getClass()+"\tCannot set sequence to sequencer ("+e+")");
            return;
          }
        }

        public void start() {
          theSequencer.start();
        }

        /*
          instantiate the necessary midi components
         */

        private void initMidiCompoments() {

          try {
            theSynthesizer = MidiSystem.getSynthesizer();
          }
          catch(Exception e) {
            System.out.println(this.getClass()+"\tSynthesizer Device not supported ("+e+")");
            System.exit(1);
          }

          try {
            theSynthesizer.open();
          }
          catch(Exception e) {
            System.out.println(this.getClass()+"\tCannot open Synthesizer Device ("+e+")");
            System.exit(1);
          }
          
          try {
            theSequencer = MidiSystem.getSequencer();
          }
          catch(Exception e) {
            System.out.println(this.getClass()+"\tSequencer Device not supported"+e+")");
            System.exit(1);
          }

          try {
            theSequencer.open();
          }
          catch(Exception e) {
            System.out.println(this.getClass()+"Cannot open Sequencer Device");
            System.exit(1);
          }
          if(!theSequencer.addMetaEventListener(this)) {
            System.out.println(this.getClass()+"\tCould not register MetaEventListener - there will be problems with scrolling! ");
          }
        }

        private Sequence generateSequence() {
          MidiEvent dummyMidiEvent;
          ShortMessage dummyShortMessage;
          Sequence dummySequence = null;
          Track[] allTracks ;
          Track theTrack;

          try {
            dummySequence = new Sequence(Sequence.PPQ,1500);
          }
          catch(InvalidMidiDataException e) {
            System.out.println("O o "+e);
          }
          
          dummySequence.createTrack();
          allTracks = dummySequence.getTracks();
          theTrack = allTracks[0];

          for(int i=0;i<20;i++) {
            theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_ON, 2, 30+i, 100,100+1000*i));
            theTrack.add(this.createMetaMidiEvent(1,"start",100+1000*i));
            theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_OFF, 2, 30+i, 100,(1000*i)+600));
            theTrack.add(this.createMetaMidiEvent(1,"end",(1000*i)+600));
          }

          return dummySequence;
        }

        /*
          A method to create a short midi event (sound)
        */

        public MidiEvent createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime) {
          ShortMessage dummyShortMessage;
          MidiEvent dummyMidiEvent;
            
          try {
            dummyShortMessage = new ShortMessage();
            dummyShortMessage.setMessage(theCommand, theChannel, theData1, theData2);
            dummyMidiEvent = new MidiEvent(dummyShortMessage,theTime);
          }
          catch (Exception e) {
            System.out.println(this.getClass()+"\t"+e);
            return null;
          }
            
          return dummyMidiEvent;
        }

        /*
          A method to create a meta midi event (used in meta() method)
        */
        public MidiEvent createMetaMidiEvent(int theType, String theData1, long theTime) {
          MetaMessage dummyMetaMessage;
          MidiEvent dummyMidiEvent;
            
          try {
            dummyMetaMessage = new MetaMessage();
            dummyMetaMessage.setMessage(theType, theData1.getBytes(), theData1.length());
            dummyMidiEvent = new MidiEvent(dummyMetaMessage,theTime);
          }
          catch (Exception e) {
            System.out.println(e);
            return null;
          }
            
          return dummyMidiEvent;
        }

        /*
          the method is activated by each meta midi event
          it puts out the actual tick position, as well as the WRONG total tick length and the RIGHT
          tick length using the work around by dividing the total length by 64
        */

        public void meta(MetaMessage p1) {
          if(p1.getType() ==47) {
            System.exit(0);
          }
          System.out.println("Actual:\t"+theSequencer.getTickPosition()+"\tWrong Length:\t"
              +theSequencer.getTickLength()+"\tRight Length:\t"+(theSequencer.getTickLength()/64));
        }

        public static void main(String[] args) {
          TickLengthTester tlt = new TickLengthTester();
          tlt.start();
        }
      }
      (Review ID: 118879)
      ======================================================================

      Name: vtR10009 Date: 07/31/2002


      This bug causes failure of new JCK test:
        api/javax_sound/midi/Sequencer/index.html#Sequencer




      ======================================================================

            fbomerssunw Florian Bomers (Inactive)
            yyoungsunw Yung-ching Young (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: