Audaspace:
authorJoerg Mueller <nexyon@gmail.com>
Sat, 31 Jul 2010 10:03:08 +0000 (10:03 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Sat, 31 Jul 2010 10:03:08 +0000 (10:03 +0000)
* Fixed some compiler warnings
* Implemented device looping
* Note: Scrubbing in the sequencer is broken atm

12 files changed:
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/OpenAL/AUD_OpenALDevice.h
intern/audaspace/Python/AUD_PyAPI.cpp
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
intern/audaspace/intern/AUD_IDevice.h
intern/audaspace/intern/AUD_NULLDevice.cpp
intern/audaspace/intern/AUD_NULLDevice.h
intern/audaspace/intern/AUD_SoftwareDevice.cpp
intern/audaspace/intern/AUD_SoftwareDevice.h
source/blender/blenkernel/intern/sound.c
source/gameengine/Ketsji/KX_SoundActuator.cpp

index 6d1f9a5527b27e8d43247f76afd89e1477113629..88e48ff20ba4b2371829c272edfd54469bc0da02 100644 (file)
@@ -65,6 +65,9 @@ struct AUD_OpenALHandle : AUD_Handle
 
        /// Whether the stream doesn't return any more data.
        bool data_end;
+
+       /// The loop count of the source.
+       int loopcount;
 };
 
 struct AUD_OpenALBufferedFactory
@@ -156,6 +159,18 @@ void AUD_OpenALDevice::updateStreams()
                                                                length = m_buffersize;
                                                                sound->reader->read(length, buffer);
 
+                                                               // looping necessary?
+                                                               if(length == 0 && sound->loopcount)
+                                                               {
+                                                                       if(sound->loopcount > 0)
+                                                                               sound->loopcount--;
+
+                                                                       sound->reader->seek(0);
+
+                                                                       length = m_buffersize;
+                                                                       sound->reader->read(length, buffer);
+                                                               }
+
                                                                // read nothing?
                                                                if(length == 0)
                                                                {
@@ -507,6 +522,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                                sound->current = -1;
                                sound->isBuffered = true;
                                sound->data_end = true;
+                               sound->loopcount = 0;
 
                                alcSuspendContext(m_context);
 
@@ -578,6 +594,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        sound->current = 0;
        sound->isBuffered = false;
        sound->data_end = false;
+       sound->loopcount = 0;
 
        valid &= getFormat(sound->format, specs.specs);
 
@@ -975,6 +992,26 @@ bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
        return result;
 }
 
+int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
+{
+       lock();
+       int result = 0;
+       if(isValid(handle))
+               result = ((AUD_OpenALHandle*)handle)->loopcount;
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               ((AUD_OpenALHandle*)handle)->loopcount = count;
+       unlock();
+       return result;
+}
+
 /* AUD_XXX Temorary disabled
 
 bool AUD_OpenALDevice::bufferFactory(void *value)
index cba031f25f96a8f1dd3a296d9779cb23391d9244..37a5b886882445b7acb588580f43fb84b1e2a1b4 100644 (file)
@@ -158,6 +158,8 @@ public:
        virtual bool setVolume(AUD_Handle* handle, float volume);
        virtual float getPitch(AUD_Handle* handle);
        virtual bool setPitch(AUD_Handle* handle, float pitch);
+       virtual int getLoopCount(AUD_Handle* handle);
+       virtual bool setLoopCount(AUD_Handle* handle, int count);
 
        virtual AUD_Vector3 getListenerLocation() const;
        virtual void setListenerLocation(const AUD_Vector3& location);
index 13617283a1ea0ac9ccec387523b7568d3d6055a8..dff7334e577073853b204910a26f24ea9d51cf7c 100644 (file)
@@ -1228,8 +1228,7 @@ Handle_get_loop_count(Handle *self, void* nothing)
 
        try
        {
-               // AUD_XXX will come soon; return Py_BuildValue("f", device->device->getPitch(self->handle));
-               AUD_THROW(AUD_ERROR_FACTORY);
+               return Py_BuildValue("i", device->device->getLoopCount(self->handle));
        }
        catch(AUD_Exception&)
        {
@@ -1250,14 +1249,8 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
 
        try
        {
-               /* AUD_XXX Doesn't work atm, will come back
-               AUD_Message message;
-               message.loopcount = loops;
-               message.type = AUD_MSG_LOOP;
-               if(device->device->sendMessage(self->handle, message))
-               {
+               if(device->device->setLoopCount(self->handle, loops))
                        return 0;
-               }*/
        }
        catch(AUD_Exception&)
        {
@@ -1302,7 +1295,7 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing)
        float x, y, z;
 
        if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
