fix for a bug reported by zapman on blenderartist.
[blender.git] / source / gameengine / Ketsji / KX_SoundActuator.cpp
1 /**
2  * KX_SoundActuator.cpp
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  *
31  */
32
33 #include "KX_SoundActuator.h"
34 #include "SND_SoundObject.h"
35 #include "KX_GameObject.h"
36 #include "SND_SoundObject.h"
37 #include "SND_Scene.h" // needed for replication
38 #include "KX_PyMath.h" // needed for PyObjectFrom()
39 #include <iostream>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 /* ------------------------------------------------------------------------- */
46 /* Native functions                                                          */
47 /* ------------------------------------------------------------------------- */
48 KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
49                                                                    SND_SoundObject* sndobj,
50                                                                    SND_Scene*   sndscene,
51                                                                    KX_SOUNDACT_TYPE type,
52                                                                    short start,
53                                                                    short end,
54                                                                    PyTypeObject* T)
55                                                                    : SCA_IActuator(gameobj,T)
56 {
57         m_soundObject = sndobj;
58         m_soundScene = sndscene;
59         m_type = type;
60         m_lastEvent = true;
61         m_isplaying = false;
62         m_startFrame = start;
63         m_endFrame = end;
64         m_pino = false;
65         
66
67 }
68
69
70
71 KX_SoundActuator::~KX_SoundActuator()
72 {
73         if (m_soundObject)
74         {
75                 m_soundScene->RemoveActiveObject(m_soundObject);
76                 m_soundScene->DeleteObject(m_soundObject);
77         }
78 }
79
80
81
82 CValue* KX_SoundActuator::GetReplica()
83 {
84         KX_SoundActuator* replica = new KX_SoundActuator(*this);
85         replica->ProcessReplica();
86         return replica;
87 };
88
89 void KX_SoundActuator::ProcessReplica()
90 {
91         SCA_IActuator::ProcessReplica();
92         if (m_soundObject)
93         {
94             SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
95                 setSoundObject(soundobj);
96                 m_soundScene->AddObject(soundobj);
97         }
98 }       
99
100 bool KX_SoundActuator::Update(double curtime, bool frame)
101 {
102         if (!frame)
103                 return true;
104         bool result = false;
105
106         // do nothing on negative events, otherwise sounds are played twice!
107         bool bNegativeEvent = IsNegativeEvent();
108         bool bPositiveEvent = m_posevent;
109         
110         RemoveAllEvents();
111
112         if (!m_soundObject)
113                 return false;
114
115         // actual audio device playing state
116         bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false;
117
118         if (m_pino)
119         {
120                 bNegativeEvent = true;
121                 m_pino = false;
122         }
123
124         if (bNegativeEvent)
125         {       
126                 // here must be a check if it is still playing
127                 if (m_isplaying && isplaying) 
128                 {
129                         switch (m_type)
130                         {
131                         case KX_SOUNDACT_PLAYSTOP:
132                         case KX_SOUNDACT_LOOPSTOP:
133                         case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
134                                 {
135                                         m_soundScene->RemoveActiveObject(m_soundObject);
136                                         break;
137                                 }
138                         case KX_SOUNDACT_PLAYEND:
139                                 {
140                                         m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
141                                         break;
142                                 }
143                         case KX_SOUNDACT_LOOPEND:
144                         case KX_SOUNDACT_LOOPBIDIRECTIONAL:
145                                 {
146                                         m_soundObject->SetLoopMode(SND_LOOP_OFF);
147                                         m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
148                                         break;
149                                 }
150                         default:
151                                 // implement me !!
152                                 break;
153                         }
154                 }
155                 // remember that we tried to stop the actuator
156                 m_isplaying = false;
157         }
158         
159 #if 1
160         // Warning: when de-activating the actuator, after a single negative event this runs again with...
161         // m_posevent==false && m_posevent==false, in this case IsNegativeEvent() returns false 
162         // and assumes this is a positive event.
163         // check that we actually have a positive event so as not to play sounds when being disabled.
164         else if(bPositiveEvent) { // <- added since 2.49
165 #else
166         else {  // <- works in most cases except a loop-end sound will never stop unless
167                         // the negative pulse is done continuesly
168 #endif
169                 if (!m_isplaying)
170                 {
171                         switch (m_type)
172                         {
173                         case KX_SOUNDACT_LOOPBIDIRECTIONAL:
174                         case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
175                                 {
176                                         m_soundObject->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
177                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
178                                         m_isplaying = true;
179                                         result = true;
180                                         break;
181                                 }
182                         case KX_SOUNDACT_LOOPEND:
183                         case KX_SOUNDACT_LOOPSTOP:
184                                 {
185                                         m_soundObject->SetLoopMode(SND_LOOP_NORMAL);
186                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
187                                         m_isplaying = true;
188                                         result = true;
189                                         break;
190                                 }
191                         case KX_SOUNDACT_PLAYSTOP:
192                         case KX_SOUNDACT_PLAYEND:
193                                 {
194                                         m_soundObject->SetLoopMode(SND_LOOP_OFF);
195                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
196                                         m_isplaying = true;
197                                         result = true;
198                                         break;
199                                 }
200                         default:
201                                 // implement me !!
202                                 break;
203                         }
204                 }
205         }
206         // verify that the sound is still playing
207         isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false;
208
209         if (isplaying)
210         {
211                 m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition());
212                 m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity());
213                 m_soundObject->SetOrientation(((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation());
214                 result = true;
215         }
216         else
217         {
218                 m_isplaying = false;
219                 result = false;
220         }
221         /*
222         if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP)))
223         {
224                 m_pino = true;
225         }
226         */
227         return result;
228 }
229
230
231
232 void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
233 {
234         m_soundObject = soundobject;
235 }
236
237
238
239 /* ------------------------------------------------------------------------- */
240 /* Python functions                                                          */
241 /* ------------------------------------------------------------------------- */
242
243
244
245 /* Integration hooks ------------------------------------------------------- */
246 PyTypeObject KX_SoundActuator::Type = {
247 #if (PY_VERSION_HEX >= 0x02060000)
248         PyVarObject_HEAD_INIT(NULL, 0)
249 #else
250         /* python 2.5 and below */
251         PyObject_HEAD_INIT( NULL )  /* required py macro */
252         0,                          /* ob_size */
253 #endif
254                 "KX_SoundActuator",
255                 sizeof(PyObjectPlus_Proxy),
256                 0,
257                 py_base_dealloc,
258                 0,
259                 0,
260                 0,
261                 0,
262                 py_base_repr,
263                 0,0,0,0,0,0,
264                 py_base_getattro,
265                 py_base_setattro,
266                 0,0,0,0,0,0,0,0,0,
267                 Methods
268 };
269
270
271
272 PyParentObject KX_SoundActuator::Parents[] = {
273         &KX_SoundActuator::Type,
274                 &SCA_IActuator::Type,
275                 &SCA_ILogicBrick::Type,
276                 &CValue::Type,
277                 NULL
278 };
279
280
281
282 PyMethodDef KX_SoundActuator::Methods[] = {
283         // Deprecated ----->
284         {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL},
285         {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_NOARGS,NULL},
286         {"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL},
287         {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_NOARGS,NULL},
288         {"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL},
289         {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_NOARGS,NULL},
290         {"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL},
291         {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_NOARGS,NULL},
292         {"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL},
293         {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_NOARGS,NULL},
294         {"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL},
295         {"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL},
296         {"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL},
297         {"setType",(PyCFunction) KX_SoundActuator::sPySetType,METH_VARARGS,NULL},
298         {"getType",(PyCFunction) KX_SoundActuator::sPyGetType,METH_NOARGS,NULL},
299         // <-----
300
301         KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, startSound),
302         KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, pauseSound),
303         KX_PYMETHODTABLE_NOARGS(KX_SoundActuator, stopSound),
304         {NULL,NULL,NULL,NULL} //Sentinel
305 };
306
307 PyAttributeDef KX_SoundActuator::Attributes[] = {
308         KX_PYATTRIBUTE_RW_FUNCTION("fileName", KX_SoundActuator, pyattr_get_filename, pyattr_set_filename),
309         KX_PYATTRIBUTE_RW_FUNCTION("volume", KX_SoundActuator, pyattr_get_gain, pyattr_set_gain),
310         KX_PYATTRIBUTE_RW_FUNCTION("pitch", KX_SoundActuator, pyattr_get_pitch, pyattr_set_pitch),
311         KX_PYATTRIBUTE_RW_FUNCTION("rollOffFactor", KX_SoundActuator, pyattr_get_rollOffFactor, pyattr_set_rollOffFactor),
312         KX_PYATTRIBUTE_RW_FUNCTION("looping", KX_SoundActuator, pyattr_get_looping, pyattr_set_looping),
313         KX_PYATTRIBUTE_RW_FUNCTION("position", KX_SoundActuator, pyattr_get_position, pyattr_set_position),
314         KX_PYATTRIBUTE_RW_FUNCTION("velocity", KX_SoundActuator, pyattr_get_velocity, pyattr_set_velocity),
315         KX_PYATTRIBUTE_RW_FUNCTION("orientation", KX_SoundActuator, pyattr_get_orientation, pyattr_set_orientation),
316         KX_PYATTRIBUTE_ENUM_RW("mode",KX_SoundActuator::KX_SOUNDACT_NODEF+1,KX_SoundActuator::KX_SOUNDACT_MAX-1,false,KX_SoundActuator,m_type),
317         { NULL }        //Sentinel
318 };
319
320 /* Methods ----------------------------------------------------------------- */
321 KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound, 
322 "startSound()\n"
323 "\tStarts the sound.\n")
324 {
325         if (m_soundObject)
326                 // This has no effect if the actuator is not active.
327                 // To start the sound you must activate the actuator. 
328                 // This function is to restart the sound.
329                 m_soundObject->StartSound();    
330         Py_RETURN_NONE;
331 }         
332
333 KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, pauseSound,
334 "pauseSound()\n"
335 "\tPauses the sound.\n")
336 {
337         if (m_soundObject)
338                 // unfortunately, openal does not implement pause correctly, it is equivalent to a stop
339                 m_soundObject->PauseSound();    
340         Py_RETURN_NONE;
341
342
343 KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound,
344 "stopSound()\n"
345 "\tStops the sound.\n")
346 {
347         if (m_soundObject)
348                 m_soundObject->StopSound();     
349         Py_RETURN_NONE;
350 }
351
352 /* Atribute setting and getting -------------------------------------------- */
353 PyObject* KX_SoundActuator::py_getattro(PyObject *attr)
354 {
355         py_getattro_up(SCA_IActuator);
356 }
357
358 PyObject* KX_SoundActuator::py_getattro_dict() {
359         py_getattro_dict_up(SCA_IActuator);
360 }
361
362 int KX_SoundActuator::py_setattro(PyObject *attr, PyObject* value) {
363         py_setattro_up(SCA_IActuator);
364 }
365
366 PyObject* KX_SoundActuator::pyattr_get_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
367 {
368         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
369         if (!actuator->m_soundObject)
370         {
371                 return PyString_FromString("");
372         }
373         STR_String objectname = actuator->m_soundObject->GetObjectName();
374         char* name = objectname.Ptr();
375         
376         if (!name) {
377                 PyErr_SetString(PyExc_RuntimeError, "value = actuator.fileName: KX_SoundActuator, unable to get sound fileName");
378                 return NULL;
379         } else
380                 return PyString_FromString(name);
381 }
382
383 PyObject* KX_SoundActuator::pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
384 {
385         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
386         float gain = (actuator->m_soundObject) ? actuator->m_soundObject->GetGain() : 1.0f;
387
388         PyObject* result = PyFloat_FromDouble(gain);
389         
390         return result;
391 }
392
393 PyObject* KX_SoundActuator::pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
394 {
395         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
396         float pitch = (actuator->m_soundObject) ? actuator->m_soundObject->GetPitch() : 1.0;
397         PyObject* result = PyFloat_FromDouble(pitch);
398         
399         return result;
400 }
401
402 PyObject* KX_SoundActuator::pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
403 {
404         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
405         float rollofffactor = (actuator->m_soundObject) ? actuator->m_soundObject->GetRollOffFactor() : 1.0;
406         PyObject* result = PyFloat_FromDouble(rollofffactor);
407         
408         return result;
409 }
410
411 PyObject* KX_SoundActuator::pyattr_get_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
412 {
413         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
414         int looping = (actuator->m_soundObject) ? actuator->m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
415         PyObject* result = PyInt_FromLong(looping);
416         
417         return result;
418 }
419
420 PyObject* KX_SoundActuator::pyattr_get_position(void * self, const struct KX_PYATTRIBUTE_DEF *attrdef) 
421 {
422         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
423         MT_Vector3 pos(0.0, 0.0, 0.0);
424
425         if (actuator->m_soundObject)
426                 pos = actuator->m_soundObject->GetPosition();
427
428         PyObject * result = PyObjectFrom(pos);
429         return result;
430 }
431
432 PyObject* KX_SoundActuator::pyattr_get_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
433 {
434         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
435         MT_Vector3 vel;
436
437         if (actuator->m_soundObject)
438                 vel = actuator->m_soundObject->GetVelocity();
439
440         PyObject * result = PyObjectFrom(vel);
441         return result;
442 }
443
444 PyObject* KX_SoundActuator::pyattr_get_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) 
445 {
446         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
447         MT_Matrix3x3 ori;
448
449         if (actuator->m_soundObject)
450                 ori = actuator->m_soundObject->GetOrientation();
451
452         PyObject * result = PyObjectFrom(ori);
453         return result;
454 }
455
456 int KX_SoundActuator::pyattr_set_filename(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
457 {
458         char *soundName = NULL;
459         KX_SoundActuator * actuator = static_cast<KX_SoundActuator*> (self);
460         // void *soundPointer = NULL; /*unused*/
461         
462         if (!PyArg_Parse(value, "s", &soundName))
463                 return PY_SET_ATTR_FAIL;
464
465         if (actuator->m_soundObject) {
466                 actuator->m_soundObject->SetObjectName(soundName);
467         }
468         
469         return PY_SET_ATTR_SUCCESS;
470 }
471
472
473 int KX_SoundActuator::pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
474 {
475         float gain = 1.0;
476         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
477         if (!PyArg_Parse(value, "f", &gain))
478                 return PY_SET_ATTR_FAIL;
479         
480         if (actuator->m_soundObject)
481                 actuator->m_soundObject->SetGain(gain);
482         
483         return PY_SET_ATTR_SUCCESS;
484 }         
485
486 int KX_SoundActuator::pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
487 {
488         float pitch = 1.0;
489         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
490         if (!PyArg_Parse(value, "f", &pitch))
491                 return PY_SET_ATTR_FAIL;
492         
493         if (actuator->m_soundObject)
494                 actuator->m_soundObject->SetPitch(pitch);
495         
496         return PY_SET_ATTR_SUCCESS;
497 }         
498
499 int KX_SoundActuator::pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
500 {
501         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
502         float rollofffactor = 1.0;
503         if (!PyArg_Parse(value, "f", &rollofffactor))
504                 return PY_SET_ATTR_FAIL;
505         
506         if (actuator->m_soundObject)
507                 actuator->m_soundObject->SetRollOffFactor(rollofffactor);
508
509         return PY_SET_ATTR_SUCCESS;
510 }         
511
512 int KX_SoundActuator::pyattr_set_looping(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
513 {
514         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
515         int looping = 1;
516         if (!PyArg_Parse(value, "i", &looping))
517                 return PY_SET_ATTR_FAIL;
518         
519         if (actuator->m_soundObject)
520                 actuator->m_soundObject->SetLoopMode(looping);
521         
522         return PY_SET_ATTR_SUCCESS;
523 }         
524
525 int KX_SoundActuator::pyattr_set_position(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
526 {
527         float pos[3];
528
529         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
530
531         if (!PyArg_ParseTuple(value, "fff", &pos[0], &pos[1], &pos[2]))
532                 return PY_SET_ATTR_FAIL;
533         
534         if (actuator->m_soundObject)
535                 actuator->m_soundObject->SetPosition(MT_Vector3(pos));
536         
537         return PY_SET_ATTR_SUCCESS;
538 }         
539
540 int KX_SoundActuator::pyattr_set_velocity(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
541 {
542         float vel[3];
543         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
544
545
546         if (!PyArg_ParseTuple(value, "fff", &vel[0], &vel[1], &vel[2]))
547                 return PY_SET_ATTR_FAIL;
548         
549         if (actuator->m_soundObject)
550                 actuator->m_soundObject->SetVelocity(MT_Vector3(vel));
551         
552         return PY_SET_ATTR_SUCCESS;
553
554 }         
555
556 int KX_SoundActuator::pyattr_set_orientation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
557 {
558
559         MT_Matrix3x3 rot;
560         KX_SoundActuator * actuator = static_cast<KX_SoundActuator *> (self);
561
562         /* if value is not a sequence PyOrientationTo makes an error */
563         if (!PyOrientationTo(value, rot, "actuator.orientation = value: KX_SoundActuator"))
564                 return PY_SET_ATTR_FAIL;
565         
566         /* Since not having m_soundObject didn't do anything in the old version,
567          * it probably should be kept that way  */
568         if (!actuator->m_soundObject)
569                 return PY_SET_ATTR_SUCCESS;
570         
571         actuator->m_soundObject->SetOrientation(rot);
572         return PY_SET_ATTR_SUCCESS;
573 }
574
575 // Deprecated ----->
576 PyObject* KX_SoundActuator::PySetFilename(PyObject* args)
577 {
578         char *soundName = NULL;
579         ShowDeprecationWarning("setFilename()", "the fileName property");
580         // void *soundPointer = NULL; /*unused*/
581         
582         if (!PyArg_ParseTuple(args, "s", &soundName))
583                 return NULL;
584
585         Py_RETURN_NONE;
586 }
587
588 PyObject* KX_SoundActuator::PyGetFilename()
589 {
590         ShowDeprecationWarning("getFilename()", "the fileName property");
591         if (!m_soundObject)
592         {
593                 return PyString_FromString("");
594         }
595         STR_String objectname = m_soundObject->GetObjectName();
596         char* name = objectname.Ptr();
597         
598         if (!name) {
599                 PyErr_SetString(PyExc_RuntimeError, "Unable to get sound fileName");
600                 return NULL;
601         } else
602                 return PyString_FromString(name);
603 }
604
605 PyObject* KX_SoundActuator::PySetGain(PyObject* args)
606 {
607         ShowDeprecationWarning("setGain()", "the volume property");
608         float gain = 1.0;
609         if (!PyArg_ParseTuple(args, "f:setGain", &gain))
610                 return NULL;
611         
612         if (m_soundObject)
613                 m_soundObject->SetGain(gain);
614         
615         Py_RETURN_NONE;
616 }         
617
618
619
620 PyObject* KX_SoundActuator::PyGetGain()
621 {
622         ShowDeprecationWarning("getGain()", "the volume property");
623         float gain = (m_soundObject) ? m_soundObject->GetGain() : 1.0f;
624         PyObject* result = PyFloat_FromDouble(gain);
625         
626         return result;
627 }
628
629
630
631 PyObject* KX_SoundActuator::PySetPitch(PyObject* args)
632 {
633         ShowDeprecationWarning("setPitch()", "the pitch property");
634         float pitch = 1.0;
635         if (!PyArg_ParseTuple(args, "f:setPitch", &pitch))
636                 return NULL;
637         
638         if (m_soundObject)
639                 m_soundObject->SetPitch(pitch);
640         
641         Py_RETURN_NONE;
642 }         
643
644
645
646 PyObject* KX_SoundActuator::PyGetPitch()
647 {
648         ShowDeprecationWarning("getPitch()", "the pitch property");
649         float pitch = (m_soundObject) ? m_soundObject->GetPitch() : 1.0;
650         PyObject* result = PyFloat_FromDouble(pitch);
651         
652         return result;
653 }
654
655
656
657 PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* args)
658 {
659         ShowDeprecationWarning("setRollOffFactor()", "the rollOffFactor property");
660         float rollofffactor = 1.0;
661         if (!PyArg_ParseTuple(args, "f:setRollOffFactor", &rollofffactor))
662                 return NULL;
663         
664         if (m_soundObject)
665                 m_soundObject->SetRollOffFactor(rollofffactor);
666
667         Py_RETURN_NONE;
668 }         
669
670
671
672 PyObject* KX_SoundActuator::PyGetRollOffFactor()
673 {
674         ShowDeprecationWarning("getRollOffFactor()", "the rollOffFactor property");
675         float rollofffactor = (m_soundObject) ? m_soundObject->GetRollOffFactor() : 1.0;
676         PyObject* result = PyFloat_FromDouble(rollofffactor);
677         
678         return result;
679 }
680
681
682
683 PyObject* KX_SoundActuator::PySetLooping(PyObject* args)
684 {
685         ShowDeprecationWarning("setLooping()", "the looping property");
686         bool looping = 1;
687         if (!PyArg_ParseTuple(args, "i:setLooping", &looping))
688                 return NULL;
689         
690         if (m_soundObject)
691                 m_soundObject->SetLoopMode(looping);
692         
693         Py_RETURN_NONE;
694 }         
695
696
697
698 PyObject* KX_SoundActuator::PyGetLooping()
699 {
700         ShowDeprecationWarning("getLooping()", "the looping property");
701         int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
702         PyObject* result = PyInt_FromLong(looping);
703         
704         return result;
705 }
706
707
708
709 PyObject* KX_SoundActuator::PySetPosition(PyObject* args)
710 {
711         MT_Point3 pos;
712         ShowDeprecationWarning("setPosition()", "the position property");
713         pos[0] = 0.0;
714         pos[1] = 0.0;
715         pos[2] = 0.0;
716
717         if (!PyArg_ParseTuple(args, "fff:setPosition", &pos[0], &pos[1], &pos[2]))
718                 return NULL;
719         
720         if (m_soundObject)
721                 m_soundObject->SetPosition(pos);
722         
723         Py_RETURN_NONE;
724 }         
725
726
727
728 PyObject* KX_SoundActuator::PySetVelocity(PyObject* args)
729 {
730         MT_Vector3 vel;
731         ShowDeprecationWarning("setVelocity()", "the velocity property");
732         vel[0] = 0.0;
733         vel[1] = 0.0;
734         vel[2] = 0.0;
735
736         if (!PyArg_ParseTuple(args, "fff:setVelocity", &vel[0], &vel[1], &vel[2]))
737                 return NULL;
738         
739         if (m_soundObject)
740                 m_soundObject->SetVelocity(vel);
741         
742         Py_RETURN_NONE;
743 }         
744
745
746
747 PyObject* KX_SoundActuator::PySetOrientation(PyObject* args)
748 {
749         MT_Matrix3x3 ori;
750         ShowDeprecationWarning("setOrientation()", "the orientation property");
751         ori[0][0] = 1.0;
752         ori[0][1] = 0.0;
753         ori[0][2] = 0.0;
754         ori[1][0] = 0.0;
755         ori[1][1] = 1.0;
756         ori[1][2] = 0.0;
757         ori[2][0] = 0.0;
758         ori[2][1] = 0.0;
759         ori[2][2] = 1.0;
760
761         if (!PyArg_ParseTuple(args, "fffffffff:setOrientation", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
762                 return NULL;
763         
764         if (m_soundObject)
765                 m_soundObject->SetOrientation(ori);
766         
767         Py_RETURN_NONE;
768 }
769
770 PyObject* KX_SoundActuator::PySetType(PyObject* args)
771 {
772         int typeArg;
773         ShowDeprecationWarning("setType()", "the mode property");
774
775         if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
776                 return NULL;
777         }
778
779         if ( (typeArg > KX_SOUNDACT_NODEF)
780           && (typeArg < KX_SOUNDACT_MAX) ) {
781                 m_type = (KX_SOUNDACT_TYPE) typeArg;
782         }
783
784         Py_RETURN_NONE;
785 }
786
787 PyObject* KX_SoundActuator::PyGetType()
788 {
789         ShowDeprecationWarning("getType()", "the mode property");
790         return PyInt_FromLong(m_type);
791 }
792 // <-----
793