1 /*
   2  * Copyright (c) 1999, 2003, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.sound.midi;
  27 
  28 import java.io.InputStream;
  29 import java.io.IOException;
  30 
  31 
  32 /**
  33  * A hardware or software device that plays back a MIDI
  34  * <code>{@link Sequence sequence}</code> is known as a <em>sequencer</em>.
  35  * A MIDI sequence contains lists of time-stamped MIDI data, such as
  36  * might be read from a standard MIDI file.  Most
  37  * sequencers also provide functions for creating and editing sequences.
  38  * <p>
  39  * The <code>Sequencer</code> interface includes methods for the following
  40  * basic MIDI sequencer operations:
  41  * <ul>
  42  * <li>obtaining a sequence from MIDI file data</li>
  43  * <li>starting and stopping playback</li>
  44  * <li>moving to an arbitrary position in the sequence</li>
  45  * <li>changing the tempo (speed) of playback</li>
  46  * <li>synchronizing playback to an internal clock or to received MIDI
  47  * messages</li>
  48  * <li>controlling the timing of another device</li>
  49  * </ul>
  50  * In addition, the following operations are supported, either directly, or
  51  * indirectly through objects that the <code>Sequencer</code> has access to:
  52  * <ul>
  53  * <li>editing the data by adding or deleting individual MIDI events or entire
  54  * tracks</li>
  55  * <li>muting or soloing individual tracks in the sequence</li>
  56  * <li>notifying listener objects about any meta-events or
  57  * control-change events encountered while playing back the sequence.</li>
  58  * </ul>
  59  *
  60  * @see Sequencer.SyncMode
  61  * @see #addMetaEventListener
  62  * @see ControllerEventListener
  63  * @see Receiver
  64  * @see Transmitter
  65  * @see MidiDevice
  66  *
  67  * @author Kara Kytle
  68  * @author Florian Bomers
  69  */
  70 public interface Sequencer extends MidiDevice {
  71 
  72 
  73     /**
  74      * A value indicating that looping should continue
  75      * indefinitely rather than complete after a specific
  76      * number of loops.
  77      *
  78      * @see #setLoopCount
  79      * @since 1.5
  80      */
  81     public static final int LOOP_CONTINUOUSLY = -1;
  82 
  83 
  84 
  85     /**
  86      * Sets the current sequence on which the sequencer operates.
  87      *
  88      * <p>This method can be called even if the
  89      * <code>Sequencer</code> is closed.
  90      *
  91      * @param sequence the sequence to be loaded.
  92      * @throws InvalidMidiDataException if the sequence contains invalid
  93      * MIDI data, or is not supported.
  94      */
  95     public void setSequence(Sequence sequence) throws InvalidMidiDataException;
  96 
  97 
  98     /**
  99      * Sets the current sequence on which the sequencer operates.
 100      * The stream must point to MIDI file data.
 101      *
 102      * <p>This method can be called even if the
 103      * <code>Sequencer</code> is closed.
 104      *
 105      * @param stream stream containing MIDI file data.
 106      * @throws IOException if an I/O exception occurs during reading of the stream.
 107      * @throws InvalidMidiDataException if invalid data is encountered
 108      * in the stream, or the stream is not supported.
 109      */
 110     public void setSequence(InputStream stream) throws IOException, InvalidMidiDataException;
 111 
 112 
 113     /**
 114      * Obtains the sequence on which the Sequencer is currently operating.
 115      *
 116      * <p>This method can be called even if the
 117      * <code>Sequencer</code> is closed.
 118      *
 119      * @return the current sequence, or <code>null</code> if no sequence is currently set.
 120      */
 121     public Sequence getSequence();
 122 
 123 
 124     /**
 125      * Starts playback of the MIDI data in the currently
 126      * loaded sequence.
 127      * Playback will begin from the current position.
 128      * If the playback position reaches the loop end point,
 129      * and the loop count is greater than 0, playback will
 130      * resume at the loop start point for the number of
 131      * repetitions set with <code>setLoopCount</code>.
 132      * After that, or if the loop count is 0, playback will
 133      * continue to play to the end of the sequence.
 134      *
 135      * <p>The implementation ensures that the synthesizer
 136      * is brought to a consistent state when jumping
 137      * to the loop start point by sending appropriate
 138      * controllers, pitch bend, and program change events.
 139      *
 140      * @throws IllegalStateException if the <code>Sequencer</code> is
 141      * closed.
 142      *
 143      * @see #setLoopStartPoint
 144      * @see #setLoopEndPoint
 145      * @see #setLoopCount
 146      * @see #stop
 147      */
 148     public void start();
 149 
 150 
 151     /**
 152      * Stops recording, if active, and playback of the currently loaded sequence,
 153      * if any.
 154      *
 155      * @throws IllegalStateException if the <code>Sequencer</code> is
 156      * closed.
 157      *
 158      * @see #start
 159      * @see #isRunning
 160      */
 161     public void stop();
 162 
 163 
 164     /**
 165      * Indicates whether the Sequencer is currently running.  The default is <code>false</code>.
 166      * The Sequencer starts running when either <code>{@link #start}</code> or <code>{@link #startRecording}</code>
 167      * is called.  <code>isRunning</code> then returns <code>true</code> until playback of the
 168      * sequence completes or <code>{@link #stop}</code> is called.
 169      * @return <code>true</code> if the Sequencer is running, otherwise <code>false</code>
 170      */
 171     public boolean isRunning();
 172 
 173 
 174     /**
 175      * Starts recording and playback of MIDI data.  Data is recorded to all enabled tracks,
 176      * on the channel(s) for which they were enabled.  Recording begins at the current position
 177      * of the sequencer.   Any events already in the track are overwritten for the duration
 178      * of the recording session.  Events from the currently loaded sequence,
 179      * if any, are delivered to the sequencer's transmitter(s) along with messages
 180      * received during recording.
 181      * <p>
 182      * Note that tracks are not by default enabled for recording.  In order to record MIDI data,
 183      * at least one track must be specifically enabled for recording.
 184      *
 185      * @throws IllegalStateException if the <code>Sequencer</code> is
 186      * closed.
 187      *
 188      * @see #startRecording
 189      * @see #recordEnable
 190      * @see #recordDisable
 191      */
 192     public void startRecording();
 193 
 194 
 195     /**
 196      * Stops recording, if active.  Playback of the current sequence continues.
 197      *
 198      * @throws IllegalStateException if the <code>Sequencer</code> is
 199      * closed.
 200      *
 201      * @see #startRecording
 202      * @see #isRecording
 203      */
 204     public void stopRecording();
 205 
 206 
 207     /**
 208      * Indicates whether the Sequencer is currently recording.  The default is <code>false</code>.
 209      * The Sequencer begins recording when <code>{@link #startRecording}</code> is called,
 210      * and then returns <code>true</code> until <code>{@link #stop}</code> or <code>{@link #stopRecording}</code>
 211      * is called.
 212      * @return <code>true</code> if the Sequencer is recording, otherwise <code>false</code>
 213      */
 214     public boolean isRecording();
 215 
 216 
 217     /**
 218      * Prepares the specified track for recording events received on a particular channel.
 219      * Once enabled, a track will receive events when recording is active.
 220      * @param track the track to which events will be recorded
 221      * @param channel the channel on which events will be received.  If -1 is specified
 222      * for the channel value, the track will receive data from all channels.
 223      * @throws IllegalArgumentException thrown if the track is not part of the current
 224      * sequence.
 225      */
 226     public void recordEnable(Track track, int channel);
 227 
 228 
 229     /**
 230      * Disables recording to the specified track.  Events will no longer be recorded
 231      * into this track.
 232      * @param track the track to disable for recording, or <code>null</code> to disable
 233      * recording for all tracks.
 234      */
 235     public void recordDisable(Track track);
 236 
 237 
 238     /**
 239      * Obtains the current tempo, expressed in beats per minute.  The
 240      * actual tempo of playback is the product of the returned value
 241      * and the tempo factor.
 242      *
 243      * @return the current tempo in beats per minute
 244      *
 245      * @see #getTempoFactor
 246      * @see #setTempoInBPM(float)
 247      * @see #getTempoInMPQ
 248      */
 249     public float getTempoInBPM();
 250 
 251 
 252     /**
 253      * Sets the tempo in beats per minute.   The actual tempo of playback
 254      * is the product of the specified value and the tempo factor.
 255      *
 256      * @param bpm desired new tempo in beats per minute
 257      * @see #getTempoFactor
 258      * @see #setTempoInMPQ(float)
 259      * @see #getTempoInBPM
 260      */
 261     public void setTempoInBPM(float bpm);
 262 
 263 
 264     /**
 265      * Obtains the current tempo, expressed in microseconds per quarter
 266      * note.  The actual tempo of playback is the product of the returned
 267      * value and the tempo factor.
 268      *
 269      * @return the current tempo in microseconds per quarter note
 270      * @see #getTempoFactor
 271      * @see #setTempoInMPQ(float)
 272      * @see #getTempoInBPM
 273      */
 274     public float getTempoInMPQ();
 275 
 276 
 277     /**
 278      * Sets the tempo in microseconds per quarter note.  The actual tempo
 279      * of playback is the product of the specified value and the tempo
 280      * factor.
 281      *
 282      * @param mpq desired new tempo in microseconds per quarter note.
 283      * @see #getTempoFactor
 284      * @see #setTempoInBPM(float)
 285      * @see #getTempoInMPQ
 286      */
 287     public void setTempoInMPQ(float mpq);
 288 
 289 
 290     /**
 291      * Scales the sequencer's actual playback tempo by the factor provided.
 292      * The default is 1.0.  A value of 1.0 represents the natural rate (the
 293      * tempo specified in the sequence), 2.0 means twice as fast, etc.
 294      * The tempo factor does not affect the values returned by
 295      * <code>{@link #getTempoInMPQ}</code> and <code>{@link #getTempoInBPM}</code>.
 296      * Those values indicate the tempo prior to scaling.
 297      * <p>
 298      * Note that the tempo factor cannot be adjusted when external
 299      * synchronization is used.  In that situation,
 300      * <code>setTempoFactor</code> always sets the tempo factor to 1.0.
 301      *
 302      * @param factor the requested tempo scalar
 303      * @see #getTempoFactor
 304      */
 305     public void setTempoFactor(float factor);
 306 
 307 
 308     /**
 309      * Returns the current tempo factor for the sequencer.  The default is
 310      * 1.0.
 311      *
 312      * @return tempo factor.
 313      * @see #setTempoFactor(float)
 314      */
 315     public float getTempoFactor();
 316 
 317 
 318     /**
 319      * Obtains the length of the current sequence, expressed in MIDI ticks,
 320      * or 0 if no sequence is set.
 321      * @return length of the sequence in ticks
 322      */
 323     public long getTickLength();
 324 
 325 
 326     /**
 327      * Obtains the current position in the sequence, expressed in MIDI
 328      * ticks.  (The duration of a tick in seconds is determined both by
 329      * the tempo and by the timing resolution stored in the
 330      * <code>{@link Sequence}</code>.)
 331      *
 332      * @return current tick
 333      * @see #setTickPosition
 334      */
 335     public long getTickPosition();
 336 
 337 
 338     /**
 339      * Sets the current sequencer position in MIDI ticks
 340      * @param tick the desired tick position
 341      * @see #getTickPosition
 342      */
 343     public void setTickPosition(long tick);
 344 
 345 
 346     /**
 347      * Obtains the length of the current sequence, expressed in microseconds,
 348      * or 0 if no sequence is set.
 349      * @return length of the sequence in microseconds.
 350      */
 351     public long getMicrosecondLength();
 352 
 353 
 354     /**
 355      * Obtains the current position in the sequence, expressed in
 356      * microseconds.
 357      * @return the current position in microseconds
 358      * @see #setMicrosecondPosition
 359      */
 360     public long getMicrosecondPosition();
 361 
 362 
 363     /**
 364      * Sets the current position in the sequence, expressed in microseconds
 365      * @param microseconds desired position in microseconds
 366      * @see #getMicrosecondPosition
 367      */
 368     public void setMicrosecondPosition(long microseconds);
 369 
 370 
 371     /**
 372      * Sets the source of timing information used by this sequencer.
 373      * The sequencer synchronizes to the master, which is the internal clock,
 374      * MIDI clock, or MIDI time code, depending on the value of
 375      * <code>sync</code>.  The <code>sync</code> argument must be one
 376      * of the supported modes, as returned by
 377      * <code>{@link #getMasterSyncModes}</code>.
 378      *
 379      * @param sync the desired master synchronization mode
 380      *
 381      * @see SyncMode#INTERNAL_CLOCK
 382      * @see SyncMode#MIDI_SYNC
 383      * @see SyncMode#MIDI_TIME_CODE
 384      * @see #getMasterSyncMode
 385      */
 386     public void setMasterSyncMode(SyncMode sync);
 387 
 388 
 389     /**
 390      * Obtains the current master synchronization mode for this sequencer.
 391      *
 392      * @return the current master synchronization mode
 393      *
 394      * @see #setMasterSyncMode(Sequencer.SyncMode)
 395      * @see #getMasterSyncModes
 396      */
 397     public SyncMode getMasterSyncMode();
 398 
 399 
 400     /**
 401      * Obtains the set of master synchronization modes supported by this
 402      * sequencer.
 403      *
 404      * @return the available master synchronization modes
 405      *
 406      * @see SyncMode#INTERNAL_CLOCK
 407      * @see SyncMode#MIDI_SYNC
 408      * @see SyncMode#MIDI_TIME_CODE
 409      * @see #getMasterSyncMode
 410      * @see #setMasterSyncMode(Sequencer.SyncMode)
 411      */
 412     public SyncMode[] getMasterSyncModes();
 413 
 414 
 415     /**
 416      * Sets the slave synchronization mode for the sequencer.
 417      * This indicates the type of timing information sent by the sequencer
 418      * to its receiver.  The <code>sync</code> argument must be one
 419      * of the supported modes, as returned by
 420      * <code>{@link #getSlaveSyncModes}</code>.
 421      *
 422      * @param sync the desired slave synchronization mode
 423      *
 424      * @see SyncMode#MIDI_SYNC
 425      * @see SyncMode#MIDI_TIME_CODE
 426      * @see SyncMode#NO_SYNC
 427      * @see #getSlaveSyncModes
 428      */
 429     public void setSlaveSyncMode(SyncMode sync);
 430 
 431 
 432     /**
 433      * Obtains the current slave synchronization mode for this sequencer.
 434      *
 435      * @return the current slave synchronization mode
 436      *
 437      * @see #setSlaveSyncMode(Sequencer.SyncMode)
 438      * @see #getSlaveSyncModes
 439      */
 440     public SyncMode getSlaveSyncMode();
 441 
 442 
 443     /**
 444      * Obtains the set of slave synchronization modes supported by the sequencer.
 445      *
 446      * @return the available slave synchronization modes
 447      *
 448      * @see SyncMode#MIDI_SYNC
 449      * @see SyncMode#MIDI_TIME_CODE
 450      * @see SyncMode#NO_SYNC
 451      */
 452     public SyncMode[] getSlaveSyncModes();
 453 
 454 
 455     /**
 456      * Sets the mute state for a track.  This method may fail for a number
 457      * of reasons.  For example, the track number specified may not be valid
 458      * for the current sequence, or the sequencer may not support this functionality.
 459      * An application which needs to verify whether this operation succeeded should
 460      * follow this call with a call to <code>{@link #getTrackMute}</code>.
 461      *
 462      * @param track the track number.  Tracks in the current sequence are numbered
 463      * from 0 to the number of tracks in the sequence minus 1.
 464      * @param mute the new mute state for the track.  <code>true</code> implies the
 465      * track should be muted, <code>false</code> implies the track should be unmuted.
 466      * @see #getSequence
 467      */
 468     public void setTrackMute(int track, boolean mute);
 469 
 470 
 471     /**
 472      * Obtains the current mute state for a track.  The default mute
 473      * state for all tracks which have not been muted is false.  In any
 474      * case where the specified track has not been muted, this method should
 475      * return false.  This applies if the sequencer does not support muting
 476      * of tracks, and if the specified track index is not valid.
 477      *
 478      * @param track the track number.  Tracks in the current sequence are numbered
 479      * from 0 to the number of tracks in the sequence minus 1.
 480      * @return <code>true</code> if muted, <code>false</code> if not.
 481      */
 482     public boolean getTrackMute(int track);
 483 
 484     /**
 485      * Sets the solo state for a track.  If <code>solo</code> is <code>true</code>
 486      * only this track and other solo'd tracks will sound. If <code>solo</code>
 487      * is <code>false</code> then only other solo'd tracks will sound, unless no
 488      * tracks are solo'd in which case all un-muted tracks will sound.
 489      * <p>
 490      * This method may fail for a number
 491      * of reasons.  For example, the track number specified may not be valid
 492      * for the current sequence, or the sequencer may not support this functionality.
 493      * An application which needs to verify whether this operation succeeded should
 494      * follow this call with a call to <code>{@link #getTrackSolo}</code>.
 495      *
 496      * @param track the track number.  Tracks in the current sequence are numbered
 497      * from 0 to the number of tracks in the sequence minus 1.
 498      * @param solo the new solo state for the track.  <code>true</code> implies the
 499      * track should be solo'd, <code>false</code> implies the track should not be solo'd.
 500      * @see #getSequence
 501      */
 502     public void setTrackSolo(int track, boolean solo);
 503 
 504 
 505     /**
 506      * Obtains the current solo state for a track.  The default mute
 507      * state for all tracks which have not been solo'd is false.  In any
 508      * case where the specified track has not been solo'd, this method should
 509      * return false.  This applies if the sequencer does not support soloing
 510      * of tracks, and if the specified track index is not valid.
 511      *
 512      * @param track the track number.  Tracks in the current sequence are numbered
 513      * from 0 to the number of tracks in the sequence minus 1.
 514      * @return <code>true</code> if solo'd, <code>false</code> if not.
 515      */
 516     public boolean getTrackSolo(int track);
 517 
 518 
 519     /**
 520      * Registers a meta-event listener to receive
 521      * notification whenever a meta-event is encountered in the sequence
 522      * and processed by the sequencer. This method can fail if, for
 523      * instance,this class of sequencer does not support meta-event
 524      * notification.
 525      *
 526      * @param listener listener to add
 527      * @return <code>true</code> if the listener was successfully added,
 528      * otherwise <code>false</code>
 529      *
 530      * @see #removeMetaEventListener
 531      * @see MetaEventListener
 532      * @see MetaMessage
 533      */
 534     public boolean addMetaEventListener(MetaEventListener listener);
 535 
 536 
 537     /**
 538      * Removes the specified meta-event listener from this sequencer's
 539      * list of registered listeners, if in fact the listener is registered.
 540      *
 541      * @param listener the meta-event listener to remove
 542      * @see #addMetaEventListener
 543      */
 544     public void removeMetaEventListener(MetaEventListener listener);
 545 
 546 
 547     /**
 548      * Registers a controller event listener to receive notification
 549      * whenever the sequencer processes a control-change event of the
 550      * requested type or types.  The types are specified by the
 551      * <code>controllers</code> argument, which should contain an array of
 552      * MIDI controller numbers.  (Each number should be between 0 and 127,
 553      * inclusive.  See the MIDI 1.0 Specification for the numbers that
 554      * correspond to various types of controllers.)
 555      * <p>
 556      * The returned array contains the MIDI controller
 557      * numbers for which the listener will now receive events.
 558      * Some sequencers might not support controller event notification, in
 559      * which case the array has a length of 0.  Other sequencers might
 560      * support notification for some controllers but not all.
 561      * This method may be invoked repeatedly.
 562      * Each time, the returned array indicates all the controllers
 563      * that the listener will be notified about, not only the controllers
 564      * requested in that particular invocation.
 565      *
 566      * @param listener the controller event listener to add to the list of
 567      * registered listeners
 568      * @param controllers the MIDI controller numbers for which change
 569      * notification is requested
 570      * @return the numbers of all the MIDI controllers whose changes will
 571      * now be reported to the specified listener
 572      *
 573      * @see #removeControllerEventListener
 574      * @see ControllerEventListener
 575      */
 576     public int[] addControllerEventListener(ControllerEventListener listener, int[] controllers);
 577 
 578 
 579     /**
 580      * Removes a controller event listener's interest in one or more
 581      * types of controller event. The <code>controllers</code> argument
 582      * is an array of MIDI numbers corresponding to the  controllers for
 583      * which the listener should no longer receive change notifications.
 584      * To completely remove this listener from the list of registered
 585      * listeners, pass in <code>null</code> for <code>controllers</code>.
 586      * The returned array contains the MIDI controller
 587      * numbers for which the listener will now receive events.  The
 588      * array has a length of 0 if the listener will not receive
 589      * change notifications for any controllers.
 590      *
 591      * @param listener old listener
 592      * @param controllers the MIDI controller numbers for which change
 593      * notification should be cancelled, or <code>null</code> to cancel
 594      * for all controllers
 595      * @return the numbers of all the MIDI controllers whose changes will
 596      * now be reported to the specified listener
 597      *
 598      * @see #addControllerEventListener
 599      */
 600     public int[] removeControllerEventListener(ControllerEventListener listener, int[] controllers);
 601 
 602 
 603     /**
 604      * Sets the first MIDI tick that will be
 605      * played in the loop. If the loop count is
 606      * greater than 0, playback will jump to this
 607      * point when reaching the loop end point.
 608      *
 609      * <p>A value of 0 for the starting point means the
 610      * beginning of the loaded sequence. The starting
 611      * point must be lower than or equal to the ending
 612      * point, and it must fall within the size of the
 613      * loaded sequence.
 614      *
 615      * <p>A sequencer's loop start point defaults to
 616      * start of the sequence.
 617      *
 618      * @param tick the loop's starting position,
 619      *        in MIDI ticks (zero-based)
 620      * @throws IllegalArgumentException if the requested
 621      *         loop start point cannot be set, usually because
 622      *         it falls outside the sequence's
 623      *         duration or because the start point is
 624      *         after the end point
 625      *
 626      * @see #setLoopEndPoint
 627      * @see #setLoopCount
 628      * @see #getLoopStartPoint
 629      * @see #start
 630      * @since 1.5
 631      */
 632     public void setLoopStartPoint(long tick);
 633 
 634 
 635     /**
 636      * Obtains the start position of the loop,
 637      * in MIDI ticks.
 638      *
 639      * @return the start position of the loop,
 640                in MIDI ticks (zero-based)
 641      * @see #setLoopStartPoint
 642      * @since 1.5
 643      */
 644     public long getLoopStartPoint();
 645 
 646 
 647     /**
 648      * Sets the last MIDI tick that will be played in
 649      * the loop. If the loop count is 0, the loop end
 650      * point has no effect and playback continues to
 651      * play when reaching the loop end point.
 652      *
 653      * <p>A value of -1 for the ending point
 654      * indicates the last tick of the sequence.
 655      * Otherwise, the ending point must be greater
 656      * than or equal to the starting point, and it must
 657      * fall within the size of the loaded sequence.
 658      *
 659      * <p>A sequencer's loop end point defaults to -1,
 660      * meaning the end of the sequence.
 661      *
 662      * @param tick the loop's ending position,
 663      *        in MIDI ticks (zero-based), or
 664      *        -1 to indicate the final tick
 665      * @throws IllegalArgumentException if the requested
 666      *         loop point cannot be set, usually because
 667      *         it falls outside the sequence's
 668      *         duration or because the ending point is
 669      *         before the starting point
 670      *
 671      * @see #setLoopStartPoint
 672      * @see #setLoopCount
 673      * @see #getLoopEndPoint
 674      * @see #start
 675      * @since 1.5
 676      */
 677     public void setLoopEndPoint(long tick);
 678 
 679 
 680     /**
 681      * Obtains the end position of the loop,
 682      * in MIDI ticks.
 683      *
 684      * @return the end position of the loop, in MIDI
 685      *         ticks (zero-based), or -1 to indicate
 686      *         the end of the sequence
 687      * @see #setLoopEndPoint
 688      * @since 1.5
 689      */
 690     public long getLoopEndPoint();
 691 
 692 
 693     /**
 694      * Sets the number of repetitions of the loop for
 695      * playback.
 696      * When the playback position reaches the loop end point,
 697      * it will loop back to the loop start point
 698      * <code>count</code> times, after which playback will
 699      * continue to play to the end of the sequence.
 700      * <p>
 701      * If the current position when this method is invoked
 702      * is greater than the loop end point, playback
 703      * continues to the end of the sequence without looping,
 704      * unless the loop end point is changed subsequently.
 705      * <p>
 706      * A <code>count</code> value of 0 disables looping:
 707      * playback will continue at the loop end point, and it
 708      * will not loop back to the loop start point.
 709      * This is a sequencer's default.
 710      *
 711      * <p>If playback is stopped during looping, the
 712      * current loop status is cleared; subsequent start
 713      * requests are not affected by an interrupted loop
 714      * operation.
 715      *
 716      * @param count the number of times playback should
 717      *        loop back from the loop's end position
 718      *        to the loop's start position, or
 719      *        <code>{@link #LOOP_CONTINUOUSLY}</code>
 720      *        to indicate that looping should
 721      *        continue until interrupted
 722      *
 723      * @throws IllegalArgumentException if <code>count</code> is
 724      * negative and not equal to {@link #LOOP_CONTINUOUSLY}
 725      *
 726      * @see #setLoopStartPoint
 727      * @see #setLoopEndPoint
 728      * @see #getLoopCount
 729      * @see #start
 730      * @since 1.5
 731      */
 732     public void setLoopCount(int count);
 733 
 734 
 735     /**
 736      * Obtains the number of repetitions for
 737      * playback.
 738      *
 739      * @return the number of loops after which
 740      *         playback plays to the end of the
 741      *         sequence
 742      * @see #setLoopCount
 743      * @see #start
 744      * @since 1.5
 745      */
 746     public int getLoopCount();
 747 
 748     /**
 749      * A <code>SyncMode</code> object represents one of the ways in which
 750      * a MIDI sequencer's notion of time can be synchronized with a master
 751      * or slave device.
 752      * If the sequencer is being synchronized to a master, the
 753      * sequencer revises its current time in response to messages from
 754      * the master.  If the sequencer has a slave, the sequencer
 755      * similarly sends messages to control the slave's timing.
 756      * <p>
 757      * There are three predefined modes that specify possible masters
 758      * for a sequencer: <code>INTERNAL_CLOCK</code>,
 759      * <code>MIDI_SYNC</code>, and <code>MIDI_TIME_CODE</code>.  The
 760      * latter two work if the sequencer receives MIDI messages from
 761      * another device.  In these two modes, the sequencer's time gets reset
 762      * based on system real-time timing clock messages or MIDI time code
 763      * (MTC) messages, respectively.  These two modes can also be used
 764      * as slave modes, in which case the sequencer sends the corresponding
 765      * types of MIDI messages to its receiver (whether or not the sequencer
 766      * is also receiving them from a master).  A fourth mode,
 767      * <code>NO_SYNC</code>, is used to indicate that the sequencer should
 768      * not control its receiver's timing.
 769      *
 770      * @see Sequencer#setMasterSyncMode(Sequencer.SyncMode)
 771      * @see Sequencer#setSlaveSyncMode(Sequencer.SyncMode)
 772      */
 773     public static class SyncMode {
 774 
 775         /**
 776          * Synchronization mode name.
 777          */
 778         private String name;
 779 
 780         /**
 781          * Constructs a synchronization mode.
 782          * @param name name of the synchronization mode
 783          */
 784         protected SyncMode(String name) {
 785 
 786             this.name = name;
 787         }
 788 
 789 
 790         /**
 791          * Determines whether two objects are equal.
 792          * Returns <code>true</code> if the objects are identical
 793          * @param obj the reference object with which to compare
 794          * @return <code>true</code> if this object is the same as the
 795          * <code>obj</code> argument, <code>false</code> otherwise
 796          */
 797         public final boolean equals(Object obj) {
 798 
 799             return super.equals(obj);
 800         }
 801 
 802 
 803         /**
 804          * Finalizes the hashcode method.
 805          */
 806         public final int hashCode() {
 807 
 808             return super.hashCode();
 809         }
 810 
 811 
 812         /**
 813          * Provides this synchronization mode's name as the string
 814          * representation of the mode.
 815          * @return the name of this synchronization mode
 816          */
 817         public final String toString() {
 818 
 819             return name;
 820         }
 821 
 822 
 823         /**
 824          * A master synchronization mode that makes the sequencer get
 825          * its timing information from its internal clock.  This is not
 826          * a legal slave sync mode.
 827          */
 828         public static final SyncMode INTERNAL_CLOCK             = new SyncMode("Internal Clock");
 829 
 830 
 831         /**
 832          * A master or slave synchronization mode that specifies the
 833          * use of MIDI clock
 834          * messages.  If this mode is used as the master sync mode,
 835          * the sequencer gets its timing information from system real-time
 836          * MIDI clock messages.  This mode only applies as the master sync
 837          * mode for sequencers that are also MIDI receivers.  If this is the
 838          * slave sync mode, the sequencer sends system real-time MIDI clock
 839          * messages to its receiver.  MIDI clock messages are sent at a rate
 840          * of 24 per quarter note.
 841          */
 842         public static final SyncMode MIDI_SYNC                  = new SyncMode("MIDI Sync");
 843 
 844 
 845         /**
 846          * A master or slave synchronization mode that specifies the
 847          * use of MIDI Time Code.
 848          * If this mode is used as the master sync mode,
 849          * the sequencer gets its timing information from MIDI Time Code
 850          * messages.  This mode only applies as the master sync
 851          * mode to sequencers that are also MIDI receivers.  If this
 852          * mode is used as the
 853          * slave sync mode, the sequencer sends MIDI Time Code
 854          * messages to its receiver.  (See the MIDI 1.0 Detailed
 855          * Specification for a description of MIDI Time Code.)
 856          */
 857         public static final SyncMode MIDI_TIME_CODE             = new SyncMode("MIDI Time Code");
 858 
 859 
 860         /**
 861          * A slave synchronization mode indicating that no timing information
 862          * should be sent to the receiver.  This is not a legal master sync
 863          * mode.
 864          */
 865         public static final SyncMode NO_SYNC                            = new SyncMode("No Timing");
 866 
 867     } // class SyncMode
 868 }