-               return NULL;
+               return -1;
 
        Device* dev = (Device*)self->device;
 
@@ -1361,7 +1354,7 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
        float x, y, z;
 
        if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
-               return NULL;
+               return -1;
 
        Device* dev = (Device*)self->device;
 
@@ -1420,7 +1413,7 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
        float w, x, y, z;
 
        if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
-               return NULL;
+               return -1;
 
        Device* dev = (Device*)self->device;
 
@@ -2368,7 +2361,7 @@ Device_set_listener_location(Device *self, PyObject* args, void* nothing)
        float x, y, z;
 
        if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
-               return NULL;
+               return -1;
 
        try
        {
@@ -2423,7 +2416,7 @@ Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
        float x, y, z;
 
        if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
-               return NULL;
+               return -1;
 
        try
        {
@@ -2478,7 +2471,7 @@ Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
        float w, x, y, z;
 
        if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z))
-               return NULL;
+               return -1;
 
        try
        {
index 1f9e76c4535a04690c92d9138fc6b2c3564f7cc0..5e0364c618c5eb1beddb39bf1dfedb470c26dfff 100644 (file)
@@ -344,24 +344,17 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
        }
 }
 
-int AUD_setLoop(AUD_Channel* handle, int loops, float time)
+int AUD_setLoop(AUD_Channel* handle, int loops)
 {
        if(handle)
        {
-               /* AUD_XXX Doesn't work atm, will come back
-
-               AUD_Message message;
-               message.type = AUD_MSG_LOOP;
-               message.loopcount = loops;
-               message.time = time;
-
                try
                {
-                       return AUD_device->sendMessage(handle, message);
+                       return AUD_device->setLoopCount(handle, loops);
                }
                catch(AUD_Exception&)
                {
-               }*/
+               }
        }
        return false;
 }
index 6b7f7c1a2ea89b51952c0466c334b293ff74e26a..f73e658d5b1d17158d78081ea0e47d87d5715478 100644 (file)
@@ -165,10 +165,9 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
  * Sets a remaining loop count of a looping sound that currently plays.
  * \param handle The playback handle.
  * \param loops The count of remaining loops, -1 for infinity.
- * \param time The time after which playback should stop, -1 for infinity.
  * \return Whether the handle is valid.
  */
-extern int AUD_setLoop(AUD_Channel* handle, int loops, float time);
+extern int AUD_setLoop(AUD_Channel* handle, int loops);
 
 /**
  * Rectifies a sound.
index 4170e27457462d12ae7f04db125c4fe52bb45552..bb2d65cde746d9577ced04d3b295b62cdfb95cc5 100644 (file)
@@ -207,6 +207,24 @@ public:
         *        - false if the handle is invalid.
         */
        virtual bool setPitch(AUD_Handle* handle, float pitch)=0;
+
+       /**
+        * Retrieves the loop count of a playing sound.
+        * A negative value indicates infinity.
+        * \return The remaining loop count.
+        */
+       virtual int getLoopCount(AUD_Handle* handle)=0;
+
+       /**
+        * Sets the loop count of a playing sound.
+        * A negative value indicates infinity.
+        * \param handle The sound handle.
+        * \param count The new loop count.
+        * \return
+        *        - true if the handle is valid.
+        *        - false if the handle is invalid.
+        */
+       virtual bool setLoopCount(AUD_Handle* handle, int count)=0;
 };
 
 #endif //AUD_IDevice
index aea2bf4ba6225c23ac791ab424cc85ea23f2e0de..ec9e02ef28f6f278d9a45af7b01f25ad8f264229 100644 (file)
@@ -123,3 +123,13 @@ bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch)
 {
        return false;
 }
+
+int AUD_NULLDevice::getLoopCount(AUD_Handle* handle)
+{
+       return 0;
+}
+
+bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count)
+{
+       return false;
+}
index 0f070da086368163b041a6335ed03a3586b826b1..c62618548033892048748b4e055ef8bc594bf6a9 100644 (file)
@@ -57,6 +57,8 @@ public:
        virtual bool setVolume(AUD_Handle* handle, float volume);
        virtual float getPitch(AUD_Handle* handle);
        virtual bool setPitch(AUD_Handle* handle, float pitch);
+       virtual int getLoopCount(AUD_Handle* handle);
+       virtual bool setLoopCount(AUD_Handle* handle, int count);
 };
 
 #endif //AUD_NULLDEVICE
