001: /*
002: *
003: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025:
026: package com.sun.mmedia;
027:
028: import com.sun.mmedia.DefaultConfiguration;
029: import com.sun.midp.main.*;
030:
031: import javax.microedition.media.*;
032: import java.io.IOException;
033: import java.io.ByteArrayOutputStream;
034: import javax.microedition.media.control.*;
035: import java.util.*;
036:
037: import com.sun.mmedia.DefaultConfiguration;
038: import com.sun.midp.log.Logging;
039: import com.sun.midp.log.LogChannels;
040: import com.sun.midp.main.*;
041:
042: /**
043: * Java Tone Sequence Player
044: * it implements ToneControl
045: */
046: public final class DirectTone extends DirectPlayer implements
047: ToneControl {
048:
049: /**
050: * It does not need data source
051: */
052: public DirectTone() {
053: hasDataSource = false;
054: }
055:
056: /**
057: * the worker method to realize the player
058: *
059: * @exception MediaException Description of the Exception
060: */
061: protected void doRealize() throws MediaException {
062:
063: // Get current isolate ID to support MVM
064: int isolateId = MIDletSuiteUtils.getIsolateId();
065:
066: // Init native library
067: if (this .source == null) {
068: hNative = nInit(isolateId, pID,
069: Manager.TONE_DEVICE_LOCATOR,
070: Manager.TONE_DEVICE_LOCATOR, -1);
071: } else {
072: hNative = nInit(isolateId, pID,
073: DefaultConfiguration.MIME_AUDIO_TONE, source
074: .getLocator(), -1);
075: }
076:
077: if (hNative == 0) {
078: throw new MediaException("Unable to realize tone player");
079: }
080:
081: // if no source stream, player is created from TONE_DEVICE_LOCATOR
082: // simply return it.
083: if (stream == null) {
084: return;
085: }
086:
087: // read the whole sequence from the source stream
088: int chunksize = 128;
089: byte[] tmpseqs = new byte[chunksize];
090: byte[] seqs = null;
091: // make use of BAOS, since it takes care of growing buffer
092: ByteArrayOutputStream baos = new ByteArrayOutputStream(
093: chunksize);
094:
095: try {
096: int read;
097:
098: while ((read = stream.read(tmpseqs, 0, chunksize)) != -1) {
099: baos.write(tmpseqs, 0, read);
100: }
101:
102: seqs = baos.toByteArray();
103: baos.close();
104: tmpseqs = null;
105: System.gc();
106:
107: } catch (IOException ex) {
108: throw new MediaException(
109: "unable to realize: fail to read from source");
110: }
111:
112: try {
113: this .setSequence(seqs);
114: } catch (Exception e) {
115: throw new MediaException("unable to realize: "
116: + e.getMessage());
117: }
118: }
119:
120: /**
121: * The worker method to actually obtain the control.
122: *
123: * @param type the class name of the <code>Control</code>.
124: * @return <code>Control</code> for the class or interface
125: * name.
126: */
127: protected Control doGetControl(String type) {
128: Control c = super .doGetControl(type);
129: if (c != null)
130: return c;
131:
132: if (getState() >= REALIZED) {
133: if (type
134: .equals("javax.microedition.media.control.ToneControl")) {
135: return this ;
136: }
137: }
138:
139: return null;
140: }
141:
142: /**
143: * Override getContentType from BasicPlayer
144: * Always return DefaultConfiguration.TONE content type
145: */
146: public String getContentType() {
147: chkClosed(true);
148: return DefaultConfiguration.MIME_AUDIO_TONE;
149: }
150:
151: /**
152: * Sets the tone sequence.<p>
153: *
154: * @param sequence The sequence to set.
155: * @exception IllegalArgumentException Thrown if the sequence is
156: * <code>null</code> or invalid.
157: * @exception IllegalStateException Thrown if the <code>Player</code>
158: * that this control belongs to is in the <i>PREFETCHED</i> or
159: * <i>STARTED</i> state.
160: */
161: public void setSequence(byte[] sequence) {
162: if (this .getState() >= Player.PREFETCHED)
163: throw new IllegalStateException(
164: "cannot set seq after prefetched");
165:
166: if (sequence == null)
167: throw new IllegalArgumentException("null sequence");
168: if (sequence.length == 0)
169: throw new IllegalArgumentException("empty sequence");
170:
171: nFlushBuffer(hNative);
172:
173: if (-1 == nBuffering(hNative, sequence, sequence.length))
174: throw new IllegalArgumentException("invalid sequence");
175:
176: if (-1 == nBuffering(hNative, sequence, -1))
177: throw new IllegalArgumentException("invalid sequence");
178:
179: hasToneSequenceSet = true;
180: }
181: }
|