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