Explorar el Código

- add generic AudioSource to abstract audio system away from AudioNode

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10416 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
nor..67 hace 12 años
padre
commit
22eb83fd9a

+ 12 - 6
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 {
 
     /**
      * <code>Status</code> 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.
      * 

+ 6 - 6
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);

+ 189 - 0
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 {
+        /**
+     * <code>Status</code> 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 <code>AudioSource</code> 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();
+
+}

+ 27 - 27
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<Integer> freeChans = new ArrayList<Integer>();
     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);

+ 23 - 23
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<Integer> freeChans = new ArrayList<Integer>();
     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<Integer> channelList = new ArrayList<Integer>();
@@ -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 {