Changeset View
Changeset View
Standalone View
Standalone View
extern/audaspace/bindings/python/PyHandle.cpp
- This file was added.
| /******************************************************************************* | |||||
| * Copyright 2009-2016 Jörg Müller | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| ******************************************************************************/ | |||||
| #include "PyHandle.h" | |||||
| #include "devices/IHandle.h" | |||||
| #include "devices/I3DHandle.h" | |||||
| #include "Exception.h" | |||||
| #include <memory> | |||||
| #include <structmember.h> | |||||
| using namespace aud; | |||||
| extern PyObject* AUDError; | |||||
| static const char* device_not_3d_error = "Device is not a 3D device!"; | |||||
| static void | |||||
| Handle_dealloc(Handle* self) | |||||
| { | |||||
| if(self->handle) | |||||
| delete reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle); | |||||
| Py_TYPE(self)->tp_free((PyObject *)self); | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_pause_doc, | |||||
| "pause()\n\n" | |||||
| "Pauses playback.\n\n" | |||||
| ":return: Whether the action succeeded.\n" | |||||
| ":rtype: bool"); | |||||
| static PyObject * | |||||
| Handle_pause(Handle* self) | |||||
| { | |||||
| try | |||||
| { | |||||
| return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->pause()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_resume_doc, | |||||
| "resume()\n\n" | |||||
| "Resumes playback.\n\n" | |||||
| ":return: Whether the action succeeded.\n" | |||||
| ":rtype: bool"); | |||||
| static PyObject * | |||||
| Handle_resume(Handle* self) | |||||
| { | |||||
| try | |||||
| { | |||||
| return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->resume()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_stop_doc, | |||||
| "stop()\n\n" | |||||
| "Stops playback.\n\n" | |||||
| ":return: Whether the action succeeded.\n" | |||||
| ":rtype: bool\n\n" | |||||
| ".. note:: This makes the handle invalid."); | |||||
| static PyObject * | |||||
| Handle_stop(Handle* self) | |||||
| { | |||||
| try | |||||
| { | |||||
| return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->stop()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static PyMethodDef Handle_methods[] = { | |||||
| {"pause", (PyCFunction)Handle_pause, METH_NOARGS, | |||||
| M_aud_Handle_pause_doc | |||||
| }, | |||||
| {"resume", (PyCFunction)Handle_resume, METH_NOARGS, | |||||
| M_aud_Handle_resume_doc | |||||
| }, | |||||
| {"stop", (PyCFunction)Handle_stop, METH_NOARGS, | |||||
| M_aud_Handle_stop_doc | |||||
| }, | |||||
| {nullptr} /* Sentinel */ | |||||
| }; | |||||
| PyDoc_STRVAR(M_aud_Handle_attenuation_doc, | |||||
| "This factor is used for distance based attenuation of the " | |||||
| "source.\n\n" | |||||
| ".. seealso:: :attr:`Device.distance_model`"); | |||||
| static PyObject * | |||||
| Handle_get_attenuation(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getAttenuation()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_attenuation(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float factor; | |||||
| if(!PyArg_Parse(args, "f:attenuation", &factor)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setAttenuation(factor)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the attenuation!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc, | |||||
| "The opening angle of the inner cone of the source. If the cone " | |||||
| "values of a source are set there are two (audible) cones with " | |||||
| "the apex at the :attr:`location` of the source and with infinite " | |||||
| "height, heading in the direction of the source's " | |||||
| ":attr:`orientation`.\n" | |||||
| "In the inner cone the volume is normal. Outside the outer cone " | |||||
| "the volume will be :attr:`cone_volume_outer` and in the area " | |||||
| "between the volume will be interpolated linearly."); | |||||
| static PyObject * | |||||
| Handle_get_cone_angle_inner(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getConeAngleInner()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_cone_angle_inner(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float angle; | |||||
| if(!PyArg_Parse(args, "f:cone_angle_inner", &angle)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setConeAngleInner(angle)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the cone inner angle!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc, | |||||
| "The opening angle of the outer cone of the source.\n\n" | |||||
| ".. seealso:: :attr:`cone_angle_inner`"); | |||||
| static PyObject * | |||||
| Handle_get_cone_angle_outer(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getConeAngleOuter()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_cone_angle_outer(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float angle; | |||||
| if(!PyArg_Parse(args, "f:cone_angle_outer", &angle)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setConeAngleOuter(angle)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the cone outer angle!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc, | |||||
| "The volume outside the outer cone of the source.\n\n" | |||||
| ".. seealso:: :attr:`cone_angle_inner`"); | |||||
| static PyObject * | |||||
| Handle_get_cone_volume_outer(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getConeVolumeOuter()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_cone_volume_outer(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float volume; | |||||
| if(!PyArg_Parse(args, "f:cone_volume_outer", &volume)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setConeVolumeOuter(volume)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the cone outer volume!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc, | |||||
| "The maximum distance of the source.\n" | |||||
| "If the listener is further away the source volume will be 0.\n\n" | |||||
| ".. seealso:: :attr:`Device.distance_model`"); | |||||
| static PyObject * | |||||
| Handle_get_distance_maximum(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getDistanceMaximum()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_distance_maximum(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float distance; | |||||
| if(!PyArg_Parse(args, "f:distance_maximum", &distance)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setDistanceMaximum(distance)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the maximum distance!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_distance_reference_doc, | |||||
| "The reference distance of the source.\n" | |||||
| "At this distance the volume will be exactly :attr:`volume`.\n\n" | |||||
| ".. seealso:: :attr:`Device.distance_model`"); | |||||
| static PyObject * | |||||
| Handle_get_distance_reference(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getDistanceReference()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_distance_reference(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float distance; | |||||
| if(!PyArg_Parse(args, "f:distance_reference", &distance)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setDistanceReference(distance)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the reference distance!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_keep_doc, | |||||
| "Whether the sound should be kept paused in the device when its " | |||||
| "end is reached.\n" | |||||
| "This can be used to seek the sound to some position and start " | |||||
| "playback again.\n\n" | |||||
| ".. warning:: If this is set to true and you forget stopping this " | |||||
| "equals a memory leak as the handle exists until the device is " | |||||
| "destroyed."); | |||||
| static PyObject * | |||||
| Handle_get_keep(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getKeep()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_keep(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| if(!PyBool_Check(args)) | |||||
| { | |||||
| PyErr_SetString(PyExc_TypeError, "keep is not a boolean!"); | |||||
| return -1; | |||||
| } | |||||
| bool keep = args == Py_True; | |||||
| try | |||||
| { | |||||
| if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setKeep(keep)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set keep of the sound!"); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_location_doc, | |||||
| "The source's location in 3D space, a 3D tuple of floats."); | |||||
| static PyObject * | |||||
| Handle_get_location(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Vector3 v = handle->getLocation(); | |||||
| return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| static int | |||||
| Handle_set_location(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float x, y, z; | |||||
| if(!PyArg_Parse(args, "(fff):location", &x, &y, &z)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Vector3 location(x, y, z); | |||||
| if(handle->setLocation(location)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Location couldn't be set!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_loop_count_doc, | |||||
| "The (remaining) loop count of the sound. A negative value indicates infinity."); | |||||
| static PyObject * | |||||
| Handle_get_loop_count(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getLoopCount()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_loop_count(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| int loops; | |||||
| if(!PyArg_Parse(args, "i:loop_count", &loops)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setLoopCount(loops)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the loop count!"); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_orientation_doc, | |||||
| "The source's orientation in 3D space as quaternion, a 4 float tuple."); | |||||
| static PyObject * | |||||
| Handle_get_orientation(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Quaternion o = handle->getOrientation(); | |||||
| return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| static int | |||||
| Handle_set_orientation(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float w, x, y, z; | |||||
| if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Quaternion orientation(w, x, y, z); | |||||
| if(handle->setOrientation(orientation)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the orientation!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_pitch_doc, | |||||
| "The pitch of the sound."); | |||||
| static PyObject * | |||||
| Handle_get_pitch(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPitch()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_pitch(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float pitch; | |||||
| if(!PyArg_Parse(args, "f:pitch", &pitch)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setPitch(pitch)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the sound pitch!"); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_position_doc, | |||||
| "The playback position of the sound in seconds."); | |||||
| static PyObject * | |||||
| Handle_get_position(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPosition()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_position(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float position; | |||||
| if(!PyArg_Parse(args, "f:position", &position)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->seek(position)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't seek the sound!"); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_relative_doc, | |||||
| "Whether the source's location, velocity and orientation is relative or absolute to the listener."); | |||||
| static PyObject * | |||||
| Handle_get_relative(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return PyBool_FromLong((long)handle->isRelative()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| static int | |||||
| Handle_set_relative(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| if(!PyBool_Check(args)) | |||||
| { | |||||
| PyErr_SetString(PyExc_TypeError, "Value is not a boolean!"); | |||||
| return -1; | |||||
| } | |||||
| bool relative = (args == Py_True); | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setRelative(relative)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the relativeness!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_status_doc, | |||||
| "Whether the sound is playing, paused or stopped (=invalid)."); | |||||
| static PyObject * | |||||
| Handle_get_status(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getStatus()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_velocity_doc, | |||||
| "The source's velocity in 3D space, a 3D tuple of floats."); | |||||
| static PyObject * | |||||
| Handle_get_velocity(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Vector3 v = handle->getVelocity(); | |||||
| return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| static int | |||||
| Handle_set_velocity(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float x, y, z; | |||||
| if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| Vector3 velocity(x, y, z); | |||||
| if(handle->setVelocity(velocity)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the velocity!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_volume_doc, | |||||
| "The volume of the sound."); | |||||
| static PyObject * | |||||
| Handle_get_volume(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getVolume()); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_volume(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float volume; | |||||
| if(!PyArg_Parse(args, "f:volume", &volume)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setVolume(volume)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the sound volume!"); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc, | |||||
| "The maximum volume of the source.\n\n" | |||||
| ".. seealso:: :attr:`Device.distance_model`"); | |||||
| static PyObject * | |||||
| Handle_get_volume_maximum(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getVolumeMaximum()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_volume_maximum(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float volume; | |||||
| if(!PyArg_Parse(args, "f:volume_maximum", &volume)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setVolumeMaximum(volume)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the maximum volume!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc, | |||||
| "The minimum volume of the source.\n\n" | |||||
| ".. seealso:: :attr:`Device.distance_model`"); | |||||
| static PyObject * | |||||
| Handle_get_volume_minimum(Handle* self, void* nothing) | |||||
| { | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| return Py_BuildValue("f", handle->getVolumeMinimum()); | |||||
| } | |||||
| else | |||||
| { | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| static int | |||||
| Handle_set_volume_minimum(Handle* self, PyObject* args, void* nothing) | |||||
| { | |||||
| float volume; | |||||
| if(!PyArg_Parse(args, "f:volume_minimum", &volume)) | |||||
| return -1; | |||||
| try | |||||
| { | |||||
| I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get()); | |||||
| if(handle) | |||||
| { | |||||
| if(handle->setVolumeMinimum(volume)) | |||||
| return 0; | |||||
| PyErr_SetString(AUDError, "Couldn't set the minimum volume!"); | |||||
| } | |||||
| else | |||||
| PyErr_SetString(AUDError, device_not_3d_error); | |||||
| } | |||||
| catch(Exception& e) | |||||
| { | |||||
| PyErr_SetString(AUDError, e.what()); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| static PyGetSetDef Handle_properties[] = { | |||||
| {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation, | |||||
| M_aud_Handle_attenuation_doc, nullptr }, | |||||
| {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner, | |||||
| M_aud_Handle_cone_angle_inner_doc, nullptr }, | |||||
| {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer, | |||||
| M_aud_Handle_cone_angle_outer_doc, nullptr }, | |||||
| {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer, | |||||
| M_aud_Handle_cone_volume_outer_doc, nullptr }, | |||||
| {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum, | |||||
| M_aud_Handle_distance_maximum_doc, nullptr }, | |||||
| {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference, | |||||
| M_aud_Handle_distance_reference_doc, nullptr }, | |||||
| {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep, | |||||
| M_aud_Handle_keep_doc, nullptr }, | |||||
| {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location, | |||||
| M_aud_Handle_location_doc, nullptr }, | |||||
| {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count, | |||||
| M_aud_Handle_loop_count_doc, nullptr }, | |||||
| {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation, | |||||
| M_aud_Handle_orientation_doc, nullptr }, | |||||
| {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch, | |||||
| M_aud_Handle_pitch_doc, nullptr }, | |||||
| {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position, | |||||
| M_aud_Handle_position_doc, nullptr }, | |||||
| {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative, | |||||
| M_aud_Handle_relative_doc, nullptr }, | |||||
| {(char*)"status", (getter)Handle_get_status, nullptr, | |||||
| M_aud_Handle_status_doc, nullptr }, | |||||
| {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity, | |||||
| M_aud_Handle_velocity_doc, nullptr }, | |||||
| {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume, | |||||
| M_aud_Handle_volume_doc, nullptr }, | |||||
| {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum, | |||||
| M_aud_Handle_volume_maximum_doc, nullptr }, | |||||
| {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum, | |||||
| M_aud_Handle_volume_minimum_doc, nullptr }, | |||||
| {nullptr} /* Sentinel */ | |||||
| }; | |||||
| PyDoc_STRVAR(M_aud_Handle_doc, | |||||
| "Handle objects are playback handles that can be used to control " | |||||
| "playback of a sound. If a sound is played back multiple times " | |||||
| "then there are as many handles."); | |||||
| static PyTypeObject HandleType = { | |||||
| PyVarObject_HEAD_INIT(nullptr, 0) | |||||
| "aud.Handle", /* tp_name */ | |||||
| sizeof(Handle), /* tp_basicsize */ | |||||
| 0, /* tp_itemsize */ | |||||
| (destructor)Handle_dealloc,/* tp_dealloc */ | |||||
| 0, /* tp_print */ | |||||
| 0, /* tp_getattr */ | |||||
| 0, /* tp_setattr */ | |||||
| 0, /* tp_reserved */ | |||||
| 0, /* tp_repr */ | |||||
| 0, /* tp_as_number */ | |||||
| 0, /* tp_as_sequence */ | |||||
| 0, /* tp_as_mapping */ | |||||
| 0, /* tp_hash */ | |||||
| 0, /* tp_call */ | |||||
| 0, /* tp_str */ | |||||
| 0, /* tp_getattro */ | |||||
| 0, /* tp_setattro */ | |||||
| 0, /* tp_as_buffer */ | |||||
| Py_TPFLAGS_DEFAULT, /* tp_flags */ | |||||
| M_aud_Handle_doc, /* tp_doc */ | |||||
| 0, /* tp_traverse */ | |||||
| 0, /* tp_clear */ | |||||
| 0, /* tp_richcompare */ | |||||
| 0, /* tp_weaklistoffset */ | |||||
| 0, /* tp_iter */ | |||||
| 0, /* tp_iternext */ | |||||
| Handle_methods, /* tp_methods */ | |||||
| 0, /* tp_members */ | |||||
| Handle_properties, /* tp_getset */ | |||||
| 0, /* tp_base */ | |||||
| 0, /* tp_dict */ | |||||
| 0, /* tp_descr_get */ | |||||
| 0, /* tp_descr_set */ | |||||
| 0, /* tp_dictoffset */ | |||||
| 0, /* tp_init */ | |||||
| 0, /* tp_alloc */ | |||||
| 0, /* tp_new */ | |||||
| }; | |||||
| AUD_API PyObject* Handle_empty() | |||||
| { | |||||
| return HandleType.tp_alloc(&HandleType, 0); | |||||
| } | |||||
| AUD_API Handle*checkHandle(PyObject* handle) | |||||
| { | |||||
| if(!PyObject_TypeCheck(handle, &HandleType)) | |||||
| { | |||||
| PyErr_SetString(PyExc_TypeError, "Object is not of type Handle!"); | |||||
| return nullptr; | |||||
| } | |||||
| return (Handle*)handle; | |||||
| } | |||||
| bool initializeHandle() | |||||
| { | |||||
| return PyType_Ready(&HandleType) >= 0; | |||||
| } | |||||
| void addHandleToModule(PyObject* module) | |||||
| { | |||||
| Py_INCREF(&HandleType); | |||||
| PyModule_AddObject(module, "Handle", (PyObject *)&HandleType); | |||||
| } | |||||