1 /*******************************************************************************
2 * Copyright 2009-2016 Jörg Müller
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 "PySequenceEntry.h"
18
19 #include "PySound.h"
20
21 #include "Exception.h"
22 #include "sequence/AnimateableProperty.h"
23 #include "sequence/SequenceEntry.h"
24
25 #include <structmember.h>
26 #include <vector>
27
28 using aud::Exception;
29 using aud::AnimateableProperty;
30 using aud::AnimateablePropertyType;
31 using aud::ISound;
32
33 extern PyObject* AUDError;
34
35 // ====================================================================
36
37 static void
SequenceEntry_dealloc(SequenceEntry * self)38 SequenceEntry_dealloc(SequenceEntry* self)
39 {
40 if(self->entry)
41 delete reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
42 Py_TYPE(self)->tp_free((PyObject *)self);
43 }
44
45 PyDoc_STRVAR(M_aud_SequenceEntry_move_doc,
46 ".. classmethod:: move()\n\n"
47 " Moves the entry.\n\n"
48 " :arg begin: The new start time.\n"
49 " :type begin: double\n"
50 " :arg end: The new end time or a negative value if unknown.\n"
51 " :type end: double\n"
52 " :arg skip: How many seconds to skip at the beginning.\n"
53 " :type skip: double\n");
54
55 static PyObject *
SequenceEntry_move(SequenceEntry * self,PyObject * args)56 SequenceEntry_move(SequenceEntry* self, PyObject* args)
57 {
58 double begin, end, skip;
59
60 if(!PyArg_ParseTuple(args, "ddd:move", &begin, &end, &skip))
61 return nullptr;
62
63 try
64 {
65 (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->move(begin, end, skip);
66 Py_RETURN_NONE;
67 }
68 catch(Exception& e)
69 {
70 PyErr_SetString(AUDError, e.what());
71 return nullptr;
72 }
73 }
74
75 PyDoc_STRVAR(M_aud_SequenceEntry_setAnimationData_doc,
76 ".. classmethod:: setAnimationData()\n\n"
77 " Writes animation data to a sequenced entry.\n\n"
78 " :arg type: The type of animation data.\n"
79 " :type type: int\n"
80 " :arg frame: The frame this data is for.\n"
81 " :type frame: int\n"
82 " :arg data: The data to write.\n"
83 " :type data: sequence of float\n"
84 " :arg animated: Whether the attribute is animated.\n"
85 " :type animated: bool");
86
87 static PyObject *
SequenceEntry_setAnimationData(SequenceEntry * self,PyObject * args)88 SequenceEntry_setAnimationData(SequenceEntry* self, PyObject* args)
89 {
90 int type, frame;
91 PyObject* py_data;
92 Py_ssize_t py_data_len;
93 PyObject* animatedo;
94 bool animated;
95
96 if(!PyArg_ParseTuple(args, "iiOO:setAnimationData", &type, &frame, &py_data, &animatedo))
97 return nullptr;
98
99 if(!PySequence_Check(py_data))
100 {
101 PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
102 return nullptr;
103 }
104
105 py_data_len= PySequence_Size(py_data);
106
107 std::vector<float> data;
108 data.resize(py_data_len);
109
110 PyObject* py_value;
111 float value;
112
113 for(Py_ssize_t i = 0; i < py_data_len; i++)
114 {
115 py_value = PySequence_GetItem(py_data, i);
116 value= (float)PyFloat_AsDouble(py_value);
117 Py_DECREF(py_value);
118
119 if(value == -1.0f && PyErr_Occurred()) {
120 return nullptr;
121 }
122
123 data.push_back(value);
124 }
125
126 if(!PyBool_Check(animatedo))
127 {
128 PyErr_SetString(PyExc_TypeError, "animated is not a boolean!");
129 return nullptr;
130 }
131
132 animated = animatedo == Py_True;
133
134 try
135 {
136 AnimateableProperty* prop = (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->getAnimProperty(static_cast<AnimateablePropertyType>(type));
137
138 if(prop->getCount() != py_data_len)
139 {
140 PyErr_SetString(PyExc_ValueError, "the amount of floats doesn't fit the animated property");
141 return nullptr;
142 }
143
144 if(animated)
145 {
146 if(frame >= 0)
147 prop->write(&data[0], frame, 1);
148 }
149 else
150 {
151 prop->write(&data[0]);
152 }
153 Py_RETURN_NONE;
154 }
155 catch(Exception& e)
156 {
157 PyErr_SetString(AUDError, e.what());
158 return nullptr;
159 }
160 }
161
162 static PyMethodDef SequenceEntry_methods[] = {
163 {"move", (PyCFunction)SequenceEntry_move, METH_VARARGS,
164 M_aud_SequenceEntry_move_doc
165 },
166 {"setAnimationData", (PyCFunction)SequenceEntry_setAnimationData, METH_VARARGS,
167 M_aud_SequenceEntry_setAnimationData_doc
168 },
169 {nullptr} /* Sentinel */
170 };
171
172 PyDoc_STRVAR(M_aud_SequenceEntry_attenuation_doc,
173 "This factor is used for distance based attenuation of the "
174 "source.\n\n"
175 ".. seealso:: :attr:`Device.distance_model`");
176
177 static PyObject *
SequenceEntry_get_attenuation(SequenceEntry * self,void * nothing)178 SequenceEntry_get_attenuation(SequenceEntry* self, void* nothing)
179 {
180 try
181 {
182 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
183 return Py_BuildValue("f", (*entry)->getAttenuation());
184 }
185 catch(Exception& e)
186 {
187 PyErr_SetString(AUDError, e.what());
188 return nullptr;
189 }
190 }
191
192 static int
SequenceEntry_set_attenuation(SequenceEntry * self,PyObject * args,void * nothing)193 SequenceEntry_set_attenuation(SequenceEntry* self, PyObject* args, void* nothing)
194 {
195 float factor;
196
197 if(!PyArg_Parse(args, "f:attenuation", &factor))
198 return -1;
199
200 try
201 {
202 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
203 (*entry)->setAttenuation(factor);
204 return 0;
205 }
206 catch(Exception& e)
207 {
208 PyErr_SetString(AUDError, e.what());
209 }
210
211 return -1;
212 }
213
214 PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_inner_doc,
215 "The opening angle of the inner cone of the source. If the cone "
216 "values of a source are set there are two (audible) cones with "
217 "the apex at the :attr:`location` of the source and with infinite "
218 "height, heading in the direction of the source's "
219 ":attr:`orientation`.\n"
220 "In the inner cone the volume is normal. Outside the outer cone "
221 "the volume will be :attr:`cone_volume_outer` and in the area "
222 "between the volume will be interpolated linearly.");
223
224 static PyObject *
SequenceEntry_get_cone_angle_inner(SequenceEntry * self,void * nothing)225 SequenceEntry_get_cone_angle_inner(SequenceEntry* self, void* nothing)
226 {
227 try
228 {
229 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
230 return Py_BuildValue("f", (*entry)->getConeAngleInner());
231 }
232 catch(Exception& e)
233 {
234 PyErr_SetString(AUDError, e.what());
235 return nullptr;
236 }
237 }
238
239 static int
SequenceEntry_set_cone_angle_inner(SequenceEntry * self,PyObject * args,void * nothing)240 SequenceEntry_set_cone_angle_inner(SequenceEntry* self, PyObject* args, void* nothing)
241 {
242 float angle;
243
244 if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
245 return -1;
246
247 try
248 {
249 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
250 (*entry)->setConeAngleInner(angle);
251 return 0;
252 }
253 catch(Exception& e)
254 {
255 PyErr_SetString(AUDError, e.what());
256 }
257
258 return -1;
259 }
260
261 PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_outer_doc,
262 "The opening angle of the outer cone of the source.\n\n"
263 ".. seealso:: :attr:`cone_angle_inner`");
264
265 static PyObject *
SequenceEntry_get_cone_angle_outer(SequenceEntry * self,void * nothing)266 SequenceEntry_get_cone_angle_outer(SequenceEntry* self, void* nothing)
267 {
268 try
269 {
270 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
271 return Py_BuildValue("f", (*entry)->getConeAngleOuter());
272 }
273 catch(Exception& e)
274 {
275 PyErr_SetString(AUDError, e.what());
276 return nullptr;
277 }
278 }
279
280 static int
SequenceEntry_set_cone_angle_outer(SequenceEntry * self,PyObject * args,void * nothing)281 SequenceEntry_set_cone_angle_outer(SequenceEntry* self, PyObject* args, void* nothing)
282 {
283 float angle;
284
285 if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
286 return -1;
287
288 try
289 {
290 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
291 (*entry)->setConeAngleOuter(angle);
292 return 0;
293 }
294 catch(Exception& e)
295 {
296 PyErr_SetString(AUDError, e.what());
297 }
298
299 return -1;
300 }
301
302 PyDoc_STRVAR(M_aud_SequenceEntry_cone_volume_outer_doc,
303 "The volume outside the outer cone of the source.\n\n"
304 ".. seealso:: :attr:`cone_angle_inner`");
305
306 static PyObject *
SequenceEntry_get_cone_volume_outer(SequenceEntry * self,void * nothing)307 SequenceEntry_get_cone_volume_outer(SequenceEntry* self, void* nothing)
308 {
309 try
310 {
311 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
312 return Py_BuildValue("f", (*entry)->getConeVolumeOuter());
313 }
314 catch(Exception& e)
315 {
316 PyErr_SetString(AUDError, e.what());
317 return nullptr;
318 }
319 }
320
321 static int
SequenceEntry_set_cone_volume_outer(SequenceEntry * self,PyObject * args,void * nothing)322 SequenceEntry_set_cone_volume_outer(SequenceEntry* self, PyObject* args, void* nothing)
323 {
324 float volume;
325
326 if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
327 return -1;
328
329 try
330 {
331 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
332 (*entry)->setConeVolumeOuter(volume);
333 return 0;
334 }
335 catch(Exception& e)
336 {
337 PyErr_SetString(AUDError, e.what());
338 }
339
340 return -1;
341 }
342
343 PyDoc_STRVAR(M_aud_SequenceEntry_distance_maximum_doc,
344 "The maximum distance of the source.\n"
345 "If the listener is further away the source volume will be 0.\n\n"
346 ".. seealso:: :attr:`Device.distance_model`");
347
348 static PyObject *
SequenceEntry_get_distance_maximum(SequenceEntry * self,void * nothing)349 SequenceEntry_get_distance_maximum(SequenceEntry* self, void* nothing)
350 {
351 try
352 {
353 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
354 return Py_BuildValue("f", (*entry)->getDistanceMaximum());
355 }
356 catch(Exception& e)
357 {
358 PyErr_SetString(AUDError, e.what());
359 return nullptr;
360 }
361 }
362
363 static int
SequenceEntry_set_distance_maximum(SequenceEntry * self,PyObject * args,void * nothing)364 SequenceEntry_set_distance_maximum(SequenceEntry* self, PyObject* args, void* nothing)
365 {
366 float distance;
367
368 if(!PyArg_Parse(args, "f:distance_maximum", &distance))
369 return -1;
370
371 try
372 {
373 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
374 (*entry)->setDistanceMaximum(distance);
375 return 0;
376 }
377 catch(Exception& e)
378 {
379 PyErr_SetString(AUDError, e.what());
380 }
381
382 return -1;
383 }
384
385 PyDoc_STRVAR(M_aud_SequenceEntry_distance_reference_doc,
386 "The reference distance of the source.\n"
387 "At this distance the volume will be exactly :attr:`volume`.\n\n"
388 ".. seealso:: :attr:`Device.distance_model`");
389
390 static PyObject *
SequenceEntry_get_distance_reference(SequenceEntry * self,void * nothing)391 SequenceEntry_get_distance_reference(SequenceEntry* self, void* nothing)
392 {
393 try
394 {
395 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
396 return Py_BuildValue("f", (*entry)->getDistanceReference());
397 }
398 catch(Exception& e)
399 {
400 PyErr_SetString(AUDError, e.what());
401 return nullptr;
402 }
403 }
404
405 static int
SequenceEntry_set_distance_reference(SequenceEntry * self,PyObject * args,void * nothing)406 SequenceEntry_set_distance_reference(SequenceEntry* self, PyObject* args, void* nothing)
407 {
408 float distance;
409
410 if(!PyArg_Parse(args, "f:distance_reference", &distance))
411 return -1;
412
413 try
414 {
415 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
416 (*entry)->setDistanceReference(distance);
417 return 0;
418 }
419 catch(Exception& e)
420 {
421 PyErr_SetString(AUDError, e.what());
422 }
423
424 return -1;
425 }
426
427 PyDoc_STRVAR(M_aud_SequenceEntry_muted_doc,
428 "Whether the entry is muted.\n");
429
430 static PyObject *
SequenceEntry_get_muted(SequenceEntry * self,void * nothing)431 SequenceEntry_get_muted(SequenceEntry* self, void* nothing)
432 {
433 try
434 {
435 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
436 return PyBool_FromLong((long)(*entry)->isMuted());
437 }
438 catch(Exception& e)
439 {
440 PyErr_SetString(AUDError, e.what());
441 return nullptr;
442 }
443 }
444
445 static int
SequenceEntry_set_muted(SequenceEntry * self,PyObject * args,void * nothing)446 SequenceEntry_set_muted(SequenceEntry* self, PyObject* args, void* nothing)
447 {
448 if(!PyBool_Check(args))
449 {
450 PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
451 return -1;
452 }
453
454 bool muted = args == Py_True;
455
456 try
457 {
458 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
459 (*entry)->mute(muted);
460 return 0;
461 }
462 catch(Exception& e)
463 {
464 PyErr_SetString(AUDError, e.what());
465 }
466
467 return -1;
468 }
469
470 PyDoc_STRVAR(M_aud_SequenceEntry_relative_doc,
471 "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
472
473 static PyObject *
SequenceEntry_get_relative(SequenceEntry * self,void * nothing)474 SequenceEntry_get_relative(SequenceEntry* self, void* nothing)
475 {
476 try
477 {
478 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
479 return PyBool_FromLong((long)(*entry)->isRelative());
480 }
481 catch(Exception& e)
482 {
483 PyErr_SetString(AUDError, e.what());
484 }
485
486 return nullptr;
487 }
488
489 static int
SequenceEntry_set_relative(SequenceEntry * self,PyObject * args,void * nothing)490 SequenceEntry_set_relative(SequenceEntry* self, PyObject* args, void* nothing)
491 {
492 if(!PyBool_Check(args))
493 {
494 PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
495 return -1;
496 }
497
498 bool relative = (args == Py_True);
499
500 try
501 {
502 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
503 (*entry)->setRelative(relative);
504 return 0;
505 }
506 catch(Exception& e)
507 {
508 PyErr_SetString(AUDError, e.what());
509 }
510
511 return -1;
512 }
513
514 PyDoc_STRVAR(M_aud_SequenceEntry_sound_doc,
515 "The sound the entry is representing and will be played in the sequence.");
516
517 static PyObject *
SequenceEntry_get_sound(SequenceEntry * self,void * nothing)518 SequenceEntry_get_sound(SequenceEntry* self, void* nothing)
519 {
520 try
521 {
522 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
523 Sound* object = (Sound*) Sound_empty();
524 if(object)
525 {
526 object->sound = new std::shared_ptr<ISound>((*entry)->getSound());
527 return (PyObject *) object;
528 }
529 }
530 catch(Exception& e)
531 {
532 PyErr_SetString(AUDError, e.what());
533 }
534
535 return nullptr;
536 }
537
538 static int
SequenceEntry_set_sound(SequenceEntry * self,PyObject * args,void * nothing)539 SequenceEntry_set_sound(SequenceEntry* self, PyObject* args, void* nothing)
540 {
541 Sound* sound = checkSound(args);
542
543 if(!sound)
544 return -1;
545
546 try
547 {
548 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
549 (*entry)->setSound(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound));
550 return 0;
551 }
552 catch(Exception& e)
553 {
554 PyErr_SetString(AUDError, e.what());
555 }
556
557 return -1;
558 }
559
560 PyDoc_STRVAR(M_aud_SequenceEntry_volume_maximum_doc,
561 "The maximum volume of the source.\n\n"
562 ".. seealso:: :attr:`Device.distance_model`");
563
564 static PyObject *
SequenceEntry_get_volume_maximum(SequenceEntry * self,void * nothing)565 SequenceEntry_get_volume_maximum(SequenceEntry* self, void* nothing)
566 {
567 try
568 {
569 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
570 return Py_BuildValue("f", (*entry)->getVolumeMaximum());
571 }
572 catch(Exception& e)
573 {
574 PyErr_SetString(AUDError, e.what());
575 return nullptr;
576 }
577 }
578
579 static int
SequenceEntry_set_volume_maximum(SequenceEntry * self,PyObject * args,void * nothing)580 SequenceEntry_set_volume_maximum(SequenceEntry* self, PyObject* args, void* nothing)
581 {
582 float volume;
583
584 if(!PyArg_Parse(args, "f:volume_maximum", &volume))
585 return -1;
586
587 try
588 {
589 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
590 (*entry)->setVolumeMaximum(volume);
591 return 0;
592 }
593 catch(Exception& e)
594 {
595 PyErr_SetString(AUDError, e.what());
596 }
597
598 return -1;
599 }
600
601 PyDoc_STRVAR(M_aud_SequenceEntry_volume_minimum_doc,
602 "The minimum volume of the source.\n\n"
603 ".. seealso:: :attr:`Device.distance_model`");
604
605 static PyObject *
SequenceEntry_get_volume_minimum(SequenceEntry * self,void * nothing)606 SequenceEntry_get_volume_minimum(SequenceEntry* self, void* nothing)
607 {
608 try
609 {
610 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
611 return Py_BuildValue("f", (*entry)->getVolumeMinimum());
612 }
613 catch(Exception& e)
614 {
615 PyErr_SetString(AUDError, e.what());
616 return nullptr;
617 }
618 }
619
620 static int
SequenceEntry_set_volume_minimum(SequenceEntry * self,PyObject * args,void * nothing)621 SequenceEntry_set_volume_minimum(SequenceEntry* self, PyObject* args, void* nothing)
622 {
623 float volume;
624
625 if(!PyArg_Parse(args, "f:volume_minimum", &volume))
626 return -1;
627
628 try
629 {
630 std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
631 (*entry)->setVolumeMinimum(volume);
632 return 0;
633 }
634 catch(Exception& e)
635 {
636 PyErr_SetString(AUDError, e.what());
637 }
638
639 return -1;
640 }
641
642 static PyGetSetDef SequenceEntry_properties[] = {
643 {(char*)"attenuation", (getter)SequenceEntry_get_attenuation, (setter)SequenceEntry_set_attenuation,
644 M_aud_SequenceEntry_attenuation_doc, nullptr },
645 {(char*)"cone_angle_inner", (getter)SequenceEntry_get_cone_angle_inner, (setter)SequenceEntry_set_cone_angle_inner,
646 M_aud_SequenceEntry_cone_angle_inner_doc, nullptr },
647 {(char*)"cone_angle_outer", (getter)SequenceEntry_get_cone_angle_outer, (setter)SequenceEntry_set_cone_angle_outer,
648 M_aud_SequenceEntry_cone_angle_outer_doc, nullptr },
649 {(char*)"cone_volume_outer", (getter)SequenceEntry_get_cone_volume_outer, (setter)SequenceEntry_set_cone_volume_outer,
650 M_aud_SequenceEntry_cone_volume_outer_doc, nullptr },
651 {(char*)"distance_maximum", (getter)SequenceEntry_get_distance_maximum, (setter)SequenceEntry_set_distance_maximum,
652 M_aud_SequenceEntry_distance_maximum_doc, nullptr },
653 {(char*)"distance_reference", (getter)SequenceEntry_get_distance_reference, (setter)SequenceEntry_set_distance_reference,
654 M_aud_SequenceEntry_distance_reference_doc, nullptr },
655 {(char*)"muted", (getter)SequenceEntry_get_muted, (setter)SequenceEntry_set_muted,
656 M_aud_SequenceEntry_muted_doc, nullptr },
657 {(char*)"relative", (getter)SequenceEntry_get_relative, (setter)SequenceEntry_set_relative,
658 M_aud_SequenceEntry_relative_doc, nullptr },
659 {(char*)"sound", (getter)SequenceEntry_get_sound, (setter)SequenceEntry_set_sound,
660 M_aud_SequenceEntry_sound_doc, nullptr },
661 {(char*)"volume_maximum", (getter)SequenceEntry_get_volume_maximum, (setter)SequenceEntry_set_volume_maximum,
662 M_aud_SequenceEntry_volume_maximum_doc, nullptr },
663 {(char*)"volume_minimum", (getter)SequenceEntry_get_volume_minimum, (setter)SequenceEntry_set_volume_minimum,
664 M_aud_SequenceEntry_volume_minimum_doc, nullptr },
665 {nullptr} /* Sentinel */
666 };
667
668 PyDoc_STRVAR(M_aud_SequenceEntry_doc,
669 "SequenceEntry objects represent an entry of a sequenced sound.");
670
671 static PyTypeObject SequenceEntryType = {
672 PyVarObject_HEAD_INIT(nullptr, 0)
673 "aud.SequenceEntry", /* tp_name */
674 sizeof(SequenceEntry), /* tp_basicsize */
675 0, /* tp_itemsize */
676 (destructor)SequenceEntry_dealloc, /* tp_dealloc */
677 0, /* tp_print */
678 0, /* tp_getattr */
679 0, /* tp_setattr */
680 0, /* tp_reserved */
681 0, /* tp_repr */
682 0, /* tp_as_number */
683 0, /* tp_as_sequence */
684 0, /* tp_as_mapping */
685 0, /* tp_hash */
686 0, /* tp_call */
687 0, /* tp_str */
688 0, /* tp_getattro */
689 0, /* tp_setattro */
690 0, /* tp_as_buffer */
691 Py_TPFLAGS_DEFAULT, /* tp_flags */
692 M_aud_SequenceEntry_doc, /* tp_doc */
693 0, /* tp_traverse */
694 0, /* tp_clear */
695 0, /* tp_richcompare */
696 0, /* tp_weaklistoffset */
697 0, /* tp_iter */
698 0, /* tp_iternext */
699 SequenceEntry_methods, /* tp_methods */
700 0, /* tp_members */
701 SequenceEntry_properties, /* tp_getset */
702 0, /* tp_base */
703 0, /* tp_dict */
704 0, /* tp_descr_get */
705 0, /* tp_descr_set */
706 0, /* tp_dictoffset */
707 0, /* tp_init */
708 0, /* tp_alloc */
709 0, /* tp_new */
710 };
711
SequenceEntry_empty()712 AUD_API PyObject* SequenceEntry_empty()
713 {
714 return SequenceEntryType.tp_alloc(&SequenceEntryType, 0);
715 }
716
717
checkSequenceEntry(PyObject * entry)718 AUD_API SequenceEntry* checkSequenceEntry(PyObject* entry)
719 {
720 if(!PyObject_TypeCheck(entry, &SequenceEntryType))
721 {
722 PyErr_SetString(PyExc_TypeError, "Object is not of type SequenceEntry!");
723 return nullptr;
724 }
725
726 return (SequenceEntry*)entry;
727 }
728
729
initializeSequenceEntry()730 bool initializeSequenceEntry()
731 {
732 return PyType_Ready(&SequenceEntryType) >= 0;
733 }
734
735
addSequenceEntryToModule(PyObject * module)736 void addSequenceEntryToModule(PyObject* module)
737 {
738 Py_INCREF(&SequenceEntryType);
739 PyModule_AddObject(module, "SequenceEntry", (PyObject *)&SequenceEntryType);
740 }
741