BGE bug fix: fix several bugs and inconsistencies in sound actuator:
authorBenoit Bolsee <benoit.bolsee@online.be>
Thu, 9 Oct 2008 06:06:11 +0000 (06:06 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Thu, 9 Oct 2008 06:06:11 +0000 (06:06 +0000)
- support stopping of loop sound
- support stopping by python
- keep state of actuator in sync with audio device.
  The lack of state sync was causing several other problems:
  - actuator stop playing the sound
  - sound chopped before the end
  - not possible to pause sound

intern/SoundSystem/intern/SND_Scene.cpp
intern/SoundSystem/intern/SND_SoundObject.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp

index bbf971ddc871dccb514f1c508e69f3275b603821..9d050a81161f8b3a8f022694dc94bb8786322112 100644 (file)
@@ -388,11 +388,18 @@ void SND_Scene::UpdateActiveObects()
 #endif
 #ifdef USE_OPENAL
                        // ok, properties Set. now see if it must play
-                       if (pObject->GetPlaystate() == SND_MUST_PLAY)
-                       {
+                       switch (pObject->GetPlaystate()){
+                       case SND_MUST_PLAY:
                                m_audiodevice->PlayObject(id);
                                pObject->SetPlaystate(SND_PLAYING);
-                               //break;
+                               break;
+                       case SND_MUST_STOP:
+                               RemoveActiveObject(pObject);
+                               break;
+                       case SND_MUST_PAUSE:
+                               m_audiodevice->PauseObject(id);
+                               pObject->SetPlaystate(SND_PAUSED);
+                               break;
                        }
 #endif
 
index e514a186e5e219f322e2e923f679d78eef68b6b7..7a244b5090dbf90189a91fcbd61a620441aa45e5 100644 (file)
@@ -91,21 +91,24 @@ SND_SoundObject::~SND_SoundObject()
 
 void SND_SoundObject::StartSound()
 {
-       m_playstate = SND_MUST_PLAY;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_PLAY;
 }
 
 
 
 void SND_SoundObject::StopSound()
 {
-       m_playstate = SND_MUST_STOP;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_STOP;
 }
 
 
 
 void SND_SoundObject::PauseSound()
 {
-       m_playstate = SND_MUST_PAUSE;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_PAUSE;
 }
 
 
index f75a1ee5c62cccd9c5e7cdaa647dd7171aa2ea42..afa5af3bc04f3b9f9fff56bd8f39e27ff5e039d1 100644 (file)
@@ -110,6 +110,9 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
        if (!m_soundObject)
                return false;
 
+       // actual audio device playing state
+       bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false;
+
        if (m_pino)
        {
                bNegativeEvent = true;
@@ -119,30 +122,40 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
        if (bNegativeEvent)
        {       
                // here must be a check if it is still playing
-               m_isplaying = false;
-
-               switch (m_type)
+               if (m_isplaying && isplaying) 
                {
-               case KX_SOUNDACT_PLAYSTOP:
-               case KX_SOUNDACT_LOOPSTOP:
-               case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
-                       {
-                               m_soundScene->RemoveActiveObject(m_soundObject);
-                               break;
-                       }
-               case KX_SOUNDACT_PLAYEND:
+                       switch (m_type)
                        {
-                               m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
+                       case KX_SOUNDACT_PLAYSTOP:
+                       case KX_SOUNDACT_LOOPSTOP:
+                       case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
+                               {
+                                       m_soundScene->RemoveActiveObject(m_soundObject);
+                                       break;
+                               }
+                       case KX_SOUNDACT_PLAYEND:
+                               {
+                                       m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
+                                       break;
+                               }
+                       case KX_SOUNDACT_LOOPEND:
+                       case KX_SOUNDACT_LOOPBIDIRECTIONAL:
+                               {
+                                       m_soundObject->SetLoopMode(SND_LOOP_OFF);
+                                       m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
+                                       break;
+                               }
+                       default:
+                               // implement me !!
                                break;
                        }
-               default:
-                       // implement me !!
-                       break;
                }
+               // remember that we tried to stop the actuator
+               m_isplaying = false;
        }
        else
        {
-               if (m_soundObject && !m_isplaying)
+               if (!m_isplaying)
                {
                        switch (m_type)
                        {
@@ -179,8 +192,10 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
                        }
                }
        }
+       // verify that the sound is still playing
+       isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false;
 
-       if (m_isplaying)
+       if (isplaying)
        {
                m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition());
                m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity());
@@ -189,14 +204,15 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
        }
        else
        {
+               m_isplaying = false;
                result = false;
        }
-
+       /*
        if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP)))
        {
                m_pino = true;
        }
-
+       */
        return result;
 }
 
@@ -312,6 +328,9 @@ PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObje
 PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds)
 {
        if (m_soundObject)
+               // This has no effect if the actuator is not active.
+               // To start the sound you must activate the actuator. 
+               // This function is to restart the sound.
                m_soundObject->StartSound();    
        Py_Return;
 }         
@@ -321,6 +340,7 @@ PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObjec
 PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds)
 {
        if (m_soundObject)
+               // unfortunately, openal does not implement pause correctly, it is equivalent to a stop
                m_soundObject->PauseSound();    
        Py_Return;
 }