Slick Forums

Discuss the Slick 2D Library
It is currently Fri Aug 17, 2018 9:18 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Thu Jan 17, 2013 7:51 pm 
Offline

Joined: Thu Apr 21, 2011 2:32 pm
Posts: 45
Hi,

For a current project, I needed to be able to loop some sound effect while changing pitch and pos. I also need the possibility to play a single source twice while keeping the ability to access the different 'playing' instances.

The actual Audio interface was close to what i needed. It already returned the source when playing, but lacked exposed function to access different ones. Also sounds can't be modified while playing.

The following patches implements those features.
First the audio interface is given the stop(int idx) and isPlaying(int idx) methods to access specific sources. modify() methods are also added to change playing sounds.
Audio.java wrote:
Code:
# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -13,6 +13,8 @@
     */
    public void stop();
 
+    public void stop(int index);
+
    /**
     * Get the ID of the OpenAL buffer holding this data (if any). This method
     * is not valid with streaming resources.
@@ -28,6 +30,12 @@
     */
    public boolean isPlaying();
 
+    public boolean isPlaying(int idx);
+
+    public void modify(float pitch, float gain, float x, float y, float z);
+
+    public void modify(int idx, float pitch, float gain, float x, float y, float z);
+
    /**
     * Play this sound as a sound effect
     *



Implementations in NullAudio and AudioImpl:
NullAudio.java wrote:
Code:
# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -1,12 +1,13 @@
 package org.newdawn.slick.openal;
 
 /**
- * A null implementation used to provide an object reference when sound
- * has failed.
+ * A null implementation used to provide an object reference when sound has
+ * failed.
  *
  * @author kevin
  */
 public class NullAudio implements Audio {
+
    /**
     * @see org.newdawn.slick.openal.Audio#getBufferID()
     */
@@ -36,14 +37,16 @@
    }
 
    /**
-    * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean)
+     * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float,
+     * boolean)
     */
    public int playAsSoundEffect(float pitch, float gain, boolean loop) {
       return 0;
    }
 
    /**
-    * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean, float, float, float)
+     * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float,
+     * boolean, float, float, float)
     */
    public int playAsSoundEffect(float pitch, float gain, boolean loop,
          float x, float y, float z) {
@@ -63,4 +66,20 @@
    public void stop() {
    }
 
+    @Override
+    public void stop(int index) {
 }
+
+    @Override
+    public boolean isPlaying(int idx) {
+        return false;
+    }
+
+    @Override
+    public void modify(float pitch, float gain, float x, float y, float z) {
+    }
+
+    @Override
+    public void modify(int idx, float pitch, float gain, float x, float y, float z) {
+    }
+}



AudioImpl.java wrote:
Code:

# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -10,14 +10,22 @@
  * @author Nathan Sweet <misc@n4te.com>
  */
 public class AudioImpl implements Audio {
   /** The store from which this sound was loaded */
    private SoundStore store;
   /** The buffer containing the sound */
    private int buffer;
   /** The index of the source being used to play this sound */
    private int index = -1;
-   
   /** The length of the audio */
    private float length;
    
    /**
@@ -53,45 +61,64 @@
     *
     */
    protected AudioImpl() {
-      
    }
    
    /**
     * @see org.newdawn.slick.openal.Audio#stop()
     */
    public void stop() {
-      if (index != -1) {
-         store.stopSource(index);
+        stop(index);
          index = -1;
       }
+
+    public void stop(int idx) {
+        if (idx != -1) {
+            store.stopSource(idx);
    }
+    }
    
    /**
     * @see org.newdawn.slick.openal.Audio#isPlaying()
     */
    public boolean isPlaying() {
-      if (index != -1) {
          return store.isPlaying(index);
       }
       
+    public boolean isPlaying(int idx) {
+        if (idx != -1) {
+            return store.isPlaying(idx);
+        }
+
       return false;
    }
    
+    public void modify(float pitch, float gain, float x, float y, float z) {
+        modify(index, pitch, gain, x, y, z);
+    }
+
+    public void modify(int idx, float pitch, float gain, float x, float y, float z) {
+        if (idx != -1) {
+            store.modify(idx, pitch, gain, x, y, z);
+        }
+    }
+
    /**
    * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean)
     */
    public int playAsSoundEffect(float pitch, float gain, boolean loop) {
       index = store.playAsSound(buffer, pitch, gain, loop);
-      return store.getSource(index);
+        return index;
    }
 
    /**
    * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean, float, float, float)
     */
    public int playAsSoundEffect(float pitch, float gain, boolean loop, float x, float y, float z) {
       index = store.playAsSoundAt(buffer, pitch, gain, loop, x, y, z);
-      return store.getSource(index);
+        return index;
    }
    
    /**
@@ -100,7 +127,7 @@
    public int playAsMusic(float pitch, float gain, boolean loop) {
       store.playAsMusic(buffer, pitch, gain, loop);
       index = 0;
-      return store.getSource(0);
+        return 0;
    }
    
    /**




The SoundStore class implements the modify function :

SoundStore wrote:
Code:
 public void modify(int source, float pitch, float gain, float x, float y, float z) {
+        int state = AL10.alGetSourcei(sources.get(source), AL10.AL_SOURCE_STATE);
+
+        if (state != AL10.AL_PLAYING && state != AL10.AL_PAUSED) {
+            return;
+        }
+        AL10.alSourcef(sources.get(source), AL10.AL_PITCH, pitch);
+        AL10.alSourcef(sources.get(source), AL10.AL_GAIN, gain);
+
+        sourcePos.clear();
+        sourceVel.clear();
+        sourceVel.put(new float[]{0, 0, 0});
+        sourcePos.put(new float[]{x, y, z});
+        sourcePos.flip();
+        sourceVel.flip();
+        AL10.alSource(sources.get(source), AL10.AL_POSITION, sourcePos);
+        AL10.alSource(sources.get(source), AL10.AL_VELOCITY, sourceVel);
+    }


This allow the Sound class - or any other class with an Audio instance - to loop the same sound several times and modify its parameters, pitch gain and pos, for each looping instance separately. This can easily be implemented in the Sound class by keeping a map of user Object keys and openal sources indexes. If a key is passed by the method call, act on the source index contained in the map. Else, use the null key.

Thanks for your time and feedback,
Charly

Edit: A note concerning the return value of the play functions in AudioImpl : The sound store functions use sources indexes (i.e it calls sources.get(index) iteself), and since I found no use of that return value in the API, i changed it to return the simple index, so that it can be passed to other soundstore functions.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group