@ -299,6 +299,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 ;
int id = channels [ src . getChannel ( ) ] ;
int id = channels [ src . getChannel ( ) ] ;
@ -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 ( ) ) ;
}
}
}
}
}
}
}
@ -974,6 +1002,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
public void deleteAudioData ( AudioData ad ) {
public void deleteAudioData ( AudioData ad ) {
synchronized ( threadLock ) {
while ( ! threadLock . get ( ) ) {
try {
threadLock . wait ( ) ;
} catch ( InterruptedException ex ) {
}
}
if ( audioDisabled )
if ( audioDisabled )
return ;
return ;
@ -997,5 +1032,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
}
}
}
}
}
}
}