/* * * 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; /** * <code>ToneControl</code> is the interface to enable playback of a * user-defined monotonic tone sequence. * <p> * A tone sequence is specified as a list of tone-duration pairs and * user-defined sequence blocks. The list is packaged as an * array of bytes. The <code>setSequence</code> method is used to * input the sequence to the <code>ToneControl</code>. In addition, * the tone sequence format specified below can also be used as a * file format to define tone sequences. A file containing a * tone sequence as specified must use ".jts" as the file extension. * <code>"audio/x-tone-seq"</code> designates the MIME type for this * format. * <p> * <a name="tone_sequence_format"></a> * The syntax of a tone sequence is described in * <a href="http://www.ietf.org/rfc/rfc2234">Augmented BNF</a> notations: * <blockquote> * <pre> * sequence = version *1tempo_definition *1resolution_definition * *block_definition 1*sequence_event * * version = VERSION version_number * VERSION = byte-value * version_number = 1 ; version # 1 * * tempo_definition = TEMPO tempo_modifier * TEMPO = byte-value * tempo_modifier = byte-value * ; multiply by 4 to get the tempo (in bpm) used * ; in the sequence. * * resolution_definition = RESOLUTION resolution_unit * RESOLUTION = byte-value * resolution_unit = byte-value * * block_definition = BLOCK_START block_number * 1*sequence_event * BLOCK_END block_number * BLOCK_START = byte-value * BLOCK_END = byte-value * block_number = byte-value * ; block_number specified in BLOCK_END has to be the * ; same as the one in BLOCK_START * * sequence_event = tone_event / block_event / * volume_event / repeat_event * * tone_event = note duration * note = byte-value ; note to be played * duration = byte-value ; duration of the note * * block_event = PLAY_BLOCK block_number * PLAY_BLOCK = byte-value * block_number = byte-value * ; block_number must be previously defined * ; by a full block_definition * * volume_event = SET_VOLUME volume * SET_VOLUME = byte-value * volume = byte-value ; new volume * * repeat_event = REPEAT multiplier tone_event * REPEAT = byte-value * multiplier = byte-value * ; number of times to repeat a tone * * byte-value = -128 - 127 * ; the value of each constant and additional * ; constraints on each parameter are specified below. * </pre> * </blockquote> * * <A HREF="#VERSION"><code>VERSION</code></A>, * <A HREF="#TEMPO"><code>TEMPO</code></A>, * <A HREF="#RESOLUTION"><code>RESOLUTION</code></A>, * <A HREF="#BLOCK_START"><code>BLOCK_START</code></A>, * <A HREF="#BLOCK_END"><code>BLOCK_END</code></A>, * <A HREF="#PLAY_BLOCK"><code>PLAY_BLOCK</code></A> * <A HREF="#SET_VOLUME"><code>SET_VOLUME</code></A> * <A HREF="#REPEAT"><code>REPEAT</code></A> * are pre-defined constants. * <p> * Following table shows the valid range of the parameters: * <blockquote> * <table border=1> * <tr> * <td align="center">Parameter</td> * <td align="center">Valid Range</td> * <td align="center">Effective Range</td> * <td align="center">Default</td></tr> * <tr> * <td><code>tempo_modifier</code></td> * <td align="center">5<= <code>tempo_modifier</code> <= 127 </td> * <td align="center">20bpm to 508bpm</td> * <td align="center">120bpm</td></tr> * <tr> * <td><code>resolution_unit</code></td> * <td align="center">1<= <code>resolution_unit</code> <= 127 </td> * <td align="center">1/1 note to 1/127 note</td> * <td align="center">1/64 note</td></tr> * <tr> * <td><code>block_number</code></td> * <td align="center">0<= <code>block_number</code> <= 127</td> * <td align="center"> - </td> * <td align="center"> - </td></tr> * <tr> * <td><code>note</code></td> * <td align="center">0<= <code>note</code> <= 127 or * <A HREF="#SILENCE"<code>SILENCE</code></a></td> * <td align="center">C-1 to G9 or rest</td> * <td align="center"> - </td></tr> * <tr> * <td><code>duration</code></td> * <td align="center">1<= <code>duration</code> <= 127 </td> * <td align="center"> - </td> * <td align="center"> - </td></tr> * <tr> * <td><code>volume</code></td> * <td align="center">0<= <code>volume</code> <= 100 </td> * <td align="center">0% to 100% volume</td> * <td align="center">100%</td></tr> * <tr> * <td><code>multiplier</code></td> * <td align="center">2<= <code>multiplier</code> <= 127 </td> * <td align="center"> - </td> * <td align="center"> - </td></tr> * </table> <br> * </blockquote> * * The frequency * of the note can be calculated from the following formula: * <pre> * SEMITONE_CONST = 17.31234049066755 = 1/(ln(2^(1/12))) * note = ln(freq/8.176)*SEMITONE_CONST * </pre> * The musical note A = note 69 (0x45) = 440 Hz. <br> * <A HREF="#C4">Middle C (C4)</A> and * <A HREF="#SILENCE">SILENCE</A> are defined as constants. * <p> * The duration of each tone is measured in units of 1/resolution notes * and tempo is specified in beats/minute, where 1 beat = 1/4 note. * Because the range of positive values of <code>byte</code> is only 1 - 127, * the tempo is * formed by multiplying the tempo modifier by 4. Very slow tempos * are excluded so range of tempo modifiers is 5 - 127 providing an * effective range of 20 - 508 bpm. * <p> * To compute the effective duration in milliseconds for a tone, * the following formula can be used: * <pre> * duration * 60 * 1000 * 4 / (resolution * tempo) * </pre> * * The following table lists some common durations in musical notes: * <blockquote> * <table border=1> * <tr> * <td align="center">Note Length</td> * <td align="center">Duration, Resolution=64</td> * <td align="center">Duration, Resolution=96</td></tr> * <tr> * <td align="center">1/1</td> * <td align="center">64</td> * <td align="center">96</td></tr> * <tr> * <td align="center">1/4</td> * <td align="center">16</td> * <td align="center">24</td></tr> * <tr> * <td align="center">1/4 dotted</td> * <td align="center">24</td> * <td align="center">36</td></tr> * <tr> * <td align="center">1/8</td> * <td align="center">8</td> * <td align="center">12</td></tr> * <tr> * <td align="center">1/8 triplets</td> * <td align="center">-</td> * <td align="center">8</td></tr> * <tr> * <td align="center">4/1</td> * <td align="center"><code>REPEAT</code> 4 <note> 64</td> * <td align="center"><code>REPEAT</code> 4 <note> 96</td> * </table> * </blockquote> * * <h2>Example</h2> * <blockquote> * <pre> * // "Mary Had A Little Lamb" has "ABAC" structure. * // Use block to repeat "A" section. * * byte tempo = 30; // set tempo to 120 bpm * byte d = 8; // eighth-note * * byte C4 = ToneControl.C4;; * byte D4 = (byte)(C4 + 2); // a whole step * byte E4 = (byte)(C4 + 4); // a major third * byte G4 = (byte)(C4 + 7); // a fifth * byte rest = ToneControl.SILENCE; // rest * * byte[] mySequence = { * ToneControl.VERSION, 1, // version 1 * ToneControl.TEMPO, tempo, // set tempo * ToneControl.BLOCK_START, 0, // start define "A" section * E4,d, D4,d, C4,d, E4,d, // content of "A" section * E4,d, E4,d, E4,d, rest,d, * ToneControl.BLOCK_END, 0, // end define "A" section * ToneControl.PLAY_BLOCK, 0, // play "A" section * D4,d, D4,d, D4,d, rest,d, // play "B" section * E4,d, G4,d, G4,d, rest,d, * ToneControl.PLAY_BLOCK, 0, // repeat "A" section * D4,d, D4,d, E4,d, D4,d, C4,d // play "C" section * }; * * try{ * Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR); * p.realize(); * ToneControl c = (ToneControl)p.getControl("ToneControl"); * c.setSequence(mySequence); * p.start(); * } catch (IOException ioe) { * } catch (MediaException me) { } * * </pre> * </blockquote> * */ public interface ToneControl extends javax.microedition.media.Control { /** * The VERSION attribute tag. * <p> * Value -2 is assigned to <code>VERSION</code>. */ byte VERSION = -2; /** * The TEMPO event tag. * <p> * Value -3 is assigned to <code>TEMPO</code>. */ byte TEMPO = -3; /** * The RESOLUTION event tag. * <p> * Value -4 is assigned to <code>RESOLUTION</code>. */ byte RESOLUTION = -4; /** * Defines a starting point for a block. * <p> * Value -5 is assigned to <code>BLOCK_START</code>. */ byte BLOCK_START = -5; /** * Defines an ending point for a block. * <p> * Value -6 is assigned to <code>BLOCK_END</code>. */ byte BLOCK_END = -6; /** * Play a defined block. * <p> * Value -7 is assigned to <code>PLAY_BLOCK</code>. */ byte PLAY_BLOCK = -7; /** * The SET_VOLUME event tag. * <p> * Value -8 is assigned to <code>SET_VOLUME</code>. */ byte SET_VOLUME = -8; /** * The REPEAT event tag. * <p> * Value -9 is assigned to <code>REPEAT</code>. */ byte REPEAT = -9; /** * Middle C. * <p> * Value 60 is assigned to <code>C4</code>. */ byte C4 = 60; /** * Silence. * <p> * Value -1 is assigned to <code>SILENCE</code>. */ byte SILENCE = -1; /** * Sets the tone sequence.<p> * * @param sequence The sequence to set. * @exception IllegalArgumentException Thrown if the sequence is * <code>null</code> or invalid. * @exception IllegalStateException Thrown if the <code>Player</code> * that this control belongs to is in the <i>PREFETCHED</i> or * <i>STARTED</i> state. */ void setSequence(byte[] sequence); }