Save This Page
Home » openjdk-7 » javax.sound » midi » [javadoc | source]
    1   /*
    2    * Copyright 1999-2004 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.sound.midi;
   27   
   28   import java.util.Vector;
   29   import com.sun.media.sound.MidiUtils;
   30   
   31   
   32   /**
   33    * A <code>Sequence</code> is a data structure containing musical
   34    * information (often an entire song or composition) that can be played
   35    * back by a <code>{@link Sequencer}</code> object. Specifically, the
   36    * <code>Sequence</code> contains timing
   37    * information and one or more tracks.  Each <code>{@link Track track}</code> consists of a
   38    * series of MIDI events (such as note-ons, note-offs, program changes, and meta-events).
   39    * The sequence's timing information specifies the type of unit that is used
   40    * to time-stamp the events in the sequence.
   41    * <p>
   42    * A <code>Sequence</code> can be created from a MIDI file by reading the file
   43    * into an input stream and invoking one of the <code>getSequence</code> methods of
   44    * {@link MidiSystem}.  A sequence can also be built from scratch by adding new
   45    * <code>Tracks</code> to an empty <code>Sequence</code>, and adding
   46    * <code>{@link MidiEvent}</code> objects to these <code>Tracks</code>.
   47    *
   48    * @see Sequencer#setSequence(java.io.InputStream stream)
   49    * @see Sequencer#setSequence(Sequence sequence)
   50    * @see Track#add(MidiEvent)
   51    * @see MidiFileFormat
   52    *
   53    * @author Kara Kytle
   54    */
   55   public class Sequence {
   56   
   57   
   58       // Timing types
   59   
   60       /**
   61        * The tempo-based timing type, for which the resolution is expressed in pulses (ticks) per quarter note.
   62        * @see #Sequence(float, int)
   63        */
   64       public static final float PPQ                                                       = 0.0f;
   65   
   66       /**
   67        * The SMPTE-based timing type with 24 frames per second (resolution is expressed in ticks per frame).
   68        * @see #Sequence(float, int)
   69        */
   70       public static final float SMPTE_24                                          = 24.0f;
   71   
   72       /**
   73        * The SMPTE-based timing type with 25 frames per second (resolution is expressed in ticks per frame).
   74        * @see #Sequence(float, int)
   75        */
   76       public static final float SMPTE_25                                          = 25.0f;
   77   
   78       /**
   79        * The SMPTE-based timing type with 29.97 frames per second (resolution is expressed in ticks per frame).
   80        * @see #Sequence(float, int)
   81        */
   82       public static final float SMPTE_30DROP                                      = 29.97f;
   83   
   84       /**
   85        * The SMPTE-based timing type with 30 frames per second (resolution is expressed in ticks per frame).
   86        * @see #Sequence(float, int)
   87        */
   88       public static final float SMPTE_30                                          = 30.0f;
   89   
   90   
   91       // Variables
   92   
   93       /**
   94        * The timing division type of the sequence.
   95        * @see #PPQ
   96        * @see #SMPTE_24
   97        * @see #SMPTE_25
   98        * @see #SMPTE_30DROP
   99        * @see #SMPTE_30
  100        * @see #getDivisionType
  101        */
  102       protected float divisionType;
  103   
  104       /**
  105        * The timing resolution of the sequence.
  106        * @see #getResolution
  107        */
  108       protected int resolution;
  109   
  110       /**
  111        * The MIDI tracks in this sequence.
  112        * @see #getTracks
  113        */
  114       protected Vector<Track> tracks = new Vector<Track>();
  115   
  116   
  117       /**
  118        * Constructs a new MIDI sequence with the specified timing division
  119        * type and timing resolution.  The division type must be one of the
  120        * recognized MIDI timing types.  For tempo-based timing,
  121        * <code>divisionType</code> is PPQ (pulses per quarter note) and
  122        * the resolution is specified in ticks per beat.  For SMTPE timing,
  123        * <code>divisionType</code> specifies the number of frames per
  124        * second and the resolution is specified in ticks per frame.
  125        * The sequence will contain no initial tracks.  Tracks may be
  126        * added to or removed from the sequence using <code>{@link #createTrack}</code>
  127        * and <code>{@link #deleteTrack}</code>.
  128        *
  129        * @param divisionType the timing division type (PPQ or one of the SMPTE types)
  130        * @param resolution the timing resolution
  131        * @throws InvalidMidiDataException if <code>divisionType</code> is not valid
  132        *
  133        * @see #PPQ
  134        * @see #SMPTE_24
  135        * @see #SMPTE_25
  136        * @see #SMPTE_30DROP
  137        * @see #SMPTE_30
  138        * @see #getDivisionType
  139        * @see #getResolution
  140        * @see #getTracks
  141        */
  142       public Sequence(float divisionType, int resolution) throws InvalidMidiDataException {
  143   
  144           if (divisionType == PPQ)
  145               this.divisionType = PPQ;
  146           else if (divisionType == SMPTE_24)
  147               this.divisionType = SMPTE_24;
  148           else if (divisionType == SMPTE_25)
  149               this.divisionType = SMPTE_25;
  150           else if (divisionType == SMPTE_30DROP)
  151               this.divisionType = SMPTE_30DROP;
  152           else if (divisionType == SMPTE_30)
  153               this.divisionType = SMPTE_30;
  154           else throw new InvalidMidiDataException("Unsupported division type: " + divisionType);
  155   
  156           this.resolution = resolution;
  157       }
  158   
  159   
  160       /**
  161        * Constructs a new MIDI sequence with the specified timing division
  162        * type, timing resolution, and number of tracks.  The division type must be one of the
  163        * recognized MIDI timing types.  For tempo-based timing,
  164        * <code>divisionType</code> is PPQ (pulses per quarter note) and
  165        * the resolution is specified in ticks per beat.  For SMTPE timing,
  166        * <code>divisionType</code> specifies the number of frames per
  167        * second and the resolution is specified in ticks per frame.
  168        * The sequence will be initialized with the number of tracks specified by
  169        * <code>numTracks</code>. These tracks are initially empty (i.e.
  170        * they contain only the meta-event End of Track).
  171        * The tracks may be retrieved for editing using the <code>{@link #getTracks}</code>
  172        * method.  Additional tracks may be added, or existing tracks removed,
  173        * using <code>{@link #createTrack}</code> and <code>{@link #deleteTrack}</code>.
  174        *
  175        * @param divisionType the timing division type (PPQ or one of the SMPTE types)
  176        * @param resolution the timing resolution
  177        * @param numTracks the initial number of tracks in the sequence.
  178        * @throws InvalidMidiDataException if <code>divisionType</code> is not valid
  179        *
  180        * @see #PPQ
  181        * @see #SMPTE_24
  182        * @see #SMPTE_25
  183        * @see #SMPTE_30DROP
  184        * @see #SMPTE_30
  185        * @see #getDivisionType
  186        * @see #getResolution
  187        */
  188       public Sequence(float divisionType, int resolution, int numTracks) throws InvalidMidiDataException {
  189   
  190           if (divisionType == PPQ)
  191               this.divisionType = PPQ;
  192           else if (divisionType == SMPTE_24)
  193               this.divisionType = SMPTE_24;
  194           else if (divisionType == SMPTE_25)
  195               this.divisionType = SMPTE_25;
  196           else if (divisionType == SMPTE_30DROP)
  197               this.divisionType = SMPTE_30DROP;
  198           else if (divisionType == SMPTE_30)
  199               this.divisionType = SMPTE_30;
  200           else throw new InvalidMidiDataException("Unsupported division type: " + divisionType);
  201   
  202           this.resolution = resolution;
  203   
  204           for (int i = 0; i < numTracks; i++) {
  205               tracks.addElement(new Track());
  206           }
  207       }
  208   
  209   
  210       /**
  211        * Obtains the timing division type for this sequence.
  212        * @return the division type (PPQ or one of the SMPTE types)
  213        *
  214        * @see #PPQ
  215        * @see #SMPTE_24
  216        * @see #SMPTE_25
  217        * @see #SMPTE_30DROP
  218        * @see #SMPTE_30
  219        * @see #Sequence(float, int)
  220        * @see MidiFileFormat#getDivisionType()
  221        */
  222       public float getDivisionType() {
  223           return divisionType;
  224       }
  225   
  226   
  227       /**
  228        * Obtains the timing resolution for this sequence.
  229        * If the sequence's division type is PPQ, the resolution is specified in ticks per beat.
  230        * For SMTPE timing, the resolution is specified in ticks per frame.
  231        *
  232        * @return the number of ticks per beat (PPQ) or per frame (SMPTE)
  233        * @see #getDivisionType
  234        * @see #Sequence(float, int)
  235        * @see MidiFileFormat#getResolution()
  236        */
  237       public int getResolution() {
  238           return resolution;
  239       }
  240   
  241   
  242       /**
  243        * Creates a new, initially empty track as part of this sequence.
  244        * The track initially contains the meta-event End of Track.
  245        * The newly created track is returned.  All tracks in the sequence
  246        * may be retrieved using <code>{@link #getTracks}</code>.  Tracks may be
  247        * removed from the sequence using <code>{@link #deleteTrack}</code>.
  248        * @return the newly created track
  249        */
  250       public Track createTrack() {
  251   
  252           Track track = new Track();
  253           tracks.addElement(track);
  254   
  255           return track;
  256       }
  257   
  258   
  259       /**
  260        * Removes the specified track from the sequence.
  261        * @param track the track to remove
  262        * @return <code>true</code> if the track existed in the track and was removed,
  263        * otherwise <code>false</code>.
  264        *
  265        * @see #createTrack
  266        * @see #getTracks
  267        */
  268       public boolean deleteTrack(Track track) {
  269   
  270           synchronized(tracks) {
  271   
  272               return tracks.removeElement(track);
  273           }
  274       }
  275   
  276   
  277       /**
  278        * Obtains an array containing all the tracks in this sequence.
  279        * If the sequence contains no tracks, an array of length 0 is returned.
  280        * @return the array of tracks
  281        *
  282        * @see #createTrack
  283        * @see #deleteTrack
  284        */
  285       public Track[] getTracks() {
  286   
  287           return (Track[]) tracks.toArray(new Track[tracks.size()]);
  288       }
  289   
  290   
  291       /**
  292        * Obtains the duration of this sequence, expressed in microseconds.
  293        * @return this sequence's duration in microseconds.
  294        */
  295       public long getMicrosecondLength() {
  296   
  297           return com.sun.media.sound.MidiUtils.tick2microsecond(this, getTickLength(), null);
  298       }
  299   
  300   
  301       /**
  302        * Obtains the duration of this sequence, expressed in MIDI ticks.
  303        *
  304        * @return this sequence's length in ticks
  305        *
  306        * @see #getMicrosecondLength
  307        */
  308       public long getTickLength() {
  309   
  310           long length = 0;
  311   
  312           synchronized(tracks) {
  313   
  314               for(int i=0; i<tracks.size(); i++ ) {
  315                   long temp = ((Track)tracks.elementAt(i)).ticks();
  316                   if( temp>length ) {
  317                       length = temp;
  318                   }
  319               }
  320               return length;
  321           }
  322       }
  323   
  324   
  325       /**
  326        * Obtains a list of patches referenced in this sequence.
  327        * This patch list may be used to load the required
  328        * <code>{@link Instrument}</code> objects
  329        * into a <code>{@link Synthesizer}</code>.
  330        *
  331        * @return an array of <code>{@link Patch}</code> objects used in this sequence
  332        *
  333        * @see Synthesizer#loadInstruments(Soundbank, Patch[])
  334        */
  335       public Patch[] getPatchList() {
  336   
  337           // $$kk: 04.09.99: need to implement!!
  338           return new Patch[0];
  339       }
  340   }

Save This Page
Home » openjdk-7 » javax.sound » midi » [javadoc | source]