diff --git a/engine/src/core/com/jme3/audio/AudioNode.java b/engine/src/core/com/jme3/audio/AudioNode.java
index 64bdfdb5c..5ee74dbd5 100644
--- a/engine/src/core/com/jme3/audio/AudioNode.java
+++ b/engine/src/core/com/jme3/audio/AudioNode.java
@@ -60,7 +60,7 @@ import java.util.logging.Logger;
* @author normenhansen
* @author Kirill Vainer
*/
-public class AudioNode extends Node {
+public class AudioNode extends Node implements AudioSource {
//Version #1 : AudioKey is now stored into "audio_key" instead of "key"
public static final int SAVABLE_VERSION = 1;
@@ -71,7 +71,7 @@ public class AudioNode extends Node {
protected Filter dryFilter;
protected AudioKey audioKey;
protected transient AudioData data = null;
- protected transient volatile Status status = Status.Stopped;
+ protected transient volatile AudioSource.Status status = AudioSource.Status.Stopped;
protected transient volatile int channel = -1;
protected Vector3f velocity = new Vector3f();
protected boolean reverbEnabled = true;
@@ -86,7 +86,9 @@ public class AudioNode extends Node {
/**
* Status
indicates the current status of the audio node.
+ * @deprecated - use AudioSource.Status instead
*/
+ @Deprecated
public enum Status {
/**
* The audio node is currently playing. This will be set if
@@ -223,7 +225,7 @@ public class AudioNode extends Node {
* Do not use.
*/
public final void setChannel(int channel) {
- if (status != Status.Stopped) {
+ if (status != AudioSource.Status.Stopped) {
throw new IllegalStateException("Can only set source id when stopped");
}
@@ -294,14 +296,14 @@ public class AudioNode extends Node {
* The status will be changed when either the {@link AudioNode#play() }
* or {@link AudioNode#stop() } methods are called.
*/
- public Status getStatus() {
+ public AudioSource.Status getStatus() {
return status;
}
/**
* Do not use.
*/
- public final void setStatus(Status status) {
+ public final void setStatus(AudioSource.Status status) {
this.status = status;
}
@@ -399,12 +401,16 @@ public class AudioNode extends Node {
this.timeOffset = timeOffset;
if (data instanceof AudioStream) {
((AudioStream) data).setTime(timeOffset);
- }else if(status == Status.Playing){
+ }else if(status == AudioSource.Status.Playing){
stop();
play();
}
}
+ public Vector3f getPosition() {
+ return getWorldTranslation();
+ }
+
/**
* @return The velocity of the audio node.
*
diff --git a/engine/src/core/com/jme3/audio/AudioRenderer.java b/engine/src/core/com/jme3/audio/AudioRenderer.java
index 5e47e0bb3..ee15bf77e 100644
--- a/engine/src/core/com/jme3/audio/AudioRenderer.java
+++ b/engine/src/core/com/jme3/audio/AudioRenderer.java
@@ -47,17 +47,17 @@ public interface AudioRenderer {
/**
* Sets the environment, used for reverb effects.
*
- * @see AudioNode#setReverbEnabled(boolean)
+ * @see AudioSource#setReverbEnabled(boolean)
* @param env The environment to set.
*/
public void setEnvironment(Environment env);
- public void playSourceInstance(AudioNode src);
- public void playSource(AudioNode src);
- public void pauseSource(AudioNode src);
- public void stopSource(AudioNode src);
+ public void playSourceInstance(AudioSource src);
+ public void playSource(AudioSource src);
+ public void pauseSource(AudioSource src);
+ public void stopSource(AudioSource src);
- public void updateSourceParam(AudioNode src, AudioParam param);
+ public void updateSourceParam(AudioSource src, AudioParam param);
public void updateListenerParam(Listener listener, ListenerParam param);
public void deleteFilter(Filter filter);
diff --git a/engine/src/core/com/jme3/audio/AudioSource.java b/engine/src/core/com/jme3/audio/AudioSource.java
new file mode 100644
index 000000000..a5fdd94cc
--- /dev/null
+++ b/engine/src/core/com/jme3/audio/AudioSource.java
@@ -0,0 +1,189 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.audio;
+
+import com.jme3.math.Vector3f;
+
+/**
+ *
+ * @author normenhansen
+ */
+public interface AudioSource {
+ /**
+ * Status
indicates the current status of the audio source.
+ */
+ public enum Status {
+ /**
+ * The audio source is currently playing. This will be set if
+ * {@link AudioSource#play() } is called.
+ */
+ Playing,
+
+ /**
+ * The audio source is currently paused.
+ */
+ Paused,
+
+ /**
+ * The audio source is currently stopped.
+ * This will be set if {@link AudioSource#stop() } is called
+ * or the audio has reached the end of the file.
+ */
+ Stopped,
+ }
+
+
+ /**
+ * Do not use.
+ */
+ public void setChannel(int channel);
+
+ /**
+ * Do not use.
+ */
+ public int getChannel();
+
+ /**
+ * Start playing the audio.
+ */
+ public void play();
+
+ /**
+ * Start playing an instance of this audio. This method can be used
+ * to play the same AudioSource
multiple times. Note
+ * that changes to the parameters of this AudioSource will not effect the
+ * instances already playing.
+ */
+ public void playInstance();
+
+ /**
+ * @return The {#link Filter dry filter} that is set.
+ * @see AudioSource#setDryFilter(com.jme3.audio.Filter)
+ */
+ public Filter getDryFilter();
+
+ /**
+ * @return The {@link AudioData} set previously with
+ * {@link AudioSource#setAudioData(com.jme3.audio.AudioData, com.jme3.audio.AudioKey) }
+ * or any of the constructors that initialize the audio data.
+ */
+ public AudioData getAudioData();
+
+ /**
+ * Do not use.
+ */
+ public void setStatus(Status status);
+
+ /**
+ * @return The {@link Status} of the audio source.
+ * The status will be changed when either the {@link AudioSource#play() }
+ * or {@link AudioSource#stop() } methods are called.
+ */
+ public Status getStatus();
+
+ /**
+ * @return True if the audio will keep looping after it is done playing,
+ * otherwise, false.
+ * @see AudioSource#setLooping(boolean)
+ */
+ public boolean isLooping();
+
+ /**
+ * @return The pitch of the audio, also the speed of playback.
+ *
+ * @see AudioSource#setPitch(float)
+ */
+ public float getPitch();
+
+ /**
+ * @return The volume of this audio source.
+ *
+ * @see AudioSource#setVolume(float)
+ */
+ public float getVolume();
+
+ /**
+ * @return the time offset in the sound sample when to start playing.
+ */
+ public float getTimeOffset();
+
+ /**
+ * @return The velocity of the audio source.
+ *
+ * @see AudioSource#setVelocity(com.jme3.math.Vector3f)
+ */
+ public Vector3f getPosition();
+
+ /**
+ * @return The velocity of the audio source.
+ *
+ * @see AudioSource#setVelocity(com.jme3.math.Vector3f)
+ */
+ public Vector3f getVelocity();
+
+ /**
+ * @return True if reverb is enabled, otherwise false.
+ *
+ * @see AudioSource#setReverbEnabled(boolean)
+ */
+ public boolean isReverbEnabled();
+
+ /**
+ * @return Filter for the reverberations of this audio source.
+ *
+ * @see AudioSource#setReverbFilter(com.jme3.audio.Filter)
+ */
+ public Filter getReverbFilter();
+
+ /**
+ * @return Max distance for this audio source.
+ *
+ * @see AudioSource#setMaxDistance(float)
+ */
+ public float getMaxDistance();
+
+ /**
+ * @return The reference playing distance for the audio source.
+ *
+ * @see AudioSource#setRefDistance(float)
+ */
+ public float getRefDistance();
+
+ /**
+ * @return True if the audio source is directional
+ *
+ * @see AudioSource#setDirectional(boolean)
+ */
+ public boolean isDirectional();
+
+ /**
+ * @return The direction of this audio source.
+ *
+ * @see AudioSource#setDirection(com.jme3.math.Vector3f)
+ */
+ public Vector3f getDirection();
+
+ /**
+ * @return The directional audio source, cone inner angle.
+ *
+ * @see AudioSource#setInnerAngle(float)
+ */
+ public float getInnerAngle();
+
+ /**
+ * @return The directional audio source, cone outer angle.
+ *
+ * @see AudioSource#setOuterAngle(float)
+ */
+ public float getOuterAngle();
+
+ /**
+ * @return True if the audio source is positional.
+ *
+ * @see AudioSource#setPositional(boolean)
+ */
+ public boolean isPositional();
+
+}
diff --git a/engine/src/jogl/com/jme3/audio/joal/JoalAudioRenderer.java b/engine/src/jogl/com/jme3/audio/joal/JoalAudioRenderer.java
index b89d626bd..77bcdbed5 100644
--- a/engine/src/jogl/com/jme3/audio/joal/JoalAudioRenderer.java
+++ b/engine/src/jogl/com/jme3/audio/joal/JoalAudioRenderer.java
@@ -31,7 +31,7 @@
*/
package com.jme3.audio.joal;
-import com.jme3.audio.AudioNode.Status;
+import com.jme3.audio.AudioSource.Status;
import com.jme3.audio.*;
import com.jme3.math.Vector3f;
import com.jme3.util.BufferUtils;
@@ -61,7 +61,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
private final ByteBuffer nativeBuf = BufferUtils.createByteBuffer(BUFFER_SIZE);
private final byte[] arrayBuf = new byte[BUFFER_SIZE];
private int[] channels;
- private AudioNode[] chanSrcs;
+ private AudioSource[] chanSrcs;
private int nextChan = 0;
private ArrayList freeChans = new ArrayList();
private Listener listener;
@@ -194,7 +194,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
ib = BufferUtils.createIntBuffer(channels.length);
- chanSrcs = new AudioNode[channels.length];
+ chanSrcs = new AudioSource[channels.length];
logger.log(Level.FINE, "AudioRenderer supports {0} channels", channels.length);
@@ -308,7 +308,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
f.clearUpdateNeeded();
}
- public void updateSourceParam(AudioNode src, AudioParam param) {
+ public void updateSourceParam(AudioSource src, AudioParam param) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -321,10 +321,10 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
return;
}
- // There is a race condition in AudioNode that can
+ // There is a race condition in AudioSource 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
+ // called from the render thread may see that that AudioSource
// still has a channel value but the audio thread may
// clear that channel before setVolume() gets to call
// updateSourceParam() (because the audio stopped playing
@@ -343,7 +343,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
return;
}
- Vector3f pos = src.getWorldTranslation();
+ Vector3f pos = src.getPosition();
al.alSource3f(id, ALConstants.AL_POSITION, pos.x, pos.y, pos.z);
break;
case Velocity:
@@ -482,9 +482,9 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
}
- private void setSourceParams(int id, AudioNode src, boolean forceNonLoop) {
+ private void setSourceParams(int id, AudioSource src, boolean forceNonLoop) {
if (src.isPositional()) {
- Vector3f pos = src.getWorldTranslation();
+ Vector3f pos = src.getPosition();
Vector3f vel = src.getVelocity();
al.alSource3f(id, ALConstants.AL_POSITION, pos.x, pos.y, pos.z);
al.alSource3f(id, ALConstants.AL_VELOCITY, vel.x, vel.y, vel.z);
@@ -731,7 +731,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
private void clearChannel(int index) {
// make room at this channel
if (chanSrcs[index] != null) {
- AudioNode src = chanSrcs[index];
+ AudioSource src = chanSrcs[index];
int sourceId = channels[index];
al.alSourceStop(sourceId);
@@ -750,7 +750,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
al.alSourcei(sourceId, AL.AL_DIRECT_FILTER, AL.AL_FILTER_NULL);
}
if (src.isPositional()) {
- AudioNode pas = (AudioNode) src;
+ AudioSource pas = (AudioSource) src;
if (pas.isReverbEnabled() && supportEfx) {
al.alSource3i(sourceId, AL.AL_AUXILIARY_SEND_FILTER, 0, 0, AL.AL_FILTER_NULL);
}
@@ -770,7 +770,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
for (int i = 0; i < channels.length; i++) {
- AudioNode src = chanSrcs[i];
+ AudioSource src = chanSrcs[i];
if (src == null) {
continue;
}
@@ -790,7 +790,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
ib.position(0).limit(1);
al.alGetSourcei(sourceId, AL.AL_SOURCE_STATE, ib);
int state = ib.get(0);
- boolean wantPlaying = src.getStatus() == AudioNode.Status.Playing;
+ boolean wantPlaying = src.getStatus() == AudioSource.Status.Playing;
boolean stopped = state == ALConstants.AL_STOPPED;
if (streaming && wantPlaying) {
@@ -803,7 +803,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
} else {
if (stopped) {
// became inactive
- src.setStatus(AudioNode.Status.Stopped);
+ src.setStatus(AudioSource.Status.Stopped);
src.setChannel(-1);
clearChannel(i);
freeChannel(i);
@@ -817,11 +817,11 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
boolean paused = state == ALConstants.AL_PAUSED;
// make sure OAL pause state & source state coincide
- assert (src.getStatus() == AudioNode.Status.Paused && paused) || (!paused);
+ assert (src.getStatus() == AudioSource.Status.Paused && paused) || (!paused);
if (stopped) {
if (boundSource) {
- src.setStatus(AudioNode.Status.Stopped);
+ src.setStatus(AudioSource.Status.Stopped);
src.setChannel(-1);
}
clearChannel(i);
@@ -859,7 +859,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void playSourceInstance(AudioNode src) {
+ public void playSourceInstance(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -902,7 +902,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void playSource(AudioNode src) {
+ public void playSource(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -917,9 +917,9 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
//assert src.getStatus() == Status.Stopped || src.getChannel() == -1;
- if (src.getStatus() == AudioNode.Status.Playing) {
+ if (src.getStatus() == AudioSource.Status.Playing) {
return;
- } else if (src.getStatus() == AudioNode.Status.Stopped) {
+ } else if (src.getStatus() == AudioSource.Status.Stopped) {
// allocate channel to this source
int index = newChannel();
@@ -941,11 +941,11 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
}
al.alSourcePlay(channels[src.getChannel()]);
- src.setStatus(AudioNode.Status.Playing);
+ src.setStatus(AudioSource.Status.Playing);
}
}
- public void pauseSource(AudioNode src) {
+ public void pauseSource(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -958,16 +958,16 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
return;
}
- if (src.getStatus() == AudioNode.Status.Playing) {
+ if (src.getStatus() == AudioSource.Status.Playing) {
assert src.getChannel() != -1;
al.alSourcePause(channels[src.getChannel()]);
- src.setStatus(AudioNode.Status.Paused);
+ src.setStatus(AudioSource.Status.Paused);
}
}
}
- public void stopSource(AudioNode src) {
+ public void stopSource(AudioSource src) {
synchronized (threadLock) {
while (!threadLock.get()) {
try {
@@ -979,11 +979,11 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
return;
}
- if (src.getStatus() != AudioNode.Status.Stopped) {
+ if (src.getStatus() != AudioSource.Status.Stopped) {
int chan = src.getChannel();
assert chan != -1; // if it's not stopped, must have id
- src.setStatus(AudioNode.Status.Stopped);
+ src.setStatus(AudioSource.Status.Stopped);
src.setChannel(-1);
clearChannel(chan);
freeChannel(chan);
diff --git a/engine/src/lwjgl/com/jme3/audio/lwjgl/LwjglAudioRenderer.java b/engine/src/lwjgl/com/jme3/audio/lwjgl/LwjglAudioRenderer.java
index e995ae609..4d80b3b8f 100644
--- a/engine/src/lwjgl/com/jme3/audio/lwjgl/LwjglAudioRenderer.java
+++ b/engine/src/lwjgl/com/jme3/audio/lwjgl/LwjglAudioRenderer.java
@@ -31,7 +31,7 @@
*/
package com.jme3.audio.lwjgl;
-import com.jme3.audio.AudioNode.Status;
+import com.jme3.audio.AudioSource.Status;
import com.jme3.audio.*;
import com.jme3.math.Vector3f;
import com.jme3.util.BufferUtils;
@@ -61,7 +61,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
private final ByteBuffer nativeBuf = BufferUtils.createByteBuffer(BUFFER_SIZE);
private final byte[] arrayBuf = new byte[BUFFER_SIZE];
private int[] channels;
- private AudioNode[] chanSrcs;
+ private AudioSource[] chanSrcs;
private int nextChan = 0;
private ArrayList freeChans = new ArrayList();
private Listener listener;
@@ -156,10 +156,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
ALCdevice device = AL.getDevice();
String deviceName = ALC10.alcGetString(device, ALC10.ALC_DEVICE_SPECIFIER);
- logger.log(Level.FINER, "Audio Device: {0}", deviceName);
- logger.log(Level.FINER, "Audio Vendor: {0}", alGetString(AL_VENDOR));
- logger.log(Level.FINER, "Audio Renderer: {0}", alGetString(AL_RENDERER));
- logger.log(Level.FINER, "Audio Version: {0}", alGetString(AL_VERSION));
+ logger.log(Level.INFO, "Audio Device: {0}", deviceName);
+ logger.log(Level.INFO, "Audio Vendor: {0}", alGetString(AL_VENDOR));
+ logger.log(Level.INFO, "Audio Renderer: {0}", alGetString(AL_RENDERER));
+ logger.log(Level.INFO, "Audio Version: {0}", alGetString(AL_VERSION));
// Find maximum # of sources supported by this implementation
ArrayList channelList = new ArrayList();
@@ -178,9 +178,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
ib = BufferUtils.createIntBuffer(channels.length);
- chanSrcs = new AudioNode[channels.length];
+ chanSrcs = new AudioSource[channels.length];
- logger.log(Level.FINE, "AudioRenderer supports {0} channels", channels.length);
+ logger.log(Level.INFO, "AudioRenderer supports {0} channels", channels.length);
supportEfx = ALC10.alcIsExtensionPresent(device, "ALC_EXT_EFX");
if (supportEfx) {
@@ -190,11 +190,11 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
ib.position(0).limit(1);
ALC10.alcGetInteger(device, EFX10.ALC_EFX_MINOR_VERSION, ib);
int minor = ib.get(0);
- logger.log(Level.FINE, "Audio effect extension version: {0}.{1}", new Object[]{major, minor});
+ logger.log(Level.INFO, "Audio effect extension version: {0}.{1}", new Object[]{major, minor});
ALC10.alcGetInteger(device, EFX10.ALC_MAX_AUXILIARY_SENDS, ib);
auxSends = ib.get(0);
- logger.log(Level.FINE, "Audio max auxilary sends: {0}", auxSends);
+ logger.log(Level.INFO, "Audio max auxilary sends: {0}", auxSends);
// create slot
ib.position(0).limit(1);
@@ -282,7 +282,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
f.clearUpdateNeeded();
}
- public void updateSourceParam(AudioNode src, AudioParam param) {
+ public void updateSourceParam(AudioSource src, AudioParam param) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -295,10 +295,10 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
return;
}
- // There is a race condition in AudioNode that can
+ // There is a race condition in AudioSource 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
+ // called from the render thread may see that that AudioSource
// still has a channel value but the audio thread may
// clear that channel before setVolume() gets to call
// updateSourceParam() (because the audio stopped playing
@@ -317,7 +317,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
return;
}
- Vector3f pos = src.getWorldTranslation();
+ Vector3f pos = src.getPosition();
alSource3f(id, AL_POSITION, pos.x, pos.y, pos.z);
break;
case Velocity:
@@ -456,9 +456,9 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
- private void setSourceParams(int id, AudioNode src, boolean forceNonLoop) {
+ private void setSourceParams(int id, AudioSource src, boolean forceNonLoop) {
if (src.isPositional()) {
- Vector3f pos = src.getWorldTranslation();
+ Vector3f pos = src.getPosition();
Vector3f vel = src.getVelocity();
alSource3f(id, AL_POSITION, pos.x, pos.y, pos.z);
alSource3f(id, AL_VELOCITY, vel.x, vel.y, vel.z);
@@ -704,7 +704,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
private void clearChannel(int index) {
// make room at this channel
if (chanSrcs[index] != null) {
- AudioNode src = chanSrcs[index];
+ AudioSource src = chanSrcs[index];
int sourceId = channels[index];
alSourceStop(sourceId);
@@ -723,7 +723,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
alSourcei(sourceId, EFX10.AL_DIRECT_FILTER, EFX10.AL_FILTER_NULL);
}
if (src.isPositional()) {
- AudioNode pas = (AudioNode) src;
+ AudioSource pas = (AudioSource) src;
if (pas.isReverbEnabled() && supportEfx) {
AL11.alSource3i(sourceId, EFX10.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX10.AL_FILTER_NULL);
}
@@ -743,7 +743,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
for (int i = 0; i < channels.length; i++) {
- AudioNode src = chanSrcs[i];
+ AudioSource src = chanSrcs[i];
if (src == null) {
continue;
}
@@ -830,7 +830,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void playSourceInstance(AudioNode src) {
+ public void playSourceInstance(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -873,7 +873,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void playSource(AudioNode src) {
+ public void playSource(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -916,7 +916,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void pauseSource(AudioNode src) {
+ public void pauseSource(AudioSource src) {
checkDead();
synchronized (threadLock) {
while (!threadLock.get()) {
@@ -938,7 +938,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
}
}
- public void stopSource(AudioNode src) {
+ public void stopSource(AudioSource src) {
synchronized (threadLock) {
while (!threadLock.get()) {
try {