Sort of fixed a streaming related memory leak. Well,
streams won't leak anymore but the buffered case technically will if you create them and drop them because that's a different level of fix. Also made the deleteAudioData synchronized since it can be called from another thread pretty trivially. And fixed a race condition that caused an IndexOutOfBounds exception if you happen to try adjusting an AudioNode's parameters right as it was finishing playing. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7506 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
e73e97f753
commit
c75f157cbb
@ -298,6 +298,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
}
|
}
|
||||||
if (audioDisabled)
|
if (audioDisabled)
|
||||||
return;
|
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;
|
assert src.getChannel() >= 0;
|
||||||
|
|
||||||
@ -745,6 +757,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
src.setChannel(-1);
|
src.setChannel(-1);
|
||||||
clearChannel(i);
|
clearChannel(i);
|
||||||
freeChannel(i);
|
freeChannel(i);
|
||||||
|
|
||||||
|
// And free the audio since it cannot be
|
||||||
|
// played again anyway.
|
||||||
|
deleteAudioData(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if (!streaming){
|
}else if (!streaming){
|
||||||
@ -913,6 +929,18 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
src.setChannel(-1);
|
src.setChannel(-1);
|
||||||
clearChannel(chan);
|
clearChannel(chan);
|
||||||
freeChannel(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];
|
int[] ids = new int[STREAMING_BUFFER_COUNT];
|
||||||
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
||||||
alGenBuffers(ib);
|
alGenBuffers(ib);
|
||||||
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
ib.position(0).limit(STREAMING_BUFFER_COUNT);
|
||||||
ib.get(ids);
|
ib.get(ids);
|
||||||
|
|
||||||
as.setIds(ids);
|
as.setIds(ids);
|
||||||
@ -974,28 +1002,36 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAudioData(AudioData ad){
|
public void deleteAudioData(AudioData ad){
|
||||||
if (audioDisabled)
|
synchronized (threadLock){
|
||||||
return;
|
while (!threadLock.get()){
|
||||||
|
try {
|
||||||
|
threadLock.wait();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (audioDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ad instanceof AudioBuffer){
|
if (ad instanceof AudioBuffer){
|
||||||
AudioBuffer ab = (AudioBuffer) ad;
|
AudioBuffer ab = (AudioBuffer) ad;
|
||||||
int id = ab.getId();
|
int id = ab.getId();
|
||||||
if (id != -1){
|
if (id != -1){
|
||||||
ib.put(0,id);
|
ib.put(0,id);
|
||||||
ib.position(0).limit(1);
|
ib.position(0).limit(1);
|
||||||
alDeleteBuffers(ib);
|
alDeleteBuffers(ib);
|
||||||
ab.resetObject();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user