|
|
@@ -298,6 +298,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|
|
}
|
|
|
if (audioDisabled)
|
|
|
return;
|
|
|
+
|
|
|
+ // There is a race condition in AudioNode that can
|
|
|
+ // cause this to be called for a node that has been
|
|
|
+ // detached from its channel. For example, setVolume()
|
|
|
+ // called from the render thread may see that that AudioNode
|
|
|
+ // still has a channel value but the audio thread may
|
|
|
+ // clear that channel before setVolume() gets to call
|
|
|
+ // updateSourceParam() (because the audio stopped playing
|
|
|
+ // on its own right as the volume was set). In this case,
|
|
|
+ // it should be safe to just ignore the update
|
|
|
+ if (src.getChannel() < 0)
|
|
|
+ return;
|
|
|
|
|
|
assert src.getChannel() >= 0;
|
|
|
|
|
|
@@ -745,6 +757,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|
|
src.setChannel(-1);
|
|
|
clearChannel(i);
|
|
|
freeChannel(i);
|
|
|
+
|
|
|
+ // And free the audio since it cannot be
|
|
|
+ // played again anyway.
|
|
|
+ deleteAudioData(stream);
|
|
|
}
|
|
|
}
|
|
|
}else if (!streaming){
|
|
|
@@ -913,6 +929,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|
|
src.setChannel(-1);
|
|
|
clearChannel(chan);
|
|
|
freeChannel(chan);
|
|
|
+
|
|
|
+ if (src.getAudioData() instanceof AudioStream) {
|
|
|
+
|
|
|
+ AudioStream stream = (AudioStream)src.getAudioData();
|
|
|
+ if (stream.isOpen()) {
|
|
|
+ stream.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ // And free the audio since it cannot be
|
|
|
+ // played again anyway.
|
|
|
+ deleteAudioData(src.getAudioData());
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -958,7 +986,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|
|
int[] ids = new int[STREAMING_BUFFER_COUNT];
|
|
|
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
|
|
alGenBuffers(ib);
|
|
|
- ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
|
|
+ ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
|
|
ib.get(ids);
|
|
|
|
|
|
as.setIds(ids);
|
|
|
@@ -974,28 +1002,36 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|
|
}
|
|
|
|
|
|
public void deleteAudioData(AudioData ad){
|
|
|
- if (audioDisabled)
|
|
|
- return;
|
|
|
-
|
|
|
- if (ad instanceof AudioBuffer){
|
|
|
- AudioBuffer ab = (AudioBuffer) ad;
|
|
|
- int id = ab.getId();
|
|
|
- if (id != -1){
|
|
|
- ib.put(0,id);
|
|
|
- ib.position(0).limit(1);
|
|
|
- alDeleteBuffers(ib);
|
|
|
- ab.resetObject();
|
|
|
+ synchronized (threadLock){
|
|
|
+ while (!threadLock.get()){
|
|
|
+ try {
|
|
|
+ threadLock.wait();
|
|
|
+ } catch (InterruptedException ex) {
|
|
|
+ }
|
|
|
}
|
|
|
- }else if (ad instanceof AudioStream){
|
|
|
- AudioStream as = (AudioStream) ad;
|
|
|
- int[] ids = as.getIds();
|
|
|
- if (ids != null){
|
|
|
- ib.clear();
|
|
|
- ib.put(ids).flip();
|
|
|
- alDeleteBuffers(ib);
|
|
|
- as.resetObject();
|
|
|
+ if (audioDisabled)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (ad instanceof AudioBuffer){
|
|
|
+ AudioBuffer ab = (AudioBuffer) ad;
|
|
|
+ int id = ab.getId();
|
|
|
+ if (id != -1){
|
|
|
+ ib.put(0,id);
|
|
|
+ ib.position(0).limit(1);
|
|
|
+ alDeleteBuffers(ib);
|
|
|
+ ab.resetObject();
|
|
|
+ }
|
|
|
+ }else if (ad instanceof AudioStream){
|
|
|
+ AudioStream as = (AudioStream) ad;
|
|
|
+ int[] ids = as.getIds();
|
|
|
+ if (ids != null){
|
|
|
+ ib.clear();
|
|
|
+ ib.put(ids).flip();
|
|
|
+ alDeleteBuffers(ib);
|
|
|
+ as.resetObject();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|