FileDocCategorySizeDatePackage
ToneControl.javaAPI DocJ2ME MIDP 2.010369Thu Nov 07 12:02:28 GMT 2002javax.microedition.media.control

ToneControl

public interface ToneControl implements javax.microedition.media.Control
ToneControl is the interface to enable playback of a user-defined monotonic tone sequence.

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 setSequence method is used to input the sequence to the ToneControl.

The syntax of a tone sequence is described in Augmented BNF notations:

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.
VERSION, TEMPO, RESOLUTION, BLOCK_START, BLOCK_END, PLAY_BLOCK SET_VOLUME REPEAT are pre-defined constants.

Following table shows the valid range of the parameters:

Parameter Valid Range Effective Range Default
tempo_modifier 5<= tempo_modifier <= 127 20bpm to 508bpm 120bpm
resolution_unit 1<= resolution_unit <= 127 1/1 note to 1/127 note 1/64 note
block_number 0<= block_number <= 127 - -
note 0<= note <= 127 or SILENCE C-1 to G9 or rest -
duration 1<= duration <= 127 - -
volume 0<= volume <= 100 0% to 100% volume 100%
multiplier 2<= multiplier <= 127 - -

The frequency of the note can be calculated from the following formula:
SEMITONE_CONST = 17.31234049066755 = 1/(ln(2^(1/12)))
note = ln(freq/8.176)*SEMITONE_CONST
The musical note A = note 69 (0x45) = 440 Hz.
Middle C (C4) and SILENCE are defined as constants.

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 byte 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.

To compute the effective duration in milliseconds for a tone, the following formula can be used:

duration * 60 * 1000 * 4 / (resolution * tempo)
The following table lists some common durations in musical notes:
Note Length Duration, Resolution=64 Duration, Resolution=96
1/1 64 96
1/4 16 24
1/4 dotted 24 36
1/8 8 12
1/8 triplets - 8
4/1 REPEAT 4 <note> 64 REPEAT 4 <note> 96

Example

// "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) { }

Fields Summary
byte
VERSION
The VERSION attribute tag.

Value -2 is assigned to VERSION.

byte
TEMPO
The TEMPO event tag.

Value -3 is assigned to TEMPO.

byte
RESOLUTION
The RESOLUTION event tag.

Value -4 is assigned to RESOLUTION.

byte
BLOCK_START
Defines a starting point for a block.

Value -5 is assigned to BLOCK_START.

byte
BLOCK_END
Defines an ending point for a block.

Value -6 is assigned to BLOCK_END.

byte
PLAY_BLOCK
Play a defined block.

Value -7 is assigned to PLAY_BLOCK.

byte
SET_VOLUME
The SET_VOLUME event tag.

Value -8 is assigned to SET_VOLUME.

byte
REPEAT
The REPEAT event tag.

Value -9 is assigned to REPEAT.

byte
C4
Middle C.

Value 60 is assigned to C4.

byte
SILENCE
Silence.

Value -1 is assigned to SILENCE.

Constructors Summary
Methods Summary
public voidsetSequence(byte[] sequence)
Sets the tone sequence.

param
sequence The sequence to set.
exception
IllegalArgumentException Thrown if the sequence is null or invalid.
exception
IllegalStateException Thrown if the Player that this control belongs to is in the PREFETCHED or STARTED state.