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