index 8ef34f6659b00c4160791358571224407af393ac..1f063e636f15157969fb23ab6b9636c0b78aaac7 100644 (file)
@@ -42,14 +42,15 @@ struct AUD_SoftwareHandle : AUD_Handle
 
        /// The volume of the source.
        float volume;
+
+       /// The loop count of the source.
+       int loopcount;
 };
 
 typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
 
 void AUD_SoftwareDevice::create()
 {
-       m_playingSounds = new std::list<AUD_SoftwareHandle*>();
-       m_pausedSounds = new std::list<AUD_SoftwareHandle*>();
        m_playback = false;
        m_volume = 1.0f;
        m_mixer = new AUD_DefaultMixer(m_specs);
@@ -70,23 +71,25 @@ void AUD_SoftwareDevice::destroy()
 
        delete m_mixer;
 
+       AUD_SoftwareHandle* handle;
+
        // delete all playing sounds
-       while(m_playingSounds->begin() != m_playingSounds->end())
+       while(!m_playingSounds.empty())
        {
-               delete (*(m_playingSounds->begin()))->reader;
-               delete *(m_playingSounds->begin());
-               m_playingSounds->erase(m_playingSounds->begin());
+               handle = m_playingSounds.front();
+               m_playingSounds.pop_front();
+               delete handle->reader;
+               delete handle;
        }
-       delete m_playingSounds;
 
        // delete all paused sounds
-       while(m_pausedSounds->begin() != m_pausedSounds->end())
+       while(!m_pausedSounds.empty())
        {
-               delete (*(m_pausedSounds->begin()))->reader;
-               delete *(m_pausedSounds->begin());
-               m_pausedSounds->erase(m_pausedSounds->begin());
+               handle = m_pausedSounds.front();
+               m_pausedSounds.pop_front();
+               delete handle->reader;
+               delete handle;
        }
-       delete m_pausedSounds;
 
        pthread_mutex_destroy(&m_mutex);
 }
@@ -98,12 +101,16 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
        {
                AUD_SoftwareHandle* sound;
                int len;
+               int pos;
                sample_t* buf;
                std::list<AUD_SoftwareHandle*> stopSounds;
+               std::list<AUD_Buffer*> tempBufs;
+               AUD_Buffer* tempbuf;
+               int samplesize = AUD_SAMPLE_SIZE(m_specs);
 
                // for all sounds
-               AUD_HandleIterator it = m_playingSounds->begin();
-               while(it != m_playingSounds->end())
+               AUD_HandleIterator it = m_playingSounds.begin();
+               while(it != m_playingSounds.end())
                {
                        sound = *it;
                        // increment the iterator to make sure it's valid,
@@ -111,13 +118,38 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
                        ++it;
 
                        // get the buffer from the source
+                       pos = 0;
                        len = length;
                        sound->reader->read(len, buf);
 
-                       m_mixer->add(buf, 0, len, sound->volume);
+                       // in case of looping
+                       while(pos + len < length && sound->loopcount)
+                       {
+                               tempbuf = new AUD_Buffer(len * samplesize);
+                               memcpy(tempbuf->getBuffer(), buf, len * samplesize);
+                               tempBufs.push_back(tempbuf);
+                               m_mixer->add(tempbuf->getBuffer(), pos, len, sound->volume);
+
+                               pos += len;
+
+                               if(sound->loopcount > 0)
+                                       sound->loopcount--;
+
+                               sound->reader->seek(0);
+
+                               len = length - pos;
+                               sound->reader->read(len, buf);
+
+                               // prevent endless loop
+                               if(!len)
+                                       break;
+                       }
+
+                       m_mixer->add(buf, pos, len, sound->volume);
+                       pos += len;
 
                        // in case the end of the sound is reached
-                       if(len < length)
+                       if(pos < length)
                        {
                                if(sound->keep)
                                        pause(sound);
@@ -129,12 +161,20 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
                // superpose
                m_mixer->superpose(buffer, length, m_volume);
 
+               // cleanup
                while(!stopSounds.empty())
                {
                        sound = stopSounds.front();
                        stopSounds.pop_front();
                        stop(sound);
                }
+
+               while(!tempBufs.empty())
+               {
+                       tempbuf = tempBufs.front();
+                       tempBufs.pop_front();
+                       delete tempbuf;
+               }
        }
 
        unlock();
@@ -142,12 +182,12 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
 
 bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
 {
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
+       for(AUD_HandleIterator i = m_playingSounds.begin();
+               i != m_playingSounds.end(); i++)
                if(*i == handle)
                        return true;
-       for(AUD_HandleIterator i = m_pausedSounds->begin();
-               i != m_pausedSounds->end(); i++)
+       for(AUD_HandleIterator i = m_pausedSounds.begin();
+               i != m_pausedSounds.end(); i++)
                if(*i == handle)
                        return true;
        return false;
@@ -170,16 +210,15 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
        if(reader == NULL)
                return NULL;
 
-       AUD_Specs rs = reader->getSpecs();
-
        // play sound
        AUD_SoftwareHandle* sound = new AUD_SoftwareHandle;
        sound->keep = keep;
        sound->reader = reader;
        sound->volume = 1.0f;
+       sound->loopcount = 0;
 
        lock();
-       m_playingSounds->push_back(sound);
+       m_playingSounds.push_back(sound);
 
        if(!m_playback)
                playing(m_playback = true);
@@ -195,14 +234,14 @@ bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
        lock();
 
        // only songs that are played can be paused
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
+       for(AUD_HandleIterator i = m_playingSounds.begin();
+               i != m_playingSounds.end(); i++)
        {
                if(*i == handle)
                {
-                       m_pausedSounds->push_back(*i);
-                       m_playingSounds->erase(i);
-                       if(m_playingSounds->empty())
+                       m_pausedSounds.push_back(*i);
+                       m_playingSounds.erase(i);
+                       if(m_playingSounds.empty())
                                playing(m_playback = false);
                        result = true;
                        break;
@@ -221,13 +260,13 @@ bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
        lock();
 
        // only songs that are paused can be resumed
-       for(AUD_HandleIterator i = m_pausedSounds->begin();
-               i != m_pausedSounds->end(); i++)
+       for(AUD_HandleIterator i = m_pausedSounds.begin();
+               i != m_pausedSounds.end(); i++)
        {
                if(*i == handle)
                {
-                       m_playingSounds->push_back(*i);
-                       m_pausedSounds->erase(i);
+                       m_playingSounds.push_back(*i);
+                       m_pausedSounds.erase(i);
                        if(!m_playback)
                                playing(m_playback = true);
                        result = true;
@@ -246,15 +285,15 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
 
        lock();
 
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
+       for(AUD_HandleIterator i = m_playingSounds.begin();
+               i != m_playingSounds.end(); i++)
        {
                if(*i == handle)
                {
                        delete (*i)->reader;
                        delete *i;
-                       m_playingSounds->erase(i);
-                       if(m_playingSounds->empty())
+                       m_playingSounds.erase(i);
+                       if(m_playingSounds.empty())
                                playing(m_playback = false);
                        result = true;
                        break;
@@ -262,14 +301,14 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
        }
        if(!result)
        {
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
+               for(AUD_HandleIterator i = m_pausedSounds.begin();
+                       i != m_pausedSounds.end(); i++)
                {
                        if(*i == handle)
                        {
                                delete (*i)->reader;
                                delete *i;
-                               m_pausedSounds->erase(i);
+                               m_pausedSounds.erase(i);
                                result = true;
                                break;
                        }
@@ -353,8 +392,8 @@ AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
 
        lock();
 
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
+       for(AUD_HandleIterator i = m_playingSounds.begin();
+               i != m_playingSounds.end(); i++)
        {
                if(*i == handle)
                {
@@ -364,8 +403,8 @@ AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
        }
        if(status == AUD_STATUS_INVALID)
        {
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
+               for(AUD_HandleIterator i = m_pausedSounds.begin();
+                       i != m_pausedSounds.end(); i++)
                {
                        if(*i == handle)
                        {
@@ -429,3 +468,23 @@ bool AUD_SoftwareDevice::setPitch(AUD_Handle* handle, float pitch)
 {
        return false;
 }
+
+int AUD_SoftwareDevice::getLoopCount(AUD_Handle* handle)
+{
+       lock();
+       int result = 0;
+       if(isValid(handle))
+               result = ((AUD_SoftwareHandle*)handle)->loopcount;
+       unlock();
+       return result;
+}
+
+bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int count)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               ((AUD_SoftwareHandle*)handle)->loopcount = count;
+       unlock();
+       return result;
+}
index cd819d638a9499fcf43630a575ff3d864bff7bd0..c14b5356c6bd91fabf5836dea44a4a4a1c281bbf 100644 (file)
@@ -29,6 +29,7 @@
 #include "AUD_IDevice.h"
 struct AUD_SoftwareHandle;
 class AUD_Mixer;
+class AUD_Buffer;
 
 #include <list>
 #include <pthread.h>
@@ -81,12 +82,12 @@ private:
        /**
         * The list of sounds that are currently playing.
         */
-       std::list<AUD_SoftwareHandle*>* m_playingSounds;
+       std::list<AUD_SoftwareHandle*> m_playingSounds;
 
        /**
         * The list of sounds that are currently paused.
         */
-       std::list<AUD_SoftwareHandle*>* m_pausedSounds;
+       std::list<AUD_SoftwareHandle*> m_pausedSounds;
 
        /**
         * Whether there is currently playback.
@@ -129,6 +130,8 @@ public:
        virtual bool setVolume(AUD_Handle* handle, float volume);
        virtual float getPitch(AUD_Handle* handle);
        virtual bool setPitch(AUD_Handle* handle, float pitch);
+       virtual int getLoopCount(AUD_Handle* handle);
+       virtual bool setLoopCount(AUD_Handle* handle, int count);
 };
 
 #endif //AUD_SOFTWAREDEVICE
index ca39355976bb929c8188ba947f474312f2c469a2..17ff6615ee735b8a85074aa8ea031b01ec469d97 100644 (file)
@@ -381,10 +381,8 @@ void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, i
 
 void sound_start_play_scene(struct Scene *scene)
 {
-       AUD_Sound* sound;
-       sound = AUD_loopSound(scene->sound_scene);
-       scene->sound_scene_handle = AUD_play(sound, 1);
-       AUD_unload(sound);
+       scene->sound_scene_handle = AUD_play(scene->sound_scene, 1);
+       AUD_setLoop(scene->sound_scene_handle, -1);
 }
 
 void sound_play_scene(struct Scene *scene)
@@ -397,8 +395,6 @@ void sound_play_scene(struct Scene *scene)
        if(status == AUD_STATUS_INVALID)
                sound_start_play_scene(scene);
 
-       AUD_setLoop(scene->sound_scene_handle, -1, -1);
-
        if(status != AUD_STATUS_PLAYING)
        {
                AUD_seek(scene->sound_scene_handle, CFRA / FPS);
@@ -436,7 +432,7 @@ void sound_seek_scene(struct bContext *C)
 
        if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
        {
-               AUD_setLoop(scene->sound_scene_handle, -1, 1 / FPS);
+               // AUD_XXX TODO: fix scrubbing, it currently doesn't stop playing
                if(scene->audio.flag & AUDIO_SYNC)
                        AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
                else
index c3ef36dfe11a8c42472f89599f5deb939b09f1fe..09ad567117f1759959b0750552d427e4b018a759 100644 (file)
@@ -76,23 +76,20 @@ void KX_SoundActuator::play()
 
        // this is the sound that will be played and not deleted afterwards
        AUD_Sound* sound = m_sound;
-       // this sounds are for temporary stacked sounds, will be deleted if not NULL
+       // this sound is for temporary stacked sounds, will be deleted if not NULL
        AUD_Sound* sound2 = NULL;
-       AUD_Sound* sound3 = NULL;
+
+       bool loop = false;
 
        switch (m_type)
        {
        case KX_SOUNDACT_LOOPBIDIRECTIONAL:
        case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
-               // create a ping pong sound on sound2 stacked on the orignal sound
-               sound2 = AUD_pingpongSound(sound);
-               // create a loop sound on sound3 stacked on the pingpong sound and let that one play (save it to sound)
-               sound = sound3 = AUD_loopSound(sound2);
-               break;
+               sound = sound2 = AUD_pingpongSound(sound);
+               // fall through
        case KX_SOUNDACT_LOOPEND:
        case KX_SOUNDACT_LOOPSTOP:
-               // create a loop sound on sound2 stacked on the pingpong sound and let that one play (save it to sound)
-               sound = sound2 = AUD_loopSound(sound);
+               loop = true;
                break;
        case KX_SOUNDACT_PLAYSTOP:
        case KX_SOUNDACT_PLAYEND:
@@ -118,14 +115,12 @@ void KX_SoundActuator::play()
        else
                m_handle = AUD_play(sound, 0);
 
+       if(loop)
+               AUD_setLoop(m_handle, -1);
        AUD_setSoundPitch(m_handle, m_pitch);
        AUD_setSoundVolume(m_handle, m_volume);
        m_isplaying = true;
 
-       // now we unload the pingpong and loop sounds, as we don't need them anymore
-       // the started sound will continue playing like it was created, don't worry!
-       if(sound3)
-               AUD_unload(sound3);
        if(sound2)
                AUD_unload(sound2);
 }
@@ -185,7 +180,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
                        case KX_SOUNDACT_LOOPBIDIRECTIONAL:
                                {
                                        // stop the looping so that the sound stops when it finished
-                                       AUD_setLoop(m_handle, 0, -1);
+                                       AUD_setLoop(m_handle, 0);
                                        break;
                                }
                        default: