Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lDEVinux
GitHub Repository: lDEVinux/eaglercraft
Path: blob/main/src/lwjgl/java/paulscode/sound/StreamThread.java
8644 views
1
package paulscode.sound;
2
3
import java.util.LinkedList;
4
import java.util.List;
5
import java.util.ListIterator;
6
7
/**
8
* The StreamThread class is used to process all streaming sources. This
9
* thread starts out asleep, and it sleeps when all streaming sources are
10
* finished playing, so it is necessary to call interrupt() after adding new
11
* streaming sources to the list.
12
*<br><br>
13
*<b><i> SoundSystem License:</b></i><br><b><br>
14
* You are free to use this library for any purpose, commercial or otherwise.
15
* You may modify this library or source code, and distribute it any way you
16
* like, provided the following conditions are met:
17
*<br>
18
* 1) You may not falsely claim to be the author of this library or any
19
* unmodified portion of it.
20
*<br>
21
* 2) You may not copyright this library or a modified version of it and then
22
* sue me for copyright infringement.
23
*<br>
24
* 3) If you modify the source code, you must clearly document the changes
25
* made before redistributing the modified source code, so other users know
26
* it is not the original code.
27
*<br>
28
* 4) You are not required to give me credit for this library in any derived
29
* work, but if you do, you must also mention my website:
30
* http://www.paulscode.com
31
*<br>
32
* 5) I the author will not be responsible for any damages (physical,
33
* financial, or otherwise) caused by the use if this library or any part
34
* of it.
35
*<br>
36
* 6) I the author do not guarantee, warrant, or make any representations,
37
* either expressed or implied, regarding the use of this library or any
38
* part of it.
39
* <br><br>
40
* Author: Paul Lamb
41
* <br>
42
* http://www.paulscode.com
43
* </b>
44
*
45
*/
46
public class StreamThread extends SimpleThread
47
{
48
/**
49
* Processes status messages, warnings, and error messages.
50
*/
51
private SoundSystemLogger logger;
52
53
/**
54
* List of sources that are currently streaming.
55
*/
56
private List<Source> streamingSources;
57
58
/**
59
* Used to synchronize access to the streaming sources list.
60
*/
61
private final Object listLock = new Object();
62
63
/**
64
* Constructor: Grabs a handle to the message logger and instantiates the
65
* streaming sources list.
66
*/
67
public StreamThread()
68
{
69
// grab a handle to the message logger:
70
logger = SoundSystemConfig.getLogger();
71
72
streamingSources = new LinkedList<Source>();
73
}
74
75
/**
76
* Removes all references to instantiated objects, and changes the thread's
77
* state to "not alive". Method alive() returns false when the cleanup()
78
* method has completed.
79
*/
80
@Override
81
protected void cleanup()
82
{
83
kill();
84
super.cleanup(); // Important!!
85
}
86
87
/**
88
* The main loop for processing commands. The thread sleeps when it finishes
89
* processing commands, and it must be interrupted to process more.
90
*/
91
@Override
92
public void run()
93
{
94
ListIterator<Source> iter;
95
Source src;
96
97
// Start out asleep:
98
snooze( 3600000 );
99
100
while( !dying() )
101
{
102
while( !dying() && !streamingSources.isEmpty() )
103
{
104
// Make sure noone else is accessing the list of sources:
105
synchronized( listLock )
106
{
107
iter = streamingSources.listIterator();
108
while( !dying() && iter.hasNext() )
109
{
110
src = iter.next();
111
// If this is a removed source, we cleanup here and then let normal cleanup run - https://github.com/MinecraftForge/MinecraftForge/pull/4765
112
if (src!=null && src.removed)
113
{
114
src.cleanup();
115
src = null;
116
}
117
if( src == null )
118
{
119
iter.remove();
120
}
121
else if( src.stopped() )
122
{
123
if( !src.rawDataStream )
124
iter.remove();
125
}
126
else if( !src.active() )
127
{
128
if( src.toLoop || src.rawDataStream )
129
src.toPlay = true;
130
iter.remove();
131
}
132
else if( !src.paused() )
133
{
134
src.checkFadeOut();
135
if( (!src.stream()) && (!src.rawDataStream) )
136
{
137
if( src.channel == null
138
|| !src.channel.processBuffer() )
139
{
140
if( src.nextCodec == null )
141
{
142
src.readBuffersFromNextSoundInSequence();
143
}
144
/*
145
if( src.getSoundSequenceQueueSize() > 0 )
146
{
147
src.incrementSoundSequence();
148
}
149
150
// check if this is a looping source
151
else*/ if( src.toLoop )
152
{
153
// wait for stream to finish playing
154
if( !src.playing() )
155
{
156
// Generate an EOS event:
157
SoundSystemConfig.notifyEOS(
158
src.sourcename,
159
src.getSoundSequenceQueueSize()
160
);
161
// Check if the source is currently
162
// in the process of fading out.
163
if( src.checkFadeOut() )
164
{
165
// Source is fading out.
166
// Keep looping until it
167
// finishes.
168
src.preLoad = true;
169
}
170
else
171
{
172
// Source is not fading out.
173
// If there is another sound in
174
// the sequence, switch to it
175
// before replaying.
176
src.incrementSoundSequence();
177
src.preLoad = true; // replay
178
}
179
}
180
}
181
else
182
{
183
// wait for stream to finish playing
184
if( !src.playing() )
185
{
186
// Generate an EOS event:
187
SoundSystemConfig.notifyEOS(
188
src.sourcename,
189
src.getSoundSequenceQueueSize()
190
);
191
// Check if the source is currently
192
// in the process of fading out
193
if( !src.checkFadeOut() )
194
{
195
// Source is not fading out.
196
// Play anything else that is
197
// in the sound sequence queue.
198
if(
199
src.incrementSoundSequence() )
200
src.preLoad = true;
201
else
202
iter.remove(); // finished
203
}
204
}
205
}
206
}
207
}
208
}
209
}
210
}
211
if( !dying() && !streamingSources.isEmpty() )
212
snooze( 20 ); // sleep a bit so we don't peg the cpu
213
}
214
if( !dying() && streamingSources.isEmpty() )
215
snooze( 3600000 ); // sleep until there is more to do.
216
}
217
218
cleanup(); // Important!!
219
}
220
221
/**
222
* Adds a new streaming source to the list. If another source in the list is
223
* already playing on the same channel, it is stopped and removed from the
224
* list.
225
* @param source New source to stream.
226
*/
227
public void watch( Source source )
228
{
229
// make sure the source exists:
230
if( source == null )
231
return;
232
233
// make sure we aren't already watching this source:
234
if( streamingSources.contains( source ) )
235
return;
236
237
ListIterator<Source> iter;
238
Source src;
239
240
// Make sure noone else is accessing the list of sources:
241
synchronized( listLock )
242
{
243
// Any currently watched source which is null or playing on the
244
// same channel as the new source should be stopped and removed
245
// from the list.
246
iter = streamingSources.listIterator();
247
while( iter.hasNext() )
248
{
249
src = iter.next();
250
if( src == null )
251
{
252
iter.remove();
253
}
254
else if( source.channel == src.channel )
255
{
256
src.stop();
257
iter.remove();
258
}
259
}
260
261
// Add the new source to the list:
262
streamingSources.add( source );
263
}
264
}
265
266
/**
267
* Prints a message.
268
* @param message Message to print.
269
*/
270
private void message( String message )
271
{
272
logger.message( message, 0 );
273
}
274
275
/**
276
* Prints an important message.
277
* @param message Message to print.
278
*/
279
private void importantMessage( String message )
280
{
281
logger.importantMessage( message, 0 );
282
}
283
284
/**
285
* Prints the specified message if error is true.
286
* @param error True or False.
287
* @param message Message to print if error is true.
288
* @return True if error is true.
289
*/
290
private boolean errorCheck( boolean error, String message )
291
{
292
return logger.errorCheck( error, "StreamThread", message, 0 );
293
}
294
295
/**
296
* Prints an error message.
297
* @param message Message to print.
298
*/
299
private void errorMessage( String message )
300
{
301
logger.errorMessage( "StreamThread", message, 0 );
302
}
303
}
304
305