Methods Summary |
---|
protected void | doClose()The worker method to close the player
|
protected void | doDeallocate()The worker method to deallocate the player
toneCommon(ad, 1, 0); // PAUSE
toneCommon(ad, 5, 0); // CLOSE
ad = 0;
|
protected Control | doGetControl(java.lang.String type)The worker method to actually obtain the control.
if ((getState() >= REALIZED) &&
(type.equals("javax.microedition.media.control.ToneControl") ||
type.equals("javax.microedition.media.control.VolumeControl")))
return this;
return null;
|
public long | doGetDuration()Obtain the duration of this player.
if (curTime >= 0)
return (long)(curTime * 1000L);
else
return TIME_UNKNOWN;
|
public long | doGetMediaTime()Gets this player's current media time
in microseconds.
return (toneCommon(ad, 15, 0)*1000L); // GET_CUR_TIME
|
protected void | doPrefetch()the worker method to prefetch the player.
if (ad <= 0) {
ad = toneInit(pID);
if (ad <= 0)
throw new MediaException("prefetch failed");
if (getLevel() == -1) {
setLevel(100);
} else {
toneCommon(ad, 7, getLevel());
}
if (isMuted()) {
toneCommon(ad, 7, 0); // SET_VOLUME
}
}
|
protected void | doRealize()the worker method to realize the player
curTime = 0;
// if no source stream, player is created from TON_DEVICE_LOCATOR
// simply return it.
if (stream == null)
return;
// read the whole sequence from the source stream
int chunksize = 128;
byte[] tmpseqs = new byte[chunksize];
byte[] seqs = null;
// make use of BAOS, since it takes care of growing buffer
ByteArrayOutputStream baos = new ByteArrayOutputStream(chunksize);
try {
int read;
while ((read = stream.read(tmpseqs, 0, chunksize)) != -1) {
baos.write(tmpseqs, 0, read);
}
seqs = baos.toByteArray();
baos.close();
tmpseqs = null;
System.gc();
} catch (IOException ex) {
throw new MediaException("fail to read from source");
}
this.setSequence(seqs);
|
protected int | doSetLevel(int vol)The worker method to actually obtain the control.
// native code takes care of the conversion from 100 to 127.
toneCommon(ad, 7, vol); // SET_VOL
return (vol);
|
protected long | doSetMediaTime(long now)The worker method to actually set player's media time.
int milli_now = (int)(now /1000);
if (getState() == STARTED)
doStop();
milli_now = toneCommon(ad, 16, milli_now); // SET_CUR_TIME
if (getState() == STARTED)
doStart();
return (milli_now * 1000L);
|
protected boolean | doStart()The worker method to start the player.
if (seqChanged) {
toneSetSeq(ad, toneSeq);
seqChanged = false;
}
toneCommon(ad, 2, 0); // START
return true;
|
protected void | doStop()The worker method to stop the player
toneCommon(ad, 1, 0); // PAUSE
|
public java.lang.String | getContentType()Return the content type.
chkClosed(true);
return "audio/x-tone-seq";
|
private void | reportErr(int code)internal utility method to throw IAE
throw new IllegalArgumentException("bad tone param: err code " + code);
|
public void | setSequence(byte[] sequence)Sets the tone sequence.
if (this.getState() >= Player.PREFETCHED)
throw new
IllegalStateException("cannot set seq after prefetched");
int tempo = 120;
int resolution = 64;
int frac = 1;
int p = 0;
try {
Stack sp = new Stack();
Hashtable blens = new Hashtable();
Hashtable pblks = new Hashtable();
boolean inblk = false;
int found = 0, thisblen = 0, len;
byte note;
int i;
int startseq = 2;
len = 0;
int tmp = 0;
if (sequence[0] != VERSION || sequence[1] != 1) {
reportErr(6);
}
if (sequence[startseq] == TEMPO) {
if (sequence[startseq+1] < 5) {
reportErr(5);
}
tempo = (sequence[startseq+1] & 0x7f) << 2;
startseq += 2;
}
if (sequence[startseq] == RESOLUTION) {
if (sequence[startseq+1] <= 0)
reportErr(8);
resolution = sequence[startseq+1];
startseq += 2;
}
frac = tempo * resolution;
for (i = startseq; i < sequence.length; i += 2) {
note = sequence[i];
if (note < REPEAT ||
((note >= 0 || note == SILENCE) && sequence[i+1] <= 0)) {
reportErr(4);
}
switch (note) {
case BLOCK_START:
if (!inblk) {
if (sequence[i+1] < 0)
reportErr(7);
found = sequence[i+1];
inblk = true;
pblks.put(new Integer(found), new Integer(i));
thisblen = 0;
continue;
} else {
reportErr(3);
}
break;
case BLOCK_END:
if (inblk) {// blk end
if (sequence[i+1] == found) {
inblk = false;
blens.put(new Integer(found),
new Integer(thisblen));
} else {
reportErr(1);
}
continue;
} else {
reportErr(1);
}
break;
case REPEAT:
if (sequence[i+1] < 2)
reportErr(9);
note = sequence[i+2];
if (!(note == SILENCE || note >= 0))
reportErr(11);
break;
case SET_VOLUME:
if (sequence[i+1] < 0 || sequence[i+1] > 100)
reportErr(10);
len += 2;
break;
case PLAY_BLOCK:
if (blens.get(new Integer(sequence[i+1])) == null)
reportErr(2);
tmp = ((Integer)(blens.get(new Integer(sequence[i+1])))).
intValue();
if (inblk) {
thisblen += tmp;
} else {
len += tmp;
}
break;
case VERSION:
case TEMPO:
case RESOLUTION:
reportErr(12);
break;
default:
// SILENCE or normal tone
if (inblk) {
thisblen += 2;
} else {
len += 2;
}
} // switch
} // end of for(i)
if (inblk) {
reportErr(1);
}
// valid tone seq
toneSeq = new int[len];
curTime = 0;
p = 0;
i = startseq;
int mul = 1;
while (i < sequence.length) {
note = sequence[i];
switch (note) {
case BLOCK_START: // blk definition, start
do {
i += 2;
} while (sequence[i] != BLOCK_END);
break;
case PLAY_BLOCK: // play_blk
sp.push(new Integer(i+2));
i = ((Integer)pblks.get(new Integer(sequence[i+1]))).
intValue() + 2;
continue;
case BLOCK_END: // end playing blk
i = ((Integer)(sp.pop())).intValue();
continue;
case SET_VOLUME:
// 0 <= sequence[i+1] <= 100
toneSeq[p++] = SET_VOLUME;
toneSeq[p++] = (sequence[i+1] & 0x7f);
break;
case REPEAT:
// 2 <= sequence[i+1] <= 127
mul = sequence[i+1];
break;
default: // regular tone or SILENCE
toneSeq[p++] = sequence[i];
// dur as milliseconds
toneSeq[p++] += (sequence[i+1]&0x7f) * mul * 240000 / frac;
curTime += toneSeq[p-1];
mul = 1;
} // switch
i += 2;
} // while
} catch (IllegalArgumentException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalArgumentException(ex.getMessage());
}
seqChanged = true;
|
private native int | toneCommon(int ad, int code, int param)Utility native functions.
|
private native int | toneInit(int pID)Initialize the audio device for this tone seq
|
private native void | toneSetSeq(int ad, int[] toneseq)Pass the tone seq to the native code.
|