Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java
38924 views
1
/*
2
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.media.sound;
27
28
import java.util.Map;
29
import java.util.Vector;
30
import java.util.WeakHashMap;
31
32
import javax.sound.sampled.AudioSystem;
33
import javax.sound.sampled.Control;
34
import javax.sound.sampled.Line;
35
import javax.sound.sampled.LineEvent;
36
import javax.sound.sampled.LineListener;
37
import javax.sound.sampled.LineUnavailableException;
38
39
40
/**
41
* AbstractLine
42
*
43
* @author Kara Kytle
44
*/
45
abstract class AbstractLine implements Line {
46
47
protected final Line.Info info;
48
protected Control[] controls;
49
AbstractMixer mixer;
50
private volatile boolean open;
51
private final Vector listeners = new Vector();
52
53
/**
54
* Contains event dispatcher per thread group.
55
*/
56
private static final Map<ThreadGroup, EventDispatcher> dispatchers =
57
new WeakHashMap<>();
58
59
/**
60
* Constructs a new AbstractLine.
61
* @param mixer the mixer with which this line is associated
62
* @param controls set of supported controls
63
*/
64
protected AbstractLine(Line.Info info, AbstractMixer mixer, Control[] controls) {
65
66
if (controls == null) {
67
controls = new Control[0];
68
}
69
70
this.info = info;
71
this.mixer = mixer;
72
this.controls = controls;
73
}
74
75
76
// LINE METHODS
77
78
public final Line.Info getLineInfo() {
79
return info;
80
}
81
82
83
public final boolean isOpen() {
84
return open;
85
}
86
87
88
public final void addLineListener(LineListener listener) {
89
synchronized(listeners) {
90
if ( ! (listeners.contains(listener)) ) {
91
listeners.addElement(listener);
92
}
93
}
94
}
95
96
97
/**
98
* Removes an audio listener.
99
* @param listener listener to remove
100
*/
101
public final void removeLineListener(LineListener listener) {
102
listeners.removeElement(listener);
103
}
104
105
106
/**
107
* Obtains the set of controls supported by the
108
* line. If no controls are supported, returns an
109
* array of length 0.
110
* @return control set
111
*/
112
public final Control[] getControls() {
113
Control[] returnedArray = new Control[controls.length];
114
115
for (int i = 0; i < controls.length; i++) {
116
returnedArray[i] = controls[i];
117
}
118
119
return returnedArray;
120
}
121
122
123
public final boolean isControlSupported(Control.Type controlType) {
124
// protect against a NullPointerException
125
if (controlType == null) {
126
return false;
127
}
128
129
for (int i = 0; i < controls.length; i++) {
130
if (controlType == controls[i].getType()) {
131
return true;
132
}
133
}
134
135
return false;
136
}
137
138
139
public final Control getControl(Control.Type controlType) {
140
// protect against a NullPointerException
141
if (controlType != null) {
142
143
for (int i = 0; i < controls.length; i++) {
144
if (controlType == controls[i].getType()) {
145
return controls[i];
146
}
147
}
148
}
149
150
throw new IllegalArgumentException("Unsupported control type: " + controlType);
151
}
152
153
154
// HELPER METHODS
155
156
157
/**
158
* This method sets the open state and generates
159
* events if it changes.
160
*/
161
final void setOpen(boolean open) {
162
163
if (Printer.trace) Printer.trace("> "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open);
164
165
boolean sendEvents = false;
166
long position = getLongFramePosition();
167
168
synchronized (this) {
169
if (this.open != open) {
170
this.open = open;
171
sendEvents = true;
172
}
173
}
174
175
if (sendEvents) {
176
if (open) {
177
sendEvents(new LineEvent(this, LineEvent.Type.OPEN, position));
178
} else {
179
sendEvents(new LineEvent(this, LineEvent.Type.CLOSE, position));
180
}
181
}
182
if (Printer.trace) Printer.trace("< "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open);
183
}
184
185
186
/**
187
* Send line events.
188
*/
189
final void sendEvents(LineEvent event) {
190
getEventDispatcher().sendAudioEvents(event, listeners);
191
}
192
193
194
/**
195
* This is an error in the API: getFramePosition
196
* should return a long value. At CD quality,
197
* the int value wraps around after 13 hours.
198
*/
199
public final int getFramePosition() {
200
return (int) getLongFramePosition();
201
}
202
203
204
/**
205
* Return the frame position in a long value
206
* This implementation returns AudioSystem.NOT_SPECIFIED.
207
*/
208
public long getLongFramePosition() {
209
return AudioSystem.NOT_SPECIFIED;
210
}
211
212
213
// $$kk: 06.03.99: returns the mixer used in construction.
214
// this is a hold-over from when there was a public method like
215
// this on line and should be fixed!!
216
final AbstractMixer getMixer() {
217
return mixer;
218
}
219
220
final EventDispatcher getEventDispatcher() {
221
// create and start the global event thread
222
//TODO need a way to stop this thread when the engine is done
223
final ThreadGroup tg = Thread.currentThread().getThreadGroup();
224
synchronized (dispatchers) {
225
EventDispatcher eventDispatcher = dispatchers.get(tg);
226
if (eventDispatcher == null) {
227
eventDispatcher = new EventDispatcher();
228
dispatchers.put(tg, eventDispatcher);
229
eventDispatcher.start();
230
}
231
return eventDispatcher;
232
}
233
}
234
235
// ABSTRACT METHODS
236
237
public abstract void open() throws LineUnavailableException;
238
public abstract void close();
239
}
240
241