blob: f995feef37dd30207b40827b620773e28234f184 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.audio;
27
28import java.util.Vector;
29import java.util.Enumeration;
30import java.io.IOException;
31import java.io.InputStream;
32import java.io.OutputStream;
33import java.io.FileOutputStream;
34
35import java.security.AccessController;
36import java.security.PrivilegedAction;
37
38
39/**
40 * This class provides an interface to play audio streams.
41 *
42 * To play an audio stream use:
43 * <pre>
44 * AudioPlayer.player.start(audiostream);
45 * </pre>
46 * To stop playing an audio stream use:
47 * <pre>
48 * AudioPlayer.player.stop(audiostream);
49 * </pre>
50 * To play an audio stream from a URL use:
51 * <pre>
52 * AudioStream audiostream = new AudioStream(url.openStream());
53 * AudioPlayer.player.start(audiostream);
54 * </pre>
55 * To play a continuous sound you first have to
56 * create an AudioData instance and use it to construct a
57 * ContinuousAudioDataStream.
58 * For example:
59 * <pre>
60 * AudioData data = new AudioStream(url.openStream()).getData();
61 * ContinuousAudioDataStream audiostream = new ContinuousAudioDataStream(data);
62 * AudioPlayer.player.start(audiostream);
63 * </pre>
64 *
65 * @see AudioData
66 * @see AudioDataStream
67 * @see AudioDevice
68 * @see AudioStream
69 * @author Arthur van Hoff, Thomas Ball
70 */
71
72public
73 class AudioPlayer extends Thread {
74
75 private AudioDevice devAudio;
76 private static boolean DEBUG = false /*true*/;
77
78 /**
79 * The default audio player. This audio player is initialized
80 * automatically.
81 */
82 public static final AudioPlayer player = getAudioPlayer();
83
84 private static ThreadGroup getAudioThreadGroup() {
85
86 if(DEBUG) { System.out.println("AudioPlayer.getAudioThreadGroup()"); }
87 ThreadGroup g = currentThread().getThreadGroup();
88 while ((g.getParent() != null) &&
89 (g.getParent().getParent() != null)) {
90 g = g.getParent();
91 }
92 return g;
93 }
94
95 /**
96 * Create an AudioPlayer thread in a privileged block.
97 */
98
99 private static AudioPlayer getAudioPlayer() {
100
101 if(DEBUG) { System.out.println("> AudioPlayer.getAudioPlayer()"); }
102 AudioPlayer audioPlayer;
103 PrivilegedAction action = new PrivilegedAction() {
104 public Object run() {
105 Thread t = new AudioPlayer();
106 t.setPriority(MAX_PRIORITY);
107 t.setDaemon(true);
108 t.start();
109 return t;
110 }
111 };
112 audioPlayer = (AudioPlayer) AccessController.doPrivileged(action);
113 return audioPlayer;
114 }
115
116 /**
117 * Construct an AudioPlayer.
118 */
119 private AudioPlayer() {
120
121 super(getAudioThreadGroup(), "Audio Player");
122 if(DEBUG) { System.out.println("> AudioPlayer private constructor"); }
123 devAudio = AudioDevice.device;
124 devAudio.open();
125 if(DEBUG) { System.out.println("< AudioPlayer private constructor completed"); }
126 }
127
128
129 /**
130 * Start playing a stream. The stream will continue to play
131 * until the stream runs out of data, or it is stopped.
132 * @see AudioPlayer#stop
133 */
134 public synchronized void start(InputStream in) {
135
136 if(DEBUG) {
137 System.out.println("> AudioPlayer.start");
138 System.out.println(" InputStream = " + in);
139 }
140 devAudio.openChannel(in);
141 notify();
142 if(DEBUG) {
143 System.out.println("< AudioPlayer.start completed");
144 }
145 }
146
147 /**
148 * Stop playing a stream. The stream will stop playing,
149 * nothing happens if the stream wasn't playing in the
150 * first place.
151 * @see AudioPlayer#start
152 */
153 public synchronized void stop(InputStream in) {
154
155 if(DEBUG) {
156 System.out.println("> AudioPlayer.stop");
157 }
158
159 devAudio.closeChannel(in);
160 if(DEBUG) {
161 System.out.println("< AudioPlayer.stop completed");
162 }
163 }
164
165 /**
166 * Main mixing loop. This is called automatically when the AudioPlayer
167 * is created.
168 */
169 public void run() {
170
171 // $$jb: 06.24.99: With the JS API, mixing is no longer done by AudioPlayer
172 // or AudioDevice ... it's done by the API itself, so this bit of legacy
173 // code does nothing.
174 // $$jb: 10.21.99: But it appears that some legacy applications
175 // check to see if this thread is alive or not, so we need to spin here.
176
177 devAudio.play();
178 if(DEBUG) {
179 System.out.println("AudioPlayer mixing loop.");
180 }
181 while(true) {
182 try{
183 Thread.sleep(5000);
184 //wait();
185 } catch(Exception e) {
186 break;
187 // interrupted
188 }
189 }
190 if(DEBUG) {
191 System.out.println("AudioPlayer exited.");
192 }
193
194 }
195 }