001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.toolkit.audio;
025:
026: import jacareto.system.Environment;
027:
028: import java.io.BufferedInputStream;
029: import java.io.File;
030: import java.io.FileInputStream;
031: import java.io.FileNotFoundException;
032: import java.io.IOException;
033: import java.io.InputStream;
034:
035: import javax.sound.sampled.AudioFormat;
036: import javax.sound.sampled.AudioInputStream;
037: import javax.sound.sampled.AudioSystem;
038: import javax.sound.sampled.DataLine;
039: import javax.sound.sampled.SourceDataLine;
040:
041: /**
042: * An audio player for standard audio files.
043: *
044: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a>
045: * @version 1.0
046: */
047: public class JacaretoAudioPlayer implements Runnable {
048: /** The audio input stream. */
049: private AudioInputStream audioInputStream;
050:
051: /** The format of the audio input stream. */
052: private AudioFormat audioFormat;
053:
054: /** The source data line used to play the audio stream. */
055: private SourceDataLine sourceDataLine;
056:
057: /** The thread where the audio file is played in. */
058: private Thread thread;
059:
060: /** Indicated whether or not the audio file is replayed at the moment. */
061: private boolean isRunning;
062:
063: /** The environment. */
064: private Environment env;
065:
066: /**
067: * Creates an audio player from the given input stream.
068: *
069: * @param env DOCUMENT ME!
070: * @param input DOCUMENT ME!
071: */
072: public JacaretoAudioPlayer(Environment env, InputStream input) {
073: this .env = env;
074:
075: try {
076: audioInputStream = AudioSystem
077: .getAudioInputStream(new BufferedInputStream(input));
078: audioFormat = audioInputStream.getFormat();
079: } catch (Exception ioex) {
080: env
081: .getLogger()
082: .error(
083: env
084: .getLanguage()
085: .getString(
086: "Toolkit.AudioPlayer.Error.Creation"),
087: ioex);
088: }
089: }
090:
091: /**
092: * Creates an audio player from the given file.
093: *
094: * @param env DOCUMENT ME!
095: * @param file DOCUMENT ME!
096: *
097: * @throws FileNotFoundException DOCUMENT ME!
098: */
099: public JacaretoAudioPlayer(Environment env, File file)
100: throws FileNotFoundException {
101: this (env, new FileInputStream(file));
102: }
103:
104: /**
105: * Creates an audio player from the file with the given filename
106: *
107: * @param env DOCUMENT ME!
108: * @param filename DOCUMENT ME!
109: *
110: * @throws FileNotFoundException DOCUMENT ME!
111: */
112: public JacaretoAudioPlayer(Environment env, String filename)
113: throws FileNotFoundException {
114: this (env, new File(filename));
115: }
116:
117: /**
118: * Starts playing an audio file.
119: */
120: public void play() {
121: if (!isRunning()) {
122: isRunning = true;
123: thread = new Thread(this );
124: thread.start();
125: }
126: }
127:
128: public void run() {
129: try {
130: DataLine.Info dataLineInfo = new DataLine.Info(
131: SourceDataLine.class, audioFormat);
132: sourceDataLine = (SourceDataLine) AudioSystem
133: .getLine(dataLineInfo);
134: sourceDataLine.open(audioFormat);
135: sourceDataLine.start();
136:
137: //Copy data from the input stream to the output data line
138: int frameSize = audioFormat.getFrameSize();
139: int bufferlengthinframes = sourceDataLine.getBufferSize() / 8;
140: int bufferlengthinbytes = bufferlengthinframes * frameSize;
141: byte[] data = new byte[bufferlengthinbytes];
142: int bytesRead = 0;
143:
144: int counter = 0;
145:
146: while (isRunning
147: && ((bytesRead = audioInputStream.read(data)) != -1)) {
148: sourceDataLine.write(data, 0, bytesRead);
149: counter++;
150: }
151:
152: while (isRunning && sourceDataLine.isActive()) {
153: Thread.sleep(500);
154: }
155:
156: // otherwise the audio stream is sometimes interrupted
157: Thread.sleep(5000);
158:
159: stop();
160: } catch (Exception ex) {
161: env.getLogger().error(
162: env.getLanguage().getString(
163: "Toolkit.AudioPlayer.Error.Play"), ex);
164: }
165: }
166:
167: /**
168: * Stops playing an audio file.
169: */
170: public void stop() {
171: isRunning = false;
172:
173: if (sourceDataLine != null) {
174: sourceDataLine.stop();
175: sourceDataLine.flush();
176: sourceDataLine.close();
177: sourceDataLine = null;
178:
179: try {
180: audioInputStream.close();
181: } catch (IOException ioex) {
182: env.getLogger().error(
183: env.getLanguage().getString(
184: "Toolkit.AudioPlayer.Error.Close"),
185: ioex);
186: }
187: }
188: }
189:
190: /**
191: * Returns whether or not the audio file is replayed at the moment.
192: *
193: * @return DOCUMENT ME!
194: */
195: public boolean isRunning() {
196: return isRunning;
197: }
198: }
|