Adding a new state for sound handles in audaspace: stopped.
authorJoerg Mueller <nexyon@gmail.com>
Wed, 14 Aug 2013 21:21:00 +0000 (21:21 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Wed, 14 Aug 2013 21:21:00 +0000 (21:21 +0000)
Now sounds that stopped playing but are still kept in the device can be differentiated from paused sounds with this state.
This should also fix the performance issues mentioned in [#36466] End of SequencerEntrys not set correctly.
Please test if sound pausing, resuming and stopping works fine in the BGE and sequencer, my tests all worked fine, but there might be a use case that needs some fixing.

intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/OpenAL/AUD_OpenALDevice.h
intern/audaspace/Python/AUD_PyAPI.cpp
intern/audaspace/intern/AUD_IHandle.h
intern/audaspace/intern/AUD_SoftwareDevice.cpp
intern/audaspace/intern/AUD_SoftwareDevice.h
intern/audaspace/intern/AUD_Space.h
source/gameengine/Ketsji/KX_SoundActuator.cpp

index 371e0007bd31303e1768768a34e29d429beb3b77..676a86e88fe21f7128b58dd04425abf9ec8ae29f 100644 (file)
@@ -67,6 +67,35 @@ static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
 static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
                                                                          "filled with data.";
 
+bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
+{
+       if(m_status)
+       {
+               AUD_MutexLock lock(*m_device);
+
+               if(m_status == AUD_STATUS_PLAYING)
+               {
+                       for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+                       {
+                               if(it->get() == this)
+                               {
+                                       boost::shared_ptr<AUD_OpenALHandle> This = *it;
+
+                                       m_device->m_playingSounds.erase(it);
+                                       m_device->m_pausedSounds.push_back(This);
+
+                                       alSourcePause(m_source);
+
+                                       m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
+
+                                       return true;
+                               }
+                       }
+               }
+       }
+
+       return false;}
+
 AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
        m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
        m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
@@ -124,32 +153,7 @@ AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, A
 
 bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
 {
-       if(m_status)
-       {
-               AUD_MutexLock lock(*m_device);
-
-               if(m_status == AUD_STATUS_PLAYING)
-               {
-                       for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
-                       {
-                               if(it->get() == this)
-                               {
-                                       boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
-                                       m_device->m_playingSounds.erase(it);
-                                       m_device->m_pausedSounds.push_back(This);
-
-                                       alSourcePause(m_source);
-
-                                       m_status = AUD_STATUS_PAUSED;
-
-                                       return true;
-                               }
-                       }
-               }
-       }
-
-       return false;
+       return pause(false);
 }
 
 bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
@@ -302,6 +306,9 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
                }
        }
 
+       if(m_status == AUD_STATUS_STOPPED)
+               m_status = AUD_STATUS_PAUSED;
+
        return true;
 }
 
@@ -409,7 +416,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
 {
        if(!m_status)
                return false;
+
+       if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
+               m_status = AUD_STATUS_PAUSED;
+
        m_loopcount = count;
+
        return true;
 }
 
@@ -987,7 +999,7 @@ void AUD_OpenALDevice::updateStreams()
                        }
 
                        for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
-                               (*it)->pause();
+                               (*it)->pause(true);
 
                        for(it = stopSounds.begin(); it != stopSounds.end(); it++)
                                (*it)->stop();
index d2a4be227bafd5d365bb669f4082432a57bf1cb8..f0e478249671dd2eb9ec7a2cd64a33d0cb4d3cf1 100644 (file)
@@ -96,6 +96,8 @@ private:
                /// Own device.
                AUD_OpenALDevice* m_device;
 
+               bool pause(bool keep);
+
        public:
 
                /**
index 9beba2eb0a0d6eea9085646496c25b34693e826e..b00289b3fae80de4e98a6e3e53922c72eea3df8e 100644 (file)
@@ -2908,6 +2908,7 @@ PyInit_aud(void)
        PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
        PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
        PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
+       PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_STOPPED);
        // distance model constants
        PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
        PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
index 9dcb743693e58eb295cf01aeb52cba8d16a649e1..c80fb4027b80528c6127eebc5d3f0cc858c42aa1 100644 (file)
@@ -113,6 +113,8 @@ public:
         *.         invalid
         *        - AUD_STATUS_PLAYING if the sound is currently played back.
         *        - AUD_STATUS_PAUSED if the sound is currently paused.
+        *        - AUD_STATUS_STOPPED if the sound finished playing and is still
+        *          kept in the device.
         * \see AUD_Status
         */
        virtual AUD_Status getStatus()=0;
index a7e5b25664bfc4bc78f1d9a32a11cf60ed858874..7bf59cd6f31a1beb261e7e39630c7da40868859e 100644 (file)
@@ -57,6 +57,37 @@ typedef enum
 /********************** AUD_SoftwareHandle Handle Code ************************/
 /******************************************************************************/
 
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
+{
+       if(m_status)
+       {
+               AUD_MutexLock lock(*m_device);
+
+               if(m_status == AUD_STATUS_PLAYING)
+               {
+                       for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+                       {
+                               if(it->get() == this)
+                               {
+                                       boost::shared_ptr<AUD_SoftwareHandle> This = *it;
+
+                                       m_device->m_playingSounds.erase(it);
+                                       m_device->m_pausedSounds.push_back(This);
+
+                                       if(m_device->m_playingSounds.empty())
+                                               m_device->playing(m_device->m_playback = false);
+
+                                       m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
+
+                                       return true;
+                               }
+                       }
+               }
+       }
+
+       return false;
+}
+
 AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
        m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_loopcount(0),
        m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
@@ -225,33 +256,7 @@ void AUD_SoftwareDevice::AUD_SoftwareHandle::setSpecs(AUD_Specs specs)
 
 bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
 {
-       if(m_status)
-       {
-               AUD_MutexLock lock(*m_device);
-
-               if(m_status == AUD_STATUS_PLAYING)
-               {
-                       for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
-                       {
-                               if(it->get() == this)
-                               {
-                                       boost::shared_ptr<AUD_SoftwareHandle> This = *it;
-
-                                       m_device->m_playingSounds.erase(it);
-                                       m_device->m_pausedSounds.push_back(This);
-
-                                       if(m_device->m_playingSounds.empty())
-                                               m_device->playing(m_device->m_playback = false);
-
-                                       m_status = AUD_STATUS_PAUSED;
-
-                                       return true;
-                               }
-                       }
-               }
-       }
-
-       return false;
+       return pause(false);
 }
 
 bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
@@ -360,6 +365,9 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
 
        m_reader->seek((int)(position * m_reader->getSpecs().rate));
 
+       if(m_status == AUD_STATUS_STOPPED)
+               m_status = AUD_STATUS_PAUSED;
+
        return true;
 }
 
@@ -429,7 +437,12 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
 {
        if(!m_status)
                return false;
+
+       if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
+               m_status = AUD_STATUS_PAUSED;
+
        m_loopcount = count;
+
        return true;
 }
 
@@ -793,19 +806,14 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
                m_mixer->read(buffer, m_volume);
 
                // cleanup
-               while(!stopSounds.empty())
-               {
-                       sound = stopSounds.front();
-                       stopSounds.pop_front();
-                       sound->stop();
-               }
+               for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
+                       (*it)->pause(true);
 
-               while(!pauseSounds.empty())
-               {
-                       sound = pauseSounds.front();
-                       pauseSounds.pop_front();
-                       sound->pause();
-               }
+               for(it = stopSounds.begin(); it != stopSounds.end(); it++)
+                       (*it)->stop();
+
+               pauseSounds.clear();
+               stopSounds.clear();
        }
 }
 
index 8675a5ce2b890eeb7705a22833889245bc09b833..3c8c1e438a370aa24ea588cff81b5b70db722177 100644 (file)
@@ -139,6 +139,8 @@ protected:
                /// Own device.
                AUD_SoftwareDevice* m_device;
 
+               bool pause(bool keep);
+
        public:
 
                /**
index f42cb1ab018005776da11b235e983d269c7bb763..ec2c06900ace0a742dca0ba38d9dda73ce47ae67 100644 (file)
@@ -125,7 +125,8 @@ typedef enum
 {
        AUD_STATUS_INVALID = 0,                 /// Invalid handle. Maybe due to stopping.
        AUD_STATUS_PLAYING,                             /// Sound is playing.
-       AUD_STATUS_PAUSED                               /// Sound is being paused.
+       AUD_STATUS_PAUSED,                              /// Sound is being paused.
+       AUD_STATUS_STOPPED                              /// Sound is stopped but kept in the device.
 } AUD_Status;
 
 /// Error codes for exceptions (C++ library) or for return values (C API).
index 5438ae5a97c7a67dcdaf4766d349ccb77095044f..3a4b1d82946acb78942091fb62869094c42cb69c 100644 (file)
@@ -109,7 +109,7 @@ void KX_SoundActuator::play()
 
        try
        {
-               m_handle = AUD_getDevice()->play(sound, 0);
+               m_handle = AUD_getDevice()->play(sound);
        }
        catch(AUD_Exception&)
        {