/* * * Copyright 1990-2009 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 * "milli-beat" 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 "milli-percent", 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>         * 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 > 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(); }