tmp
[blender.git] / extern / audaspace / bindings / python / PyHRTF.cpp
1 /*******************************************************************************
2 * Copyright 2009-2015 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 "PyHRTF.h"
18 #include "PySound.h"
19
20 #include "Exception.h"
21 #include "fx/HRTF.h"
22 #include "fx/HRTFLoader.h"
23
24 extern PyObject* AUDError;
25
26 static PyObject *
27 HRTF_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
28 {
29         HRTFP* self = (HRTFP*)type->tp_alloc(type, 0);
30
31         if(self != nullptr)
32         {
33                 try
34                 {
35                         self->hrtf = new std::shared_ptr<aud::HRTF>(new aud::HRTF());
36                 }
37                 catch(aud::Exception& e)
38                 {
39                         Py_DECREF(self);
40                         PyErr_SetString(AUDError, e.what());
41                         return nullptr;
42                 }
43         }
44
45         return (PyObject *)self;
46 }
47
48 static void
49 HRTF_dealloc(HRTFP* self)
50 {
51         if(self->hrtf)
52                 delete reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf);
53         Py_TYPE(self)->tp_free((PyObject *)self);
54 }
55
56 PyDoc_STRVAR(M_aud_HRTF_addImpulseResponse_doc,
57         "addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
58         "Adds a new hrtf to the HRTF object\n\n"
59         ":arg sound: The sound that contains the hrtf.\n"
60         ":type sound: :class:`Sound`\n"
61         ":arg azimuth: The azimuth angle of the hrtf.\n"
62         ":type azimuth: float\n"
63         ":arg elevation: The elevation angle of the hrtf.\n"
64         ":type elevation: float\n"
65         ":return: Whether the action succeeded.\n"
66         ":rtype: bool");
67
68 static PyObject *
69 HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
70 {
71         PyObject* object;
72         float azimuth, elevation;
73
74         if(!PyArg_ParseTuple(args, "Off:hrtf", &object, &azimuth, &elevation))
75                 return nullptr;
76
77         Sound* ir = checkSound(object);
78         if(!ir)
79                 return nullptr;
80
81         try
82         {
83                 return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf))->addImpulseResponse(std::make_shared<aud::StreamBuffer>(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(ir->sound)), azimuth, elevation));
84         }
85         catch(aud::Exception& e)
86         {
87                 PyErr_SetString(AUDError, e.what());
88                 return nullptr;
89         }
90 }
91
92 PyDoc_STRVAR(M_aud_HRTF_loadLeftHrtfSet_doc,
93         "loadLeftHrtfSet(extension, directory)\n\n"
94         "Loads all HRTFs from a directory.\n\n"
95         ":arg extension: The file extension of the hrtfs.\n"
96         ":type extension: string\n"
97         ":arg directory: The path to where the HRTF files are located.\n"
98         ":type extension: string\n"
99         ":return: The loaded :class:`HRTF` object.\n"
100         ":rtype: :class:`HRTF`\n\n");
101
102 static PyObject *
103 HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
104 {
105         const char* dir = nullptr;
106         const char* ext = nullptr;
107
108         if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
109                 return nullptr;
110
111         HRTFP* self;
112         self = (HRTFP*)type->tp_alloc(type, 0);
113
114         try
115         {
116                 self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadLeftHRTFs(ext, dir));
117         }
118         catch(aud::Exception& e)
119         {
120                 Py_DECREF(self);
121                 PyErr_SetString(AUDError, e.what());
122                 return nullptr;
123         }
124         return (PyObject *)self;
125 }
126
127 PyDoc_STRVAR(M_aud_HRTF_loadRightHrtfSet_doc,
128         "loadLeftHrtfSet(extension, directory)\n\n"
129         "Loads all HRTFs from a directory.\n\n"
130         ":arg extension: The file extension of the hrtfs.\n"
131         ":type extension: string\n"
132         ":arg directory: The path to where the HRTF files are located.\n"
133         ":type extension: string\n"
134         ":return: The loaded :class:`HRTF` object.\n"
135         ":rtype: :class:`HRTF`\n\n");
136
137 static PyObject *
138 HRTF_loadRightHrtfSet(PyTypeObject* type, PyObject* args)
139 {
140         const char* dir = nullptr;
141         const char* ext = nullptr;
142
143         if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
144                 return nullptr;
145
146         HRTFP* self;
147         self = (HRTFP*)type->tp_alloc(type, 0);
148
149         try
150         {
151                 self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadRightHRTFs(ext, dir));
152         }
153         catch(aud::Exception& e)
154         {
155                 Py_DECREF(self);
156                 PyErr_SetString(AUDError, e.what());
157                 return nullptr;
158         }
159         return (PyObject *)self;
160 }
161
162 static PyMethodDef HRTF_methods[] = {
163         { "addImpulseResponseFromSound", (PyCFunction)HRTF_addImpulseResponseFromSound, METH_VARARGS | METH_KEYWORDS,
164         M_aud_HRTF_addImpulseResponse_doc
165         },
166         { "loadLeftHrtfSet", (PyCFunction)HRTF_loadLeftHrtfSet, METH_VARARGS | METH_CLASS,
167         M_aud_HRTF_loadLeftHrtfSet_doc
168         },
169         { "loadRightHrtfSet", (PyCFunction)HRTF_loadRightHrtfSet, METH_VARARGS | METH_CLASS,
170         M_aud_HRTF_loadRightHrtfSet_doc
171         },
172         { nullptr }  /* Sentinel */
173 };
174
175 PyDoc_STRVAR(M_aud_HRTF_doc,
176         "An HRTF object represents a set of head related transfer functions as impulse responses. It's used for binaural sound");
177
178 PyTypeObject HRTFType = {
179         PyVarObject_HEAD_INIT(nullptr, 0)
180         "aud.HRTF",                                                             /* tp_name */
181         sizeof(HRTFP),                                                  /* tp_basicsize */
182         0,                                                                              /* tp_itemsize */
183         (destructor)HRTF_dealloc,                               /* tp_dealloc */
184         0,                                                                              /* tp_print */
185         0,                                                                              /* tp_getattr */
186         0,                                                                              /* tp_setattr */
187         0,                                                                              /* tp_reserved */
188         0,                                                                              /* tp_repr */
189         0,                                                                              /* tp_as_number */
190         0,                                                                              /* tp_as_sequence */
191         0,                                                                              /* tp_as_mapping */
192         0,                                                                              /* tp_hash  */
193         0,                                                                              /* tp_call */
194         0,                                                                              /* tp_str */
195         0,                                                                              /* tp_getattro */
196         0,                                                                              /* tp_setattro */
197         0,                                                                              /* tp_as_buffer */
198         Py_TPFLAGS_DEFAULT,                                             /* tp_flags */
199         M_aud_HRTF_doc,                                                 /* tp_doc */
200         0,                                                                              /* tp_traverse */
201         0,                                                                              /* tp_clear */
202         0,                                                                              /* tp_richcompare */
203         0,                                                                              /* tp_weaklistoffset */
204         0,                                                                              /* tp_iter */
205         0,                                                                              /* tp_iternext */
206         HRTF_methods,                                                   /* tp_methods */
207         0,                                                                              /* tp_members */
208         0,                                                                              /* tp_getset */
209         0,                                                                              /* tp_base */
210         0,                                                                              /* tp_dict */
211         0,                                                                              /* tp_descr_get */
212         0,                                                                              /* tp_descr_set */
213         0,                                                                              /* tp_dictoffset */
214         0,                                                                              /* tp_init */
215         0,                                                                              /* tp_alloc */
216         HRTF_new,                                                               /* tp_new */
217 };
218
219 AUD_API PyObject* HRTF_empty()
220 {
221         return HRTFType.tp_alloc(&HRTFType, 0);
222 }
223
224
225 AUD_API HRTFP* checkHRTF(PyObject* hrtf)
226 {
227         if(!PyObject_TypeCheck(hrtf, &HRTFType))
228         {
229                 PyErr_SetString(PyExc_TypeError, "Object is not of type HRTF!");
230                 return nullptr;
231         }
232
233         return (HRTFP*)hrtf;
234 }
235
236
237 bool initializeHRTF()
238 {
239         return PyType_Ready(&HRTFType) >= 0;
240 }
241
242
243 void addHRTFToModule(PyObject* module)
244 {
245         Py_INCREF(&HRTFType);
246         PyModule_AddObject(module, "HRTF", (PyObject *)&HRTFType);
247 }