/*
 * 
 * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation. 
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt). 
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA 
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions. 
 */

package javax.microedition.media.control;

/**
 * TempoControl controls the tempo, in musical terms, of a song.
 * <p>
 * 
 * TempoControl is typically implemented in Players for MIDI
 * media, i.e. playback of a Standard MIDI File (SMF).<p>
 * 
 * TempoControl is basic functionality for a MIDI playback 
 * application. This is in contrast to {@link MIDIControl MIDIControl},
 * which targets advanced applications. Moreover, TempoControl 
 * needs a sequence - e.g. a MIDI file - to operate. MIDIControl 
 * does not require a sequence.<p>
 * 
 * Musical tempo is usually specified in beats per minute. To
 * provide a means to access tempos with fractional beats per
 * minute, the methods to set and get the tempo work on
 * &quot;milli-beat&quot; per minute. A simple division by
 * 1000 is sufficient to get the actual beats per minute.<p>
 * 
 * As a MIDI file can contain any number of tempo changes
 * during playback, the absolute tempo is a state of the
 * sequencer. During playback of a MIDI file, setting the tempo
 * in response to a user interaction will not always yield the
 * desired result: the user's tempo can be overridden by the
 * playing MIDI file to another tempo just moments later.<br>
 * In order to overcome this problem, a relative tempo rate is
 * used (in Java Sound terms: tempo factor). This rate is
 * applied to all tempo settings. The tempo rate is specified
 * in &quot;milli-percent&quot;, i.e. a value of 100'000 means
 * playback at original tempo. The tempo rate is set with the
 * <code>setRate()</code> method of the super class,
 * {@link RateControl RateControl}.<p>
 * 
 * The concept of tempo rate allows one to play back a MIDI sequence 
 * at a different tempo without losing the relative tempo changes
 * in it.<p>
 * 
 * The <code>setTempo()</code> and <code>getTempo()</code> methods 
 * do <b>not</b> affect or reflect the playback rate. This means that 
 * changing the 
 * rate will not result in a change of the value returned by
 * <code>getTempo()</code>. Similarly, setting the tempo with 
 * <code>setTempo()</code> does not change the rate, i.e. 
 * the return value of <code>getRate()</code> is not changed. The 
 * effective playback tempo is always the product of tempo and rate:<br>
 * <br>
 * <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 * effectiveBeatsPerMinute = getTempo() 
 * getRate() / 1000 / 100000</code>
 * <p>
 * 
 * @see javax.microedition.media.Player
 * @see javax.microedition.media.control.RateControl
 * @see javax.microedition.media.control.PitchControl
 * @see javax.microedition.media.control.MIDIControl
 */

public interface TempoControl extends RateControl {

    /**
     * Sets the current playback tempo.
     *
     * Tempo is a volatile state of the sequencer. As MIDI sequences
     * may contain META tempo events, tempo may change during
     * playback of the sequence. Setting the tempo with
     * <code>setTempo()</code> does not prevent the tempo from
     * being changed subsequently by tempo events in the MIDI
     * sequence. Example: during playback of a sequence,
     * the user changes the tempo. But just moments later, the
     * MIDI sequence changes the tempo to another value, so
     * effectively the user interaction is ignored.
     * To overcome this, and to allow consistent user interaction,
     * use <code>{@link RateControl#setRate(int) setRate()}</code>
     * inherited from <code>RateControl</code>.<p>
     *
     * The <code>setTempo()</code> method returns the actual tempo
     * set by the <code>Player</code>'s implementation. It
     * sets the tempo as close to the requested value as possible,
     * but is not required to set it to the exact value. Specifically,
     * implementations may have a lower or upper limit, which will
     * be used as tempo if the requested tempo is out of limits.
     * 0 or negative tempo does not exist and will always result
     * in the lower tempo limit of the implementation. Implementations
     * are guaranteed to support 10'000 to 300'000 milli-beats per minute.<p>
     *
     * Setting tempo to a stopped sequence will force the
     * sequence to start with that tempo, even if the sequence has a tempo
     * event at the start position. Any subsequent tempo events in
     * the sequence will be considered, though. Rewinding back to
     * a position with a tempo event will result in a
     * tempo change caused by the tempo event, too. Example: a sequence
     * with initial tempo of 120bpm has not been started yet. The
     * user sets the tempo to 140bpm and starts playback. When the
     * playback position is then reset to the beginning, the tempo will be
     * set to 120bpm due to the tempo event at the beginning of the sequence.<p>
     *
     * Playback rate (see <code>{@link RateControl#setRate(int) setRate()}</code>)
     * and tempo are independent factors of the effective tempo. Modifying
     * tempo with <code>setTempo()</code> does not affect the playback 
     * rate and vice versa. The effective tempo is the product of tempo and rate.
     *
     * @param millitempo The tempo specified in milli-beats
     *        per minute (must be &gt; 0, e.g. 120'000 for 120 beats per minute)
     * @return tempo that was actually set, expressed in milli-beats per minute
     * @see #getTempo
     */
    
    int setTempo(int millitempo);

    /**
     * Gets the current playback tempo.
     * This represents the current state of the sequencer:
     * <ul>
     *  <li>A sequencer may not be initialized before the
     *      <code>Player</code> is prefetched.  An uninitialized 
     *      sequencer in this case returns
     *      a default tempo of 120 beats per minute.</li>
     *  <li>After prefetching has finished, the tempo is
     *      set to the start tempo of the MIDI sequence (if any).</li>
     *  <li>During playback, the return value is the current tempo and
     *      varies with tempo events in the MIDI file</li>
     *  <li>A stopped sequence retains the last tempo it had
     *      before it was stopped.</li>
     *  <li>A call to <code>setTempo()</code> changes current tempo
     *      until a tempo event in the MIDI file is encountered.</li>
     * </ul>
     * @return current tempo, expressed in milli-beats per minute
     * @see #setTempo
     */
    int getTempo();

}
