Merge with trunk r37757.
[blender.git] / source / gameengine / Ketsji / KX_SoundActuator.cpp
index 75012181ac27b88f11b3d3a1cdb33c7916107bf0..0e7b00aeb24d54066a1c584b1cac124c01c52698 100644 (file)
@@ -57,7 +57,7 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
                                                                   KX_SOUNDACT_TYPE type)//,
                                                                   : SCA_IActuator(gameobj, KX_ACT_SOUND)
 {
-       m_sound = sound;
+       m_sound = AUD_copy(sound);
        m_volume = volume;
        m_pitch = pitch;
        m_is3d = is3d;
@@ -73,12 +73,16 @@ KX_SoundActuator::~KX_SoundActuator()
 {
        if(m_handle)
                AUD_stop(m_handle);
+       AUD_unload(m_sound);
 }
 
 void KX_SoundActuator::play()
 {
        if(m_handle)
+       {
                AUD_stop(m_handle);
+               m_handle = NULL;
+       }
 
        if(!m_sound)
                return;
@@ -106,11 +110,16 @@ void KX_SoundActuator::play()
                break;
        }
 
+       m_handle = AUD_play(sound, 0);
+
+       if(sound2)
+               AUD_unload(sound2);
+
+       if(!m_handle)
+               return;
+
        if(m_is3d)
        {
-               // sound shall be played 3D
-               m_handle = AUD_play(sound, 0);
-
                AUD_setRelative(m_handle, false);
                AUD_setVolumeMaximum(m_handle, m_3d.max_gain);
                AUD_setVolumeMinimum(m_handle, m_3d.min_gain);
@@ -121,17 +130,12 @@ void KX_SoundActuator::play()
                AUD_setConeAngleOuter(m_handle, m_3d.cone_outer_angle);
                AUD_setConeVolumeOuter(m_handle, m_3d.cone_outer_gain);
        }
-       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;
-
-       if(sound2)
-               AUD_unload(sound2);
 }
 
 CValue* KX_SoundActuator::GetReplica()
@@ -163,7 +167,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
                return false;
 
        // actual audio device playing state
-       bool isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING;
+       bool isplaying = m_handle ? (AUD_getStatus(m_handle) == AUD_STATUS_PLAYING) : false;
 
        if (bNegativeEvent)
        {
@@ -177,7 +181,9 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
                        case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
                                {
                                        // stop immediately
-                                       AUD_stop(m_handle);
+                                       if(m_handle)
+                                               AUD_stop(m_handle);
+                                       m_handle = NULL;
                                        break;
                                }
                        case KX_SOUNDACT_PLAYEND:
@@ -189,7 +195,8 @@ 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);
+                                       if(m_handle)
+                                               AUD_setLoop(m_handle, 0);
                                        break;
                                }
                        default:
@@ -215,7 +222,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
                        play();
        }
        // verify that the sound is still playing
-       isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING ? true : false;
+       isplaying = m_handle ? (AUD_getStatus(m_handle) == AUD_STATUS_PLAYING) : false;
 
        if (isplaying)
        {
@@ -290,6 +297,7 @@ PyAttributeDef KX_SoundActuator::Attributes[] = {
        KX_PYATTRIBUTE_RW_FUNCTION("cone_angle_inner", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
        KX_PYATTRIBUTE_RW_FUNCTION("cone_angle_outer", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
        KX_PYATTRIBUTE_RW_FUNCTION("cone_volume_outer", KX_SoundActuator, pyattr_get_3d_property, pyattr_set_3d_property),
+       KX_PYATTRIBUTE_RW_FUNCTION("sound", KX_SoundActuator, pyattr_get_sound, pyattr_set_sound),
 
        KX_PYATTRIBUTE_RW_FUNCTION("time", KX_SoundActuator, pyattr_get_audposition, pyattr_set_audposition),
        KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain),
@@ -303,15 +311,18 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound,
 "startSound()\n"
 "\tStarts the sound.\n")
 {
-       switch(AUD_getStatus(m_handle))
+       if(m_handle)
        {
-       case AUD_STATUS_PLAYING:
-               break;
-       case AUD_STATUS_PAUSED:
-               AUD_resume(m_handle);
-               break;
-       default:
-               play();
+               switch(AUD_getStatus(m_handle))
+               {
+               case AUD_STATUS_PLAYING:
+                       break;
+               case AUD_STATUS_PAUSED:
+                       AUD_resume(m_handle);
+                       break;
+               default:
+                       play();
+               }
        }
        Py_RETURN_NONE;
 }
@@ -320,7 +331,8 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, pauseSound,
 "pauseSound()\n"
 "\tPauses the sound.\n")
 {
-       AUD_pause(m_handle);
+       if(m_handle)
+               AUD_pause(m_handle);
        Py_RETURN_NONE;
 }
 
@@ -328,7 +340,9 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound,
 "stopSound()\n"
 "\tStops the sound.\n")
 {
-       AUD_stop(m_handle);
+       if(m_handle)
+               AUD_stop(m_handle);
+       m_handle = NULL;
        Py_RETURN_NONE;
 }
 
@@ -404,6 +418,12 @@ PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRI
        return result;
 }
 
+PyObject* KX_SoundActuator::pyattr_get_sound(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+       KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+       return AUD_getPythonFactory(actuator->m_sound);
+}
+
 int KX_SoundActuator::pyattr_set_3d_property(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
 {
        KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
@@ -505,4 +525,22 @@ int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_D
        return PY_SET_ATTR_SUCCESS;
 }
 
+int KX_SoundActuator::pyattr_set_sound(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+       PyObject* sound = NULL;
+       KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
+       if (!PyArg_Parse(value, "O", &sound))
+               return PY_SET_ATTR_FAIL;
+
+       AUD_Sound* snd = AUD_getPythonSound(sound);
+       if(snd)
+       {
+               AUD_unload(actuator->m_sound);
+               actuator->m_sound = snd;
+               return PY_SET_ATTR_SUCCESS;
+       }
+
+       return PY_SET_ATTR_FAIL;
+}
+
 #endif // WITH_PYTHON