tmp
[blender.git] / extern / audaspace / bindings / python / PyDynamicMusic.cpp
1 /*******************************************************************************
2 * Copyright 2015-2016 Juan Francisco Crespo Gal├ín
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *   http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
16
17 #include "PyDynamicMusic.h"
18 #include "PySound.h"
19 #include "PyHandle.h"
20 #include "PyDevice.h"
21
22 #include "Exception.h"
23 #include "fx/DynamicMusic.h"
24
25 extern PyObject* AUDError;
26
27 static PyObject *
28 DynamicMusic_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
29 {
30         DynamicMusicP* self = (DynamicMusicP*)type->tp_alloc(type, 0);
31
32         if(self != nullptr)
33         {
34                 PyObject* object;
35                 if(!PyArg_ParseTuple(args, "O:device", &object))
36                         return nullptr;
37                 Device* device = checkDevice(object);
38
39                 try
40                 {
41                         self->dynamicMusic = new std::shared_ptr<aud::DynamicMusic>(new aud::DynamicMusic(*reinterpret_cast<std::shared_ptr<aud::IDevice>*>(device->device)));
42                 }
43                 catch(aud::Exception& e)
44                 {
45                         Py_DECREF(self);
46                         PyErr_SetString(AUDError, e.what());
47                         return nullptr;
48                 }
49         }
50
51         return (PyObject *)self;
52 }
53
54 static void
55 DynamicMusic_dealloc(DynamicMusicP* self)
56 {
57         if(self->dynamicMusic)
58                 delete reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic);
59         Py_TYPE(self)->tp_free((PyObject *)self);
60 }
61
62 PyDoc_STRVAR(M_aud_DynamicMusic_addScene_doc,
63         "addScene(scene)\n\n"
64         "Adds a new scene.\n\n"
65         ":arg scene: The scene sound.\n"
66         ":type scene: :class:`Sound`\n"
67         ":return: The new scene id.\n"
68         ":rtype: int");
69
70 static PyObject *
71 DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
72 {
73         PyObject* object;
74         if(!PyArg_Parse(args, "O:sound", &object))
75                 return nullptr;
76
77         Sound* sound = checkSound(object);
78         if(!sound)
79                 return nullptr;
80
81         try
82         {
83                 return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addScene(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound)));
84         }
85         catch(aud::Exception& e)
86         {
87                 PyErr_SetString(AUDError, e.what());
88                 return nullptr;
89         }
90 }
91
92 PyDoc_STRVAR(M_aud_DynamicMusic_addTransition_doc,
93         "addTransition(ini, end, transition)\n\n"
94         "Adds a new scene.\n\n"
95         ":arg ini: the initial scene foor the transition.\n"
96         ":type ini: int\n"
97         ":arg end: The final scene for the transition.\n"
98         ":type end: int\n"
99         ":arg transition: The transition sound.\n"
100         ":type transition: :class:`Sound`\n"
101         ":return: false if the ini or end scenes don't exist, true othrwise.\n"
102         ":rtype: bool");
103
104 static PyObject *
105 DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
106 {
107         PyObject* object;
108         int ini, end;
109         if(!PyArg_ParseTuple(args, "iiO:sound", &ini, &end, &object))
110                 return nullptr;
111         Sound* sound = checkSound(object);
112         if(!sound)
113                 return nullptr;
114
115         try
116         {
117                 (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addTransition(ini, end, *reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound));
118                 Py_RETURN_NONE;
119         }
120         catch(aud::Exception& e)
121         {
122                 PyErr_SetString(AUDError, e.what());
123                 return nullptr;
124         }
125 }
126
127 PyDoc_STRVAR(M_aud_DynamicMusic_resume_doc,
128         "resume()\n\n"
129         "Resumes playback of the scene.\n\n"
130         ":return: Whether the action succeeded.\n"
131         ":rtype: bool");
132
133 static PyObject *
134 DynamicMusic_resume(DynamicMusicP* self)
135 {
136         try
137         {
138                 return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->resume());
139         }
140         catch(aud::Exception& e)
141         {
142                 PyErr_SetString(AUDError, e.what());
143                 return nullptr;
144         }
145 }
146
147 PyDoc_STRVAR(M_aud_DynamicMusic_pause_doc,
148         "pause()\n\n"
149         "Pauses playback of the scene.\n\n"
150         ":return: Whether the action succeeded.\n"
151         ":rtype: bool");
152
153 static PyObject *
154 DynamicMusic_pause(DynamicMusicP* self)
155 {
156         try
157         {
158                 return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->pause());
159         }
160         catch(aud::Exception& e)
161         {
162                 PyErr_SetString(AUDError, e.what());
163                 return nullptr;
164         }
165 }
166
167 PyDoc_STRVAR(M_aud_DynamicMusic_stop_doc,
168         "stop()\n\n"
169         "Stops playback of the scene.\n\n"
170         ":return: Whether the action succeeded.\n"
171         ":rtype: bool\n\n");
172
173 static PyObject *
174 DynamicMusic_stop(DynamicMusicP* self)
175 {
176         try
177         {
178                 return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->stop());
179         }
180         catch(aud::Exception& e)
181         {
182                 PyErr_SetString(AUDError, e.what());
183                 return nullptr;
184         }
185 }
186
187 static PyMethodDef DynamicMusic_methods[] = {
188         { "addScene", (PyCFunction)DynamicMusic_addScene, METH_O,
189         M_aud_DynamicMusic_addScene_doc
190         },
191         { "addTransition", (PyCFunction)DynamicMusic_addTransition, METH_VARARGS,
192         M_aud_DynamicMusic_addTransition_doc
193         },
194         { "resume", (PyCFunction)DynamicMusic_resume, METH_NOARGS,
195         M_aud_DynamicMusic_resume_doc
196         },
197         { "pause", (PyCFunction)DynamicMusic_pause, METH_NOARGS,
198         M_aud_DynamicMusic_pause_doc
199         },
200         { "stop", (PyCFunction)DynamicMusic_stop, METH_NOARGS,
201         M_aud_DynamicMusic_stop_doc
202         },
203         { nullptr }  /* Sentinel */
204 };
205
206 /////////////////////////////////////////////////////
207
208 PyDoc_STRVAR(M_aud_DynamicMusic_status_doc,
209         "Whether the scene is playing, paused or stopped (=invalid).");
210
211 static PyObject *
212 DynamicMusic_get_status(DynamicMusicP* self, void* nothing)
213 {
214         try
215         {
216                 return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getStatus());
217         }
218         catch(aud::Exception& e)
219         {
220                 PyErr_SetString(AUDError, e.what());
221                 return nullptr;
222         }
223 }
224
225 PyDoc_STRVAR(M_aud_DynamicMusic_position_doc,
226         "The playback position of the scene in seconds.");
227
228 static int
229 DynamicMusic_set_position(DynamicMusicP* self, PyObject* args, void* nothing)
230 {
231         float position;
232
233         if(!PyArg_Parse(args, "f:position", &position))
234                 return -1;
235
236         try
237         {
238                 if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->seek(position))
239                         return 0;
240                 PyErr_SetString(AUDError, "Couldn't seek the sound!");
241         }
242         catch(aud::Exception& e)
243         {
244                 PyErr_SetString(AUDError, e.what());
245         }
246
247         return -1;
248 }
249
250 static PyObject *
251 DynamicMusic_get_position(DynamicMusicP* self, void* nothing)
252 {
253         try
254         {
255                 return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getPosition());
256         }
257         catch(aud::Exception& e)
258         {
259                 PyErr_SetString(AUDError, e.what());
260                 return nullptr;
261         }
262 }
263
264 PyDoc_STRVAR(M_aud_DynamicMusic_fadeTime_doc,
265         "The length in seconds of the crossfade transition");
266
267 static int
268 DynamicMusic_set_fadeTime(DynamicMusicP* self, PyObject* args, void* nothing)
269 {
270         float fadeTime;
271
272         if(!PyArg_Parse(args, "f:fadeTime", &fadeTime))
273                 return -1;
274
275         try
276         {
277                 (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setFadeTime(fadeTime);
278                 return 0;
279         }
280         catch(aud::Exception& e)
281         {
282                 PyErr_SetString(AUDError, e.what());
283         }
284
285         return -1;
286 }
287
288 static PyObject *
289 DynamicMusic_get_fadeTime(DynamicMusicP* self, void* nothing)
290 {
291         try
292         {
293                 return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getFadeTime());
294         }
295         catch(aud::Exception& e)
296         {
297                 PyErr_SetString(AUDError, e.what());
298                 return nullptr;
299         }
300 }
301
302 PyDoc_STRVAR(M_aud_DynamicMusic_scene_doc,
303         "The current scene");
304
305 static int
306 DynamicMusic_set_scene(DynamicMusicP* self, PyObject* args, void* nothing)
307 {
308         int scene;
309
310         if(!PyArg_Parse(args, "i:scene", &scene))
311                 return -1;
312
313         try
314         {
315                 if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->changeScene(scene))
316                         return 0;
317                 PyErr_SetString(AUDError, "Couldn't change the scene!");
318         }
319         catch(aud::Exception& e)
320         {
321                 PyErr_SetString(AUDError, e.what());
322         }
323
324         return -1;
325 }
326
327 static PyObject *
328 DynamicMusic_get_scene(DynamicMusicP* self, void* nothing)
329 {
330         try
331         {
332                 return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getScene());
333         }
334         catch(aud::Exception& e)
335         {
336                 PyErr_SetString(AUDError, e.what());
337                 return nullptr;
338         }
339 }
340
341 PyDoc_STRVAR(M_aud_DynamicMusic_volume_doc,
342         "The volume of the scene.");
343
344 static int
345 DynamicMusic_set_volume(DynamicMusicP* self, PyObject* args, void* nothing)
346 {
347         float volume;
348
349         if(!PyArg_Parse(args, "f:volume", &volume))
350                 return -1;
351
352         try
353         {
354                 if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setVolume(volume))
355                         return 0;
356                 PyErr_SetString(AUDError, "Couldn't change the volume!");
357         }
358         catch(aud::Exception& e)
359         {
360                 PyErr_SetString(AUDError, e.what());
361         }
362
363         return -1;
364 }
365
366 static PyObject *
367 DynamicMusic_get_volume(DynamicMusicP* self, void* nothing)
368 {
369         try
370         {
371                 return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getVolume());
372         }
373         catch(aud::Exception& e)
374         {
375                 PyErr_SetString(AUDError, e.what());
376                 return nullptr;
377         }
378 }
379
380 static PyGetSetDef DynamicMusic_properties[] = {
381         { (char*)"status", (getter)DynamicMusic_get_status, nullptr,
382         M_aud_DynamicMusic_status_doc, nullptr },
383         { (char*)"position", (getter)DynamicMusic_get_position, (setter)DynamicMusic_set_position,
384         M_aud_DynamicMusic_position_doc, nullptr },
385         { (char*)"fadeTime", (getter)DynamicMusic_get_fadeTime, (setter)DynamicMusic_set_fadeTime,
386         M_aud_DynamicMusic_fadeTime_doc, nullptr },
387         { (char*)"scene", (getter)DynamicMusic_get_scene, (setter)DynamicMusic_set_scene,
388         M_aud_DynamicMusic_scene_doc, nullptr },
389         { (char*)"volume", (getter)DynamicMusic_get_volume, (setter)DynamicMusic_set_volume,
390         M_aud_DynamicMusic_volume_doc, nullptr },
391         { nullptr }  /* Sentinel */
392 };
393
394 PyDoc_STRVAR(M_aud_DynamicMusic_doc,
395         "The DynamicMusic object allows to play music depending on a current scene, scene changes are managed by the class, with the possibility of custom transitions.\n"
396         "The default transition is a crossfade effect, and the default scene is silent and has id 0");
397
398 PyTypeObject DynamicMusicType = {
399         PyVarObject_HEAD_INIT(nullptr, 0)
400         "aud.DynamicMusic",                                             /* tp_name */
401         sizeof(DynamicMusicP),                                  /* tp_basicsize */
402         0,                                                                              /* tp_itemsize */
403         (destructor)DynamicMusic_dealloc,               /* tp_dealloc */
404         0,                                                                              /* tp_print */
405         0,                                                                              /* tp_getattr */
406         0,                                                                              /* tp_setattr */
407         0,                                                                              /* tp_reserved */
408         0,                                                                              /* tp_repr */
409         0,                                                                              /* tp_as_number */
410         0,                                                                              /* tp_as_sequence */
411         0,                                                                              /* tp_as_mapping */
412         0,                                                                              /* tp_hash  */
413         0,                                                                              /* tp_call */
414         0,                                                                              /* tp_str */
415         0,                                                                              /* tp_getattro */
416         0,                                                                              /* tp_setattro */
417         0,                                                                              /* tp_as_buffer */
418         Py_TPFLAGS_DEFAULT,                                             /* tp_flags */
419         M_aud_DynamicMusic_doc,                                 /* tp_doc */
420         0,                                                                              /* tp_traverse */
421         0,                                                                              /* tp_clear */
422         0,                                                                              /* tp_richcompare */
423         0,                                                                              /* tp_weaklistoffset */
424         0,                                                                              /* tp_iter */
425         0,                                                                              /* tp_iternext */
426         DynamicMusic_methods,                                   /* tp_methods */
427         0,                                                                              /* tp_members */
428         DynamicMusic_properties,                                /* tp_getset */
429         0,                                                                              /* tp_base */
430         0,                                                                              /* tp_dict */
431         0,                                                                              /* tp_descr_get */
432         0,                                                                              /* tp_descr_set */
433         0,                                                                              /* tp_dictoffset */
434         0,                                                                              /* tp_init */
435         0,                                                                              /* tp_alloc */
436         DynamicMusic_new,                                               /* tp_new */
437 };
438
439 AUD_API PyObject* DynamicMusic_empty()
440 {
441         return DynamicMusicType.tp_alloc(&DynamicMusicType, 0);
442 }
443
444
445 AUD_API DynamicMusicP* checkDynamicMusic(PyObject* dynamicMusic)
446 {
447         if(!PyObject_TypeCheck(dynamicMusic, &DynamicMusicType))
448         {
449                 PyErr_SetString(PyExc_TypeError, "Object is not of type DynamicMusic!");
450                 return nullptr;
451         }
452
453         return (DynamicMusicP*)dynamicMusic;
454 }
455
456
457 bool initializeDynamicMusic()
458 {
459         return PyType_Ready(&DynamicMusicType) >= 0;
460 }
461
462
463 void addDynamicMusicToModule(PyObject* module)
464 {
465         Py_INCREF(&DynamicMusicType);
466         PyModule_AddObject(module, "DynamicMusic", (PyObject *)&DynamicMusicType);
467